diff --git a/.gitignore b/.gitignore index 6f1e869b8a..a03a82b38c 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,7 @@ # /cachegrind/ /cachegrind/*.so +/cachegrind/*.dSYM /cachegrind/.deps /cachegrind/cachegrind-*-darwin /cachegrind/cachegrind-*-linux @@ -130,6 +131,7 @@ # /callgrind/ /callgrind/*.so +/callgrind/*.dSYM /callgrind/.deps /callgrind/callgrind-*-darwin /callgrind/callgrind-*-linux @@ -692,6 +694,7 @@ /helgrind/tests/bug327548 /helgrind/tests/bug392331 /helgrind/tests/bug484480 +/helgrind/tests/bug513598 /helgrind/tests/cond_init_destroy /helgrind/tests/cond_timedwait_invalid /helgrind/tests/cond_timedwait_test @@ -707,6 +710,7 @@ /helgrind/tests/locked_vs_unlocked1 /helgrind/tests/locked_vs_unlocked2 /helgrind/tests/locked_vs_unlocked3 +/helgrind/tests/lock_destroy_report /helgrind/tests/Makefile /helgrind/tests/Makefile.in /helgrind/tests/pth_barrier @@ -758,6 +762,7 @@ # /lackey/ /lackey/*.so +/lackey/*.dSYM /lackey/.deps /lackey/lackey-*-darwin /lackey/lackey-*-linux @@ -907,7 +912,6 @@ /memcheck/tests/demangle-rust /memcheck/tests/describe-block /memcheck/tests/descr_belowsp -/memcheck/tests/dir /memcheck/tests/doublefree /memcheck/tests/duplicate_align_size_errors /memcheck/tests/dw4 @@ -954,6 +958,7 @@ /memcheck/tests/lsframe2 /memcheck/tests/Makefile /memcheck/tests/Makefile.in +/memcheck/tests/linux/madv_guard /memcheck/tests/mallinfo /memcheck/tests/mallinfo2 /memcheck/tests/malloc1 @@ -984,6 +989,7 @@ /memcheck/tests/new_nothrow /memcheck/tests/new_override /memcheck/tests/noisy_child +/memcheck/tests/nothing /memcheck/tests/null_socket /memcheck/tests/origin1-yes /memcheck/tests/origin2-not-quite @@ -1008,6 +1014,7 @@ /memcheck/tests/realloc1 /memcheck/tests/realloc2 /memcheck/tests/realloc3 +/memcheck/tests/replaces_malloc_client_req /memcheck/tests/recursive-merge /memcheck/tests/resvn_stack /memcheck/tests/sbfragment @@ -1019,6 +1026,8 @@ /memcheck/tests/sendmsg /memcheck/tests/sh-mem /memcheck/tests/sh-mem-random +/memcheck/tests/simple_leak +/memcheck/tests/simple_reachable /memcheck/tests/sized_aligned_new_delete_args /memcheck/tests/sized_aligned_new_delete_misaligned1 /memcheck/tests/sized_aligned_new_delete_misaligned2 @@ -1062,7 +1071,7 @@ /memcheck/tests/wcscat /memcheck/tests/weirdioctl /memcheck/tests/with space -/memcheck/tests/wcpncpy +/memcheck/tests/wcpncpy1 /memcheck/tests/wcsncpy /memcheck/tests/wmemcmp /memcheck/tests/wrap1 @@ -1077,6 +1086,7 @@ /memcheck/tests/wrapmalloc /memcheck/tests/wrapmallocstatic /memcheck/tests/writev1 +/memcheck/tests/xmas_tree /memcheck/tests/xml1 /memcheck/tests/zeropage @@ -1088,6 +1098,7 @@ /memcheck/tests/amd64/bt_everything /memcheck/tests/amd64/bug132146 /memcheck/tests/amd64/bug279698 +/memcheck/tests/amd64/bug406674 /memcheck/tests/amd64/bug492210 /memcheck/tests/amd64/defcfaexpr /memcheck/tests/amd64/fxsave-amd64 @@ -1205,6 +1216,7 @@ /memcheck/tests/linux/dlclose_leak_so.so /memcheck/tests/linux/getregset /memcheck/tests/linux/ioctl-tiocsig +/memcheck/tests/linux/ioctl_procmap_query /memcheck/tests/linux/lsframe1 /memcheck/tests/linux/lsframe2 /memcheck/tests/linux/Makefile @@ -1298,6 +1310,7 @@ /memcheck/tests/solaris/Makefile.in /memcheck/tests/solaris/aligned_alloc /memcheck/tests/solaris/brk +/memcheck/tests/solaris/bug519613 /memcheck/tests/solaris/context_stack_die /memcheck/tests/solaris/door_data /memcheck/tests/solaris/door_kill @@ -1318,6 +1331,7 @@ /memcheck/tests/solaris/pkcs11 /memcheck/tests/solaris/scalar /memcheck/tests/solaris/scalar_auditon_stat +/memcheck/tests/solaris/scalar_crypto /memcheck/tests/solaris/scalar_frealpathat /memcheck/tests/solaris/scalar_getrandom /memcheck/tests/solaris/scalar_ioctl @@ -1443,7 +1457,8 @@ /memcheck/tests/freebsd/capsicum /memcheck/tests/freebsd/chflags /memcheck/tests/freebsd/chmod_chown -/memcheck/tests/freebsd/clock_nanosleep_interrupt +/memcheck/tests/freebsd/clock_nanosleep1 +/memcheck/tests/freebsd/clock_nanosleep2 /memcheck/tests/freebsd/delete_sized_mismatch /memcheck/tests/freebsd/errno_aligned_allocs /memcheck/tests/freebsd/eventfd1 @@ -1465,6 +1480,8 @@ /memcheck/tests/freebsd/kqueue /memcheck/tests/freebsd/kqueuex /memcheck/tests/freebsd/linkat +/memcheck/tests/freebsd/lsframe1 +/memcheck/tests/freebsd/lsframe2 /memcheck/tests/freebsd/memalign /memcheck/tests/freebsd/misc /memcheck/tests/freebsd/openpty @@ -1552,6 +1569,7 @@ /nightly/valgrind-old # /none/ +/none/*.dSYM /none/*.so /none/.deps /none/Makefile @@ -1587,6 +1605,7 @@ /none/tests/bug290061 /none/tests/bug491394 /none/tests/bug492678 +/none/tests/bug514094 /none/tests/closeall /none/tests/coolo_sigaction /none/tests/coolo_strlen @@ -1648,7 +1667,6 @@ /none/tests/pluto /none/tests/ppoll_alarm /none/tests/process_vm_readv_writev -/none/tests/procfs-cmdline-exe /none/tests/pselect_alarm /none/tests/pselect_sigmask_null /none/tests/pth_2sig @@ -1905,6 +1923,8 @@ /none/tests/darwin/bug228343 /none/tests/darwin/bug254164 /none/tests/darwin/bug390269 +/none/tests/darwin/bug411369 +/none/tests/darwin/procfs-cmdline-exe /none/tests/darwin/rlimit # /none/tests/linux/ @@ -1927,7 +1947,9 @@ /none/tests/linux/mremap5 /none/tests/linux/mremap6 /none/tests/linux/open_client +/none/tests/linux/procfs-cmdline-exe /none/tests/linux/pthread-stack +/none/tests/linux/readlinkat_self /none/tests/linux/stack-overflow /none/tests/linux/getdents_filter @@ -2196,8 +2218,6 @@ /none/tests/s390x/cu14_1 /none/tests/s390x/cu41 /none/tests/s390x/ecag -/none/tests/s390x/fpext_warn -/none/tests/s390x/fpext_fail /none/tests/s390x/bfp-306054 /none/tests/s390x/bfp-arith /none/tests/s390x/bfp-load @@ -2242,6 +2262,7 @@ /none/tests/s390x/pfpo /none/tests/s390x/rxsbg /none/tests/s390x/popcnt +/none/tests/s390x/popcnt-mi3 /none/tests/s390x/vector /none/tests/s390x/lsc2 /none/tests/s390x/ppno @@ -2251,8 +2272,11 @@ /none/tests/s390x/high-word /none/tests/s390x/vector_float /none/tests/s390x/misc3 +/none/tests/s390x/misc4 /none/tests/s390x/vec2 /none/tests/s390x/vec2_float +/none/tests/s390x/vec3 +/none/tests/s390x/vecdiv # /none/tests/riscv64/ /none/tests/riscv64/*.stderr.diff @@ -2329,7 +2353,9 @@ /none/tests/solaris/proc_auxv /none/tests/solaris/proc_auxv_multiple /none/tests/solaris/proc_psinfo +/none/tests/solaris/procfs-cmdline-exe /none/tests/solaris/pthread-stack +/none/tests/solaris/readlinkat_self /none/tests/solaris/reserve_sysstat_addr /none/tests/solaris/reserve_sysstat_zone_addr /none/tests/solaris/resolv @@ -2358,6 +2384,7 @@ none/tests/freebsd/bug499212 /none/tests/freebsd/hello_world /none/tests/freebsd/open_client /none/tests/freebsd/proc_pid_file +/none/tests/freebsd/procfs-cmdline-exe /none/tests/freebsd/sanity_level_thread /none/tests/freebsd/usrstack /none/tests/freebsd/umtx_shm_creat @@ -2548,6 +2575,10 @@ none/tests/freebsd/bug499212 /VEX/priv/.deps /VEX/priv/.dirstamp +# /VEX/priv/objdump +/VEX/priv/objdump/.deps +/VEX/priv/objdump/.dirstamp + # /VEX/pub/ /VEX/pub/libvex_guest_offsets.h diff --git a/AUTHORS b/AUTHORS index cff2c893d4..e27725b5d3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -86,8 +86,12 @@ s390. Rhys Kidd updated and maintains the macOS port. -Paul Floyd maintains the FreeBSD port and occasionally fixes Solaris -and macOS issues. +Paul Floyd maintains the FreeBSD and illumos ports and generally +tries to deal with issues related to threading, C++, ELF reading +and the Darwin port. + +Louis Brunner updated and maintains the macOS port from +macOS 10.12 onwards. Many, many people sent bug reports, patches, and helpful feedback. diff --git a/Makefile.all.am b/Makefile.all.am index d4f6b3fb79..4f185d79cc 100644 --- a/Makefile.all.am +++ b/Makefile.all.am @@ -120,6 +120,8 @@ AM_CFLAGS_BASE = \ @FLAG_W_OLD_STYLE_DECLARATION@ \ @FLAG_FINLINE_FUNCTIONS@ \ @FLAG_FNO_STACK_PROTECTOR@ \ + @FLAG_FNO_DIAGNOSTICS_SHOW_CARET@ \ + @FLAG_FTRACK_MACRO_EXPANSION@ \ @FLAG_FSANITIZE@ \ -fno-strict-aliasing \ -fno-builtin @@ -151,6 +153,7 @@ if VGCONF_OS_IS_DARWIN AM_CFLAGS_PSO_BASE = -dynamic \ -O -g -fno-omit-frame-pointer -fno-strict-aliasing \ -fpic -fPIC -fno-builtin @FLAG_FNO_IPA_ICF@ +AM_CFLAGS_BASE += @FLAG_W_NO_EXPANSION_TO_DEFINED@ @FLAG_W_NO_NULLABILITY_COMPLETENESS@ else if VGCONF_OS_IS_FREEBSD AM_CFLAGS_PSO_BASE = -O -g -fno-omit-frame-pointer -fno-strict-aliasing \ @@ -257,7 +260,8 @@ AM_CCASFLAGS_ARM64_FREEBSD = @FLAG_M64@ -g AM_FLAG_M3264_X86_DARWIN = -arch i386 AM_CFLAGS_X86_DARWIN = $(WERROR) -arch i386 $(AM_CFLAGS_BASE) \ - -mmacosx-version-min=10.6 \ + -I@SDK_INC_DIR@ \ + @CLANG_OS_MIN_VERS_ARG@ \ -fno-pic -fno-PIC AM_CFLAGS_PSO_X86_DARWIN = $(AM_CFLAGS_X86_DARWIN) $(AM_CFLAGS_PSO_BASE) @@ -265,7 +269,8 @@ AM_CCASFLAGS_X86_DARWIN = -arch i386 -g AM_FLAG_M3264_AMD64_DARWIN = -arch x86_64 AM_CFLAGS_AMD64_DARWIN = $(WERROR) -arch x86_64 $(AM_CFLAGS_BASE) \ - -mmacosx-version-min=10.6 + -I@SDK_INC_DIR@ \ + @CLANG_OS_MIN_VERS_ARG@ AM_CFLAGS_PSO_AMD64_DARWIN = $(AM_CFLAGS_AMD64_DARWIN) $(AM_CFLAGS_PSO_BASE) AM_CCASFLAGS_AMD64_DARWIN = -arch x86_64 -g diff --git a/Makefile.am b/Makefile.am index 176317a5d3..3e7eb7fa07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,11 +48,9 @@ SUPP_FILES = \ glibc-2.X-helgrind.supp \ glibc-2.2-LinuxThreads-helgrind.supp \ glibc-2.X-drd.supp \ - darwin9.supp darwin9-drd.supp \ freebsd.supp freebsd-helgrind.supp freebsd-drd.supp \ - darwin10.supp darwin10-drd.supp \ - darwin11.supp darwin12.supp darwin13.supp darwin14.supp darwin15.supp \ - darwin16.supp darwin17.supp \ + darwin-legacy.supp darwin.supp \ + darwin-drd.supp darwin-helgrind.supp \ bionic.supp \ solaris11.supp solaris12.supp \ musl.supp @@ -71,16 +69,22 @@ pkgconfig_DATA = valgrind.pc BUILT_SOURCES = default.supp include/vgversion.h valgrind.pc CLEANFILES = default.supp +BUNSEN ?= yes + ifeq "$(BUNSEN)" "no" + VG_REGTEST_ARG ?= "--no-bunsen" + else + VG_REGTEST_ARG ?= + endif + default.supp: $(DEFAULT_SUPP_FILES) echo "# This is a generated file, composed of the following suppression rules:" > default.supp echo "# " $(DEFAULT_SUPP_FILES) >> default.supp cat $^ >> default.supp -## Preprend @PERL@ because tests/vg_regtest isn't executable -## Ensure make exits with error if PERL fails or post_regtest_checks fails. +## Ensure make exits with error if vg_regtest fails or post_regtest_checks fails. regtest: check $(top_srcdir)/gdbserver_tests/make_local_links $(GDB) - if @PERL@ tests/vg_regtest gdbserver_tests $(TOOLS) $(EXP_TOOLS) ; then \ + if tests/vg_regtest $(VG_REGTEST_ARG) gdbserver_tests $(TOOLS) $(EXP_TOOLS) ; then \ tests/post_regtest_checks $(abs_top_srcdir) gdbserver_tests $(TOOLS) $(EXP_TOOLS); \ else \ tests/post_regtest_checks $(abs_top_srcdir) gdbserver_tests $(TOOLS) $(EXP_TOOLS); \ @@ -89,16 +93,15 @@ regtest: check post-regtest-checks: tests/post_regtest_checks $(abs_top_srcdir) gdbserver_tests $(TOOLS) $(EXP_TOOLS) nonexp-regtest: check - @PERL@ tests/vg_regtest $(TOOLS) + tests/vg_regtest $(VG_REGTEST_ARG) $(TOOLS) exp-regtest: check - @PERL@ tests/vg_regtest gdbserver_tests $(EXP_TOOLS) + tests/vg_regtest $(VG_REGTEST_ARG) gdbserver_tests $(EXP_TOOLS) # Nb: gdbserver_tests are put in exp-regtest rather than nonexp-regtest # because they are tested with various valgrind tools, so might be using # an experimental tool. -## Preprend @PERL@ because tests/vg_perf isn't executable perf: check - @PERL@ perf/vg_perf perf + perf/vg_perf perf # Auxiliary test suites run under valgrind auxchecks: all diff --git a/Makefile.vex.am b/Makefile.vex.am index f75e9b4c69..ca50e0df2e 100644 --- a/Makefile.vex.am +++ b/Makefile.vex.am @@ -41,6 +41,8 @@ noinst_HEADERS = \ priv/ir_opt.h \ priv/guest_generic_bb_to_IR.h \ priv/guest_generic_x87.h \ + priv/guest_generic_sse.h \ + priv/guest_generic_helpers.h \ priv/guest_x86_defs.h \ priv/guest_amd64_defs.h \ priv/guest_ppc_defs.h \ @@ -68,7 +70,10 @@ noinst_HEADERS = \ priv/host_mips_defs.h \ priv/host_nanomips_defs.h \ priv/common_nanomips_defs.h \ - priv/host_riscv64_defs.h + priv/host_riscv64_defs.h \ + priv/objdump/dis-asm.h \ + priv/objdump/s390.h \ + priv/objdump/stubs.h BUILT_SOURCES = pub/libvex_guest_offsets.h CLEANFILES = pub/libvex_guest_offsets.h @@ -178,13 +183,16 @@ LIBVEX_SOURCES_COMMON = \ priv/host_arm64_isel.c \ priv/host_s390_defs.c \ priv/host_s390_isel.c \ - priv/s390_disasm.c \ priv/host_mips_defs.c \ priv/host_nanomips_defs.c \ priv/host_mips_isel.c \ priv/host_nanomips_isel.c \ priv/host_riscv64_defs.c \ - priv/host_riscv64_isel.c + priv/host_riscv64_isel.c \ + priv/objdump/dis-init.c \ + priv/objdump/s390-dis.c \ + priv/objdump/s390-opc.c \ + priv/objdump/s390-opc.tab LIBVEXMULTIARCH_SOURCES = priv/multiarch_main_main.c @@ -197,13 +205,13 @@ LIBVEX_CFLAGS = ${LTO_CFLAGS} \ libvex_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_SOURCES = $(LIBVEX_SOURCES_COMMON) libvex_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CPPFLAGS = \ - $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) -Ipriv + $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) -I$(srcdir)/priv libvex_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CFLAGS = \ $(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) $(LIBVEX_CFLAGS) if VGCONF_HAVE_PLATFORM_SEC libvex_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_SOURCES = $(LIBVEX_SOURCES_COMMON) libvex_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CPPFLAGS = \ - $(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) -Ipriv + $(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) -I$(srcdir)/priv libvex_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CFLAGS = \ $(AM_CFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) $(LIBVEX_CFLAGS) endif @@ -211,14 +219,14 @@ endif libvexmultiarch_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_SOURCES = \ $(LIBVEXMULTIARCH_SOURCES) libvexmultiarch_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CPPFLAGS = \ - $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) -Ipriv + $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) -I$(srcdir)/priv libvexmultiarch_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CFLAGS = \ $(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) $(LIBVEX_CFLAGS) if VGCONF_HAVE_PLATFORM_SEC libvexmultiarch_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_SOURCES = \ $(LIBVEXMULTIARCH_SOURCES) libvexmultiarch_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CPPFLAGS = \ - $(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) -Ipriv + $(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) -I$(srcdir)/priv libvexmultiarch_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CFLAGS = \ $(AM_CFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) $(LIBVEX_CFLAGS) endif diff --git a/NEWS b/NEWS index ce6cc7130f..045c363a23 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,204 @@ +Release 3.27.1 (20 May 2026) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This point release contains only bug fixes. + +* ==================== FIXED BUGS ==================== + +The following bugs have been fixed or resolved in this point release. + +519574 valgrind 3.27 "--fair-sched=yes" does not work +519613 Valgrind incorrectly unpacks the result of sys_port (port_getn) + on error, leading to a ~60s wallclock time delay on every call +n-i-bz Update vg-lifespan (copyright) years +n-i-bz Use SSizeT for VG_(readlink) result in VG_(realpath) + +To see details of a given bug, visit + https://bugs.kde.org/show_bug.cgi?id=XXXXXX +where XXXXXX is the bug number as listed above. + + +Release 3.27.0 (20 Apr 2026) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release supports X86/Linux, AMD64/Linux, ARM32/Linux, ARM64/Linux, +PPC32/Linux, PPC64BE/Linux, PPC64LE/Linux, S390X/Linux, MIPS32/Linux, +MIPS64/Linux, RISCV64/Linux, ARM/Android, ARM64/Android, MIPS32/Android, +X86/Android, X86/Solaris, AMD64/Solaris, X86/macOS, AMD64/macOS. +X86/FreeBSD, AMD64/FreeBSD and ARM64/FreeBSD. There is preliminary support +for nanoMIPS/Linux. macOS is supported up to version 13 Ventura (amd64 only). + +* ==================== CORE CHANGES =================== + +* There are two new client requests + + - VALGRIND_REPLACES_MALLOC Returns 1 if the tool replaces malloc + (e.g., memcheck). Returns 0 if the tool does not replace malloc + (e.g., cachegrind and callgrind) or if the executable is not + running under VALGRIND. + + - VALGRIND_GET_TOOLNAME Get the running tool name as a string. Takes + two arguments, an input buffer pointer and the length of that + buffer. Returns the required length (including terminating nul) + for the tool name. Returns 0 and the contents supplied buffer are + not modified if not running under Valgrind. + + See also the full description in the valgrind.h header file or the + in The Client Request mechanism section of the Valgrind User Manual. + +* linux lightweight guard pages (madvise MADV_GUARD_INSTALL) supported + + glibc 2.42+ (with linux 6.13+) uses MADV_GUARD_INSTALL to setup + stack guard pages. These lightweight guard pages are now supported + under valgrind. By default, Valgrind can handle to up to 500 madvise + guard pages. With thread heavy workloads the default value might not + be sufficient. Use --max-guard-pages=N to provide a different limit. + If --max-guard-pages is not set explicitly, then it will default to + the --max-threads setting. + +* --num-callers now has a minimum value of 2. + + This is a breaking change. See + https://bugs.kde.org/show_bug.cgi?id=515183#c13 + for full details. + +* ================== PLATFORM CHANGES ================= + +* x86: Support for SSE4.1 instructions has been ported from AMD64 to + (32bit) x86. This is ongoing work. Currently the following SSE4.1 + instructions are supported BLENDPD BLENDPS BLENDVPD BLENDVPS + MOVNTDQA MPSADBW PBLENDVB PBLENDW PCMPEQQ PINSRD PMAXSB PMAXSD + PMAXUD PMAXUW PMINSB PMINSD PMINUD PMINUW PMULLD PTEST. + Bug #518222 tracks further progress. + +* s390x: Machine models older than z196 are no longer supported. + +* s390x: Support new z/Architecture features from the 15th edition. In + particular this enables running binaries compiled with `-march=arch15' + or `-march=z17' and exploiting the new MSA extensions 10-13. + +* Support for the following macOS versions has been added + 10.13 High Sierra (bug fixes) + 10.14 Mojave + 10.15 Catalina + 11.0 Big Sur (Intel only) + 12.0 Monterey (Intel only) + 13.0 Ventura (Intel only, preliminary) + +* The Linux Test Project (LTP) v20260130 was integrated. New linux + syscall wrappers for file_getattr, file_setattr, lsm_get_self_attr, + lsm_set_self_attr, lsm_list_modules were added. + +* ==================== TOOL CHANGES =================== + +* Helgrind: + + - New debug option --show-events=0|1|2. Controls tracing of internal + Helgrind synchronization, threading and memory events. At level 1, + Helgrind prints a trace of its synchronization, threading and memory + events. At level 2, additional memory events are also traced. The + default value of 0 disables tracing. + + - New option --track-destroy=no|yes|all. Checks for missing + pthread_mutex_destroy and pthread_rwlock_destroy calls. With yes, + Helgrind warns when pthread_mutex_init or pthread_rwlock_init is called + on the address of a live (undestroyed) lock. With all, Helgrind also + reports undestroyed locks at process exit. --track-destroy does not track + locks that use static initializers. + +* ==================== FIXED BUGS ==================== + +The following bugs have been fixed or resolved. Note that "n-i-bz" +stands for "not in bugzilla" -- that is, a bug that was reported to us +but never got a bugzilla entry. We encourage you to file bugs in +bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather +than mailing the developers (or mailing lists) directly -- bugs that +are not entered into bugzilla tend to get forgotten about or ignored. + +126256 (fnop) vex x86->IR: unhandled instruction bytes: 0xD9 0xD0 0x31 0xC0 +228343 none/tests/darwin/bug228343 fails on OS X +233298 MEMPOOL_FREE not reflected in heap summary +253436 vex amd64->IR: unhandled instruction bytes: 0xF2 0xA6 (repne cmps) +258140 Valgrind on OS X always reports some memory "still reachable" +390754 unhandled amd64-darwin syscall: unix:216 (open_dprotected_np) +406674 False positive when reading bitfield value on code compiled with + clang 7.0 +413369 unhandled amd64-darwin syscall: unix:151 (getpgid) +413410 unhandled amd64-darwin syscall: mach:50 (on macOS 10.15) +487055 memcheck/tests/x86-linux/scalar fails running in Docker +503238 s390x: Support miscellaneous-instruction-extensions facility 4 +503239 s390x: Support vector-enhancements facility 3 +503240 s390x: Support MSA extensions 10, 11, and 12 +509562 s390x: Define minimum required machine model +510416 Missing syswraps for file_getattr and file_setattr +510563 Add missing syswraps for lsm_get_self_attr and lsm_set_self_attr +510864 Add SSE4.1 PMAXSD and PMINSD instructions support for 32-bit x86 +511329 Darwin and FreeBSD: Move setting of carry flag out of + ML_(do_syscall_for_client_WRK) +511461 Darwin 17 (MacOS X 10.13) memcheck issues +511713 Refactor syscall argument handling +511717 gdbserver (valgrind_read_memory) the 'impossible' happened: + Killed by fatal signal (SIGSEGV) +511972 valgrind-3.26.0 tests fail to build on upcomig gcc-16: + unrecognized command-line option + '-Wno-alloc-size-larger-than=18446744073709551615' +512030 s390x: bfp-convert testcase fails +512037 malloc trace does not print free size or alignment +512291 Valgrind on Solaris should drop support for long gone /dev/crypto + framework +512571 regtest problems with darwin dsymutil +512873 Add SSE4.1 min/max instructions for x86 32 bit +513257 Add missing syswraps for lsm_list_modules +513522 m_libcassert.c: 'ordered comparison of pointer with integer zero' + compiler warning +513475 Add SSE4.1 PMULLD instruction for x86 32 bit +513598 Helgrind should detect locks without pthread_{rwlock,mutex}_destroy + being called - Assertion 'lk->kind == LK_rdwr' failed. +514094 readlink("/proc/self/exe") overwrites buffer beyond its return value +514206 Assertion '!sr_isError(sr)' failed - mmap fd points to an open + descriptor to a PCI device +514297 Track madvise MADV_GUARD_INSTALL in address space manager +514343 Add a valgrind.h macro VALGRIND_REPLACES_MALLOC +514596 Add SSE4.1 BLENDPD instruction for x86 32 bit +514613 Unclosed leak_summary/still_reachable tag in xml output +514659 ltp 20250930 vs linux 6.18.3 doesn't build +514762 Many "Bad file descriptor" messages when using --track-fds=yes and + -d on systems without /proc +515183 Error occurred while executing the command + `valgrind --num-callers=1 ./hello_world` +515265 Add SSE4.1 BLENDPS and PBLENDW instructions for x86 32 bit +516223 Add SSE4.1 PBLENDVB, BLENDVPS and BLENDVPD + instructions for x86 32 bit +515612 Sanity check VG_(realpath) and VG_(readlink) return values +515731 Distinguish between realloc functions in realloc size 0 error messages +515810 Update the LTP version in valgrind testsuite to 20260130 +515992 Add FreeBSD /proc virtualisation for cmdline and file +516090 Regression : Linux FreeBSD and Darwin: refactor *at syscall dirfd checks +516225 Add MOVNTDQA SSE4.1 support for x86 +516289 illumos lsframe2 regtest fails +516748 Incorrect use of SET_STATUS_Failure for syscall wrappers that return + error codes rather than -1 on error +517455 Add PCMPEQQ SSE4.1 support for x86 +517697 Implement CLRSSONSTACK and SETUJMPBUF handling on Solaris. +517748 Add ability to redirect global functions to Darwin +517840 Add PTEST SSE4.1 support for x86 +518216 Add SSE4.1 MPSADBW instruction support for x86 32 bit +518076 FreeBSD: add syscall wrapper for renameat2 +518078 Configure should accept names for GDB other than "gdb" +518159 pth_once issues on Darwin +518482 FreeBSD: assert in parse_procselfmaps when built with GNU binutils +518609 Setting double verbose interferes with symbol loading (FreeBSD 16) +518778 Valgrind LTP testsuite fails to compile on Fedora 44+ +518951 LTP testcase fsconfig02 fails under Valgrind + +To see details of a given bug, visit + https://bugs.kde.org/show_bug.cgi?id=XXXXXX +where XXXXXX is the bug number as listed above. + +(3.27.0.RC1: 13 Apr 2026) +(3.27.0.RC2: 17 Apr 2026) + + Release 3.26.0 (24 Oct 2025) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -17,6 +218,9 @@ X86/macOS 10.13, AMD64/macOS 10.13 and nanoMIPS/Linux. documentation. all, builds all documentation. html, builds HTML docs but skips building PDFs. See also README_DEVELOPERS. +* Control generation of files that are only useful for post-processing + with bunsen. make regtest BUNSEN=no inhibits generating those files. + * New VEX API function LibVEX_set_VexControl * The deprecated IROps: Iop_Clz32/64 and Iop_Ctz32/64 have been removed @@ -187,6 +391,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 508030 Add several missing syscall hooks to ppc64-linux 508093 VALGRIND_CLO_CHANGE does not update vex_control 508145 ppc64le needs ld.so hardwire for strcmp +508328 Memory allegedly uninitialized after ioctl(PROCMAP_QUERY) 508154 PRE(sys_fchownat) not handling VKI_AT_FDCWD 508638 Self-hosting not working on FreeBSD 508777 amd64-linux: add minimal scalar test @@ -204,6 +409,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 509572 s390x: Overhaul BFP testsuite 509590 Run the LTP tests with LTP_QUIET 509567 unhandled amd64-linux syscall: 443 (quotactl_fd) +509634 Add ARG4 checks for quotactl and quotactl_fd syswraps 509642 Add missing ppc64-linux syswraps 509643 Add missing s390x-linux syswraps 510169 Update the LTP version in valgrind testsuite to 20250930 @@ -664,7 +870,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 471311 gdb --multi mode stdout redirecting to stderr 471807 Add support for lazy reading and downloading of DWARF debuginfo 472219 Syscall param ppoll(ufds.events) points to uninitialised byte(s) -472875 none/tests/s390x/dfp-1 failure +472875 none/tests/s390x/dfp-1 failure 472963 Broken regular expression in configure.ac 473604 Fix bug472219.c compile failure with Clang 16 473677 make check compile failure with Clang 16 based on GCC 13.x @@ -854,7 +1060,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38 445743 "The impossible happened: mutex is locked simultaneously by two threads" while using mutexes with priority inheritance and signals -449309 Missing loopback device ioctl(s) +449309 Missing loopback device ioctl(s) 459476 vgdb: allow address reuse to avoid "address already in use" errorsuse" errors 460356 s390: Sqrt32Fx4 -- cannot reduce tree 462830 WARNING: unhandled amd64-freebsd syscall: 474 @@ -931,7 +1137,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 453055 shared_timed_mutex drd test fails with "Lock shared failed" message 453602 Missing command line option to enable/disable debuginfod 452802 Handle lld 9+ split RW PT_LOAD segments correctly -454040 s390x: False-positive memcheck:cond in memmem on arch13 systems +454040 s390x: False-positive memcheck:cond in memmem on arch13 systems 456171 [PATCH] FreeBSD: Don't record address errors when accessing the 'kern.ps_strings' sysctl struct n-i-bz Implement vgdb invoker on FreeBSD 458845 PowerPC: The L field for the dcbf and sync instruction should be @@ -1054,6 +1260,8 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506211 Constant folding improvements 506453 Unexpected behaviour with IR injection and vex-guest-chase=yes 509157 riscv64: Shift instructions can behave wrong +510840 Use objdump for disassembly in VEX (s390x only) +517596 VEX/priv/guest_ppc_toIR.c: Two possible cut'n'paste errors To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/README.freebsd b/README.freebsd index ef850513ee..dcb950194c 100644 --- a/README.freebsd +++ b/README.freebsd @@ -186,6 +186,76 @@ git history. You can also look at https://docs.freebsd.org/en/books/porters-handbook/versions/ +More about syscalls +------------------- + +One thing that is specific to FreeBSD (and Darwin) is how the "syscall()" +libc function is implemented. On Linux this function shuffles the arguments +so that "syscall(__NR_write, 1, data, len)" will result in syscall +__NR_write (4) with arguments 1, data, len. On FreeBSD (and Darwin) this +shuffling is not done in libc, it is done in the kernel. FreeBSD has two +special "syscall syscalls". These are syscalls 0 and 198, which take +the target syscall number and its arguments as parameters. +"syscall(SYS_write, 1, data, len)" on FreeBSD will result in +syscall SYS_syscall (0) with arguments 4 (SYS_write), 1, data, len. The +kernel will then call kern_write with arguments 1, data, len. + +The way that syscall arguments are passed on FreeBSD depends on the +architecture. On x86 they are all on the stack. On arm64 they are +all in registers. On amd64 the syscall number and the first six arguments +are in registers and any further arguments are on the stack. + +There are two ways that Valgrind makes syscalls. +a) for its own use as the host +b) on behalf of the guest. + +The first category are fairly straightforward. These are called via a +series of macros from VG_(do_syscall0) to VG_(do_syscall8). The number +indicates the argument count. The macros expand to VG_(do_syscall) which +uses do_syscall_WRK to do the job in assembler. + +The second category can be much more complicated. It is all done in +VG_(client_syscall). There are extensive explanations in the same file, +syswrap-main.c. The main things that this function does are + +i. Get the syscall arguments with getSyscallArgsFromGuestState. This function + has special handling for "syscall syscall". Since we want to validate + the arguments of the final syscall getSyscallArgsFromGuestState will shuffle + the arguments to be in the order of the final syscall (canonical order). + In order to be able to distinguish between "syscall syscall" and other syscalls + two syscall numbers may be stored, original_sysno and canonical_sysno. + Usually they are the same, only differing for "syscall syscall". +ii. Call getSyscallArgLayout. This is always in canonical form. The layout + indicates whether arguments are in registers or on the stack. On FreeBSD + with "syscall syscall" the arguments are effectively bumped up one slot. + That means that there is special handling for argument 6 on amd64, + which can either be in a register or on the stack depending on whether + it is a regular syscall or "syscall syscall". +iii. Call a pre-syscall tool hook (mainly used for syscall timing by callgrind + and cachegrind). This uses the args from step i. +iv. Call the PRE handler. That uses the arguments fetched in step i and the layout + obtained in step ii. The PRE_REG_READX macros use the layout and + the PRE_MEM_READ/WRITE and ARGX macros use the canonical arguments. + +Several things are possible at this point. The PRE may have performed the +syscall or marked it as complete. The syscall may be marked as blocking. +If the syscall is not blocking then Valgrind just makes the syscall and stores +the result. Blocking system calls are more complicated and continue as follows. + +v. Put back the syscall arguments with putSyscallArgsIntoGuestState() + (they may have changed in the PRE). On FreeBSD the original_sysno is checked + to see which form of unshuffling needs to be done. +vi. Call the syscall via ML_(do_syscall_for_client_WRK). This is preceded + by releasing the global lock and restoring the client signal mask, and + followed by blocking signals and acquiring the global lock. +vii. Get the syscall arguments again with getSyscallArgsFromGuestState. + This is only required to match the non-blocking flow. + +The final two steps are for both blocking and non-blocking system calls. + +viii. Put the syscall result into the guest state. +ix. Call the post handler. + Capsicum enabled applications ----------------------------- Valgrind will not work well with Capsicum enabled applications. As an example, diff --git a/README.s390 b/README.s390 index d2236d29fa..980285ab7f 100644 --- a/README.s390 +++ b/README.s390 @@ -1,10 +1,9 @@ Requirements ------------ -- You need GCC 3.4 or later to compile the s390 port. -- To run valgrind a z10 machine or any later model is recommended. - Older machine models down to and including z990 may work but have - not been tested extensively. +- You need a GCC-compatible compiler with C11 support to compile + the s390 port. +- Valgrind requires a machine not older than z196 to run. Limitations @@ -17,9 +16,6 @@ Limitations `docs/internals/s390-opcodes.csv', by grepping for "not implemented". - FP signalling is not accurate. E.g., the "compare and signal" instructions behave like their non-signalling counterparts. -- On machine models predating z10, cachegrind will assume a z10 cache - architecture. Otherwise, cachegrind will query the hosts cache system - and use those parameters. - Some gcc versions use mvc to copy 4/8 byte values. This will affect certain debug messages. For example, memcheck will complain about 4 one-byte reads/writes instead of just a single read/write. diff --git a/README_DEVELOPERS b/README_DEVELOPERS index 5d9fb823f9..286ed3b52c 100644 --- a/README_DEVELOPERS +++ b/README_DEVELOPERS @@ -68,7 +68,8 @@ files. These are listed, and non-passing tests detailed, in the test-suite-overall.log file. (Token *.trs and test-suite.log files are also created, for emulating automake-style testsuites, as expected by tools such as bunsen.) - +Generation of those files can be suppressed by specifying "BUNSEN=no" when +invoking make. Platform-specific setup for regression tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/VEX/Makefile-gcc b/VEX/Makefile-gcc deleted file mode 100644 index 57e33cdb25..0000000000 --- a/VEX/Makefile-gcc +++ /dev/null @@ -1,425 +0,0 @@ - -PUB_HEADERS = pub/libvex_basictypes.h \ - pub/libvex_ir.h \ - pub/libvex.h \ - pub/libvex_trc_values.h \ - pub/libvex_emnote.h \ - pub/libvex_guest_x86.h \ - pub/libvex_guest_amd64.h \ - pub/libvex_guest_arm.h \ - pub/libvex_guest_ppc32.h \ - pub/libvex_guest_ppc64.h \ - pub/libvex_guest_s390x.h \ - pub/libvex_s390x_common.h \ - pub/libvex_guest_mips32.h \ - pub/libvex_guest_offsets.h - -PRIV_HEADERS = priv/host_x86_defs.h \ - priv/host_amd64_defs.h \ - priv/host_arm_defs.h \ - priv/host_ppc_defs.h \ - priv/host_s390_defs.h \ - priv/host_mips_defs.h \ - priv/host_generic_maddf.h \ - priv/host_generic_regs.h \ - priv/host_generic_simd64.h \ - priv/host_generic_simd128.h \ - priv/host_generic_simd256.h \ - priv/main_globals.h \ - priv/main_util.h \ - priv/guest_generic_x87.h \ - priv/guest_generic_bb_to_IR.h \ - priv/guest_x86_defs.h \ - priv/guest_amd64_defs.h \ - priv/guest_arm_defs.h \ - priv/guest_ppc_defs.h \ - priv/guest_mips_defs.h \ - priv/mips_defs.h \ - priv/s390_disasm.h \ - priv/s390_defs.h \ - priv/ir_match.h \ - priv/ir_opt.h - -LIB_OBJS = priv/ir_defs.o \ - priv/ir_match.o \ - priv/ir_opt.o \ - priv/ir_inject.o \ - priv/main_main.o \ - priv/main_globals.o \ - priv/main_util.o \ - priv/s390_disasm.o \ - priv/host_x86_defs.o \ - priv/host_amd64_defs.o \ - priv/host_arm_defs.o \ - priv/host_arm64_defs.o \ - priv/host_ppc_defs.o \ - priv/host_s390_defs.o \ - priv/host_mips_defs.o \ - priv/host_x86_isel.o \ - priv/host_amd64_isel.o \ - priv/host_arm_isel.o \ - priv/host_arm64_isel.o \ - priv/host_ppc_isel.o \ - priv/host_s390_isel.o \ - priv/host_mips_isel.o \ - priv/host_generic_maddf.o \ - priv/host_generic_regs.o \ - priv/host_generic_simd64.o \ - priv/host_generic_simd128.o \ - priv/host_generic_simd256.o \ - priv/host_generic_reg_alloc2.o \ - priv/host_generic_reg_alloc3.o \ - priv/guest_generic_x87.o \ - priv/guest_generic_bb_to_IR.o \ - priv/guest_x86_helpers.o \ - priv/guest_amd64_helpers.o \ - priv/guest_arm_helpers.o \ - priv/guest_arm64_helpers.o \ - priv/guest_ppc_helpers.o \ - priv/guest_s390_helpers.o \ - priv/guest_mips_helpers.o \ - priv/guest_x86_toIR.o \ - priv/guest_amd64_toIR.o \ - priv/guest_arm_toIR.o \ - priv/guest_arm64_toIR.o \ - priv/guest_ppc_toIR.o \ - priv/guest_s390_toIR.o \ - priv/guest_mipsdsp_toIR.o \ - priv/guest_mips_toIR.o - -PUB_INCLUDES = -Ipub - -# Do not add any priv/host-ARCH or priv/guest-ARCH directories to this -# list, as they contain duplicate file names (each host has a hdefs.h, -# for example). -PRIV_INCLUDES = -Ipriv - - -ifndef CC - CC = gcc -endif -ifndef AR - AR = ar -endif - -# Put -g -O2 after any flags we inherit from V. -O2 vs -O -# makes a significant difference, at least with gcc4. -CCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow \ - -Wpointer-arith -Wbad-function-cast -Wcast-qual \ - -Wcast-align -Wmissing-declarations \ - -Wwrite-strings -Wformat -Wformat-security \ - $(EXTRA_CFLAGS) -g -O2 -fstrict-aliasing - -#CC = icc -#CCFLAGS = -g -Wall -wd981 -wd279 -wd1287 -wd869 -wd111 -wd188 -wd186 -# 981: operands are evaluated in unspecified order -# 279: controlling expression is constant -# 1287: invalid attribute for parameter -# 869: parameter "..." was never referenced -# 111: statement is unreachable -# 188: enumerated type mixed with another type -# (the above are for icc 8.0 -- 8.0.0.55 I think) -# 186: pointless comparison of unsigned integer with zero - -# kludge: stops V biarch builds screwing up at -j 2 or above -# The Right fix is to autoconf/automake-ise vex. -.NOTPARALLEL: - -all: vex - -# Empty, needed for Valgrind -install: - -scratch: clean all - -vex: libvex.a - -libvex.a: $(LIB_OBJS) - rm -f libvex.a - $(AR) crus libvex.a $(LIB_OBJS) - - -# The idea with these TAG-s is to mark the flavour of libvex.a -# most recently built, so if the same target is re-requested, we -# don't rebuild everything, but if a different one is requested -# then we scrub everything and start over. - -libvex-x86-linux.a: TAG-x86-linux libvex.a - mv -f libvex.a libvex-x86-linux.a -TAG-x86-linux: - if [ ! -f TAG-x86-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-x86-linux - -libvex-amd64-linux.a: TAG-amd64-linux libvex.a - mv -f libvex.a libvex-amd64-linux.a -TAG-amd64-linux: - if [ ! -f TAG-amd64-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-amd64-linux - -libvex-ppc32-linux.a: TAG-ppc32-linux libvex.a - mv -f libvex.a libvex-ppc32-linux.a -TAG-ppc32-linux: - if [ ! -f TAG-ppc32-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-ppc32-linux - -libvex-ppc64-linux.a: TAG-ppc64-linux libvex.a - mv -f libvex.a libvex-ppc64-linux.a -TAG-ppc64-linux: - if [ ! -f TAG-ppc64-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-ppc64-linux - -libvex-mips-linux.a: TAG-mips32-linux libvex.a - mv -f libvex.a libvex-mips32-linux.a -TAG-mips-linux: - if [ ! -f TAG-mips32-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-mips32-linux - -libvex-ppc32-aix5.a: TAG-ppc32-aix5 libvex.a - mv -f libvex.a libvex-ppc32-aix5.a -TAG-ppc32-aix5: - if [ ! -f TAG-ppc32-aix5 ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-ppc32-aix5 - -libvex-ppc64-aix5.a: TAG-ppc64-aix5 libvex.a - mv -f libvex.a libvex-ppc64-aix5.a -TAG-ppc64-aix5: - if [ ! -f TAG-ppc64-aix5 ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-ppc64-aix5 - -libvex-x86-darwin.a: TAG-x86-darwin libvex.a - mv -f libvex.a libvex-x86-darwin.a -TAG-x86-darwin: - if [ ! -f TAG-x86-darwin ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-x86-darwin - -libvex-amd64-darwin.a: TAG-amd64-darwin libvex.a - mv -f libvex.a libvex-amd64-darwin.a -TAG-amd64-darwin: - if [ ! -f TAG-amd64-darwin ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-amd64-darwin - -libvex-arm64-linux.a: TAG-arm64-linux libvex.a - mv -f libvex.a libvex-arm64-linux.a -TAG-arm64-linux: - if [ ! -f TAG-arm64-linux ] ; then rm -f $(LIB_OBJS) TAG-* libvex.a ; fi - touch TAG-arm64-linux - - -clean: - rm -f $(LIB_OBJS) *.a TAG-* \ - pub/libvex_guest_offsets.h \ - auxprogs/genoffsets.s - -minidist: - rm -f vex--minidist-2005MMDD.tar - tar cf vex--minidist-2005MMDD.tar $(PUB_HEADERS) $(PRIV_HEADERS) \ - Makefile-gcc \ - `echo $(LIB_OBJS) | sed "s/\.o/\.c/g"` - @echo - @echo minidist done, size follows: - @ls -l vex--minidist-2005MMDD.tar - @echo - -# This is very uggerly. Need to sed out both "xyzzyN" and -# "xyzzy$N" since gcc on different targets emits the constants -# differently -- with a leading $ on x86/amd64 but none on ppc32/64. -# ICC also emits the constants differently with a leading # #define -pub/libvex_guest_offsets.h: - rm -f auxprogs/genoffsets.s - $(CC) $(CCFLAGS) -O -S -o auxprogs/genoffsets.s \ - auxprogs/genoffsets.c - grep xyzzy auxprogs/genoffsets.s | grep "^[# ]*#define" \ - | sed "s/# #define/#define/g" \ - | sed "s/xyzzy\\$$//g" \ - | sed "s/xyzzy#//g" \ - | sed "s/xyzzy//g" \ - > pub/libvex_guest_offsets.h - rm -f auxprogs/genoffsets.s - - -ALL_HEADERS = $(PUB_HEADERS) $(PRIV_HEADERS) -ALL_INCLUDES = $(PUB_INCLUDES) $(PRIV_INCLUDES) - -priv/ir_defs.o: $(ALL_HEADERS) priv/ir_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_defs.o \ - -c priv/ir_defs.c - -priv/ir_inject.o: $(ALL_HEADERS) priv/ir_inject.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_inject.o \ - -c priv/ir_inject.c - -priv/ir_match.o: $(ALL_HEADERS) priv/ir_match.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_match.o \ - -c priv/ir_match.c - -priv/ir_opt.o: $(ALL_HEADERS) priv/ir_opt.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_opt.o \ - -c priv/ir_opt.c - -priv/main_main.o: $(ALL_HEADERS) priv/main_main.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main_main.o \ - -c priv/main_main.c - -priv/main_globals.o: $(ALL_HEADERS) priv/main_globals.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main_globals.o \ - -c priv/main_globals.c - -priv/main_util.o: $(ALL_HEADERS) priv/main_util.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main_util.o \ - -c priv/main_util.c - -priv/host_x86_defs.o: $(ALL_HEADERS) priv/host_x86_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_x86_defs.o \ - -c priv/host_x86_defs.c - -priv/host_amd64_defs.o: $(ALL_HEADERS) priv/host_amd64_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_amd64_defs.o \ - -c priv/host_amd64_defs.c - -priv/host_arm_defs.o: $(ALL_HEADERS) priv/host_arm_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_arm_defs.o \ - -c priv/host_arm_defs.c - -priv/host_arm64_defs.o: $(ALL_HEADERS) priv/host_arm64_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_arm64_defs.o \ - -c priv/host_arm64_defs.c - -priv/host_ppc_defs.o: $(ALL_HEADERS) priv/host_ppc_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_ppc_defs.o \ - -c priv/host_ppc_defs.c - -priv/host_s390_defs.o: $(ALL_HEADERS) priv/host_s390_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_s390_defs.o \ - -c priv/host_s390_defs.c - -priv/host_mips_defs.o: $(ALL_HEADERS) priv/host_mips_defs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_mips_defs.o \ - -c priv/host_mips_defs.c - -priv/host_x86_isel.o: $(ALL_HEADERS) priv/host_x86_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_x86_isel.o \ - -c priv/host_x86_isel.c - -priv/host_amd64_isel.o: $(ALL_HEADERS) priv/host_amd64_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_amd64_isel.o \ - -c priv/host_amd64_isel.c - -priv/host_arm_isel.o: $(ALL_HEADERS) priv/host_arm_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_arm_isel.o \ - -c priv/host_arm_isel.c - -priv/host_arm64_isel.o: $(ALL_HEADERS) priv/host_arm64_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_arm64_isel.o \ - -c priv/host_arm64_isel.c - -priv/host_ppc_isel.o: $(ALL_HEADERS) priv/host_ppc_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_ppc_isel.o \ - -c priv/host_ppc_isel.c - -priv/host_s390_isel.o: $(ALL_HEADERS) priv/host_s390_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_s390_isel.o \ - -c priv/host_s390_isel.c - -priv/host_mips_isel.o: $(ALL_HEADERS) priv/host_mips_isel.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_mips_isel.o \ - -c priv/host_mips_isel.c - -priv/host_generic_maddf.o: $(ALL_HEADERS) priv/host_generic_maddf.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_maddf.o \ - -c priv/host_generic_maddf.c - -priv/host_generic_regs.o: $(ALL_HEADERS) priv/host_generic_regs.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_regs.o \ - -c priv/host_generic_regs.c - -priv/host_generic_simd64.o: $(ALL_HEADERS) priv/host_generic_simd64.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_simd64.o \ - -c priv/host_generic_simd64.c - -priv/host_generic_simd128.o: $(ALL_HEADERS) priv/host_generic_simd128.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_simd128.o \ - -c priv/host_generic_simd128.c - -priv/host_generic_simd256.o: $(ALL_HEADERS) priv/host_generic_simd256.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_simd256.o \ - -c priv/host_generic_simd256.c - -priv/host_generic_reg_alloc2.o: $(ALL_HEADERS) priv/host_generic_reg_alloc2.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_reg_alloc2.o \ - -c priv/host_generic_reg_alloc2.c - -priv/host_generic_reg_alloc3.o: $(ALL_HEADERS) priv/host_generic_reg_alloc3.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_generic_reg_alloc3.o \ - -c priv/host_generic_reg_alloc3.c - -priv/guest_x86_toIR.o: $(ALL_HEADERS) priv/guest_x86_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_x86_toIR.o \ - -c priv/guest_x86_toIR.c - -priv/guest_generic_x87.o: $(ALL_HEADERS) priv/guest_generic_x87.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_generic_x87.o \ - -c priv/guest_generic_x87.c - -priv/guest_generic_bb_to_IR.o: $(ALL_HEADERS) priv/guest_generic_bb_to_IR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_generic_bb_to_IR.o \ - -c priv/guest_generic_bb_to_IR.c - -priv/guest_x86_helpers.o: $(ALL_HEADERS) priv/guest_x86_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_x86_helpers.o \ - -c priv/guest_x86_helpers.c - -priv/guest_amd64_helpers.o: $(ALL_HEADERS) priv/guest_amd64_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_amd64_helpers.o \ - -c priv/guest_amd64_helpers.c - -priv/guest_amd64_toIR.o: $(ALL_HEADERS) priv/guest_amd64_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_amd64_toIR.o \ - -c priv/guest_amd64_toIR.c - -priv/guest_arm_helpers.o: $(ALL_HEADERS) priv/guest_arm_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_arm_helpers.o \ - -c priv/guest_arm_helpers.c - -priv/guest_arm64_helpers.o: $(ALL_HEADERS) priv/guest_arm64_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_arm64_helpers.o \ - -c priv/guest_arm64_helpers.c - -priv/guest_arm_toIR.o: $(ALL_HEADERS) priv/guest_arm_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_arm_toIR.o \ - -c priv/guest_arm_toIR.c - -priv/guest_arm64_toIR.o: $(ALL_HEADERS) priv/guest_arm64_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_arm64_toIR.o \ - -c priv/guest_arm64_toIR.c - -priv/guest_ppc_helpers.o: $(ALL_HEADERS) priv/guest_ppc_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_ppc_helpers.o \ - -c priv/guest_ppc_helpers.c - -priv/guest_s390_helpers.o: $(ALL_HEADERS) priv/guest_s390_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_s390_helpers.o \ - -c priv/guest_s390_helpers.c - -priv/guest_ppc_toIR.o: $(ALL_HEADERS) priv/guest_ppc_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_ppc_toIR.o \ - -c priv/guest_ppc_toIR.c - -priv/guest_s390_toIR.o: $(ALL_HEADERS) priv/guest_s390_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_s390_toIR.o \ - -c priv/guest_s390_toIR.c - -priv/s390_disasm.o: $(ALL_HEADERS) priv/s390_disasm.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/s390_disasm.o \ - -c priv/s390_disasm.c - -priv/guest_mips_helpers.o: $(ALL_HEADERS) priv/guest_mips_helpers.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_mips_helpers.o \ - -c priv/guest_mips_helpers.c - -priv/guest_mipsdsp_toIR.o: $(ALL_HEADERS) priv/guest_mipsdsp_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_mipsdsp_toIR.o \ - -c priv/guest_mipsdsp_toIR.c - -priv/guest_mips_toIR.o: $(ALL_HEADERS) priv/guest_mips_toIR.c - $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_mips_toIR.o \ - -c priv/guest_mips_toIR.c diff --git a/VEX/auxprogs/genoffsets.c b/VEX/auxprogs/genoffsets.c index 07ff09be7d..c4bb262c5e 100644 --- a/VEX/auxprogs/genoffsets.c +++ b/VEX/auxprogs/genoffsets.c @@ -98,7 +98,6 @@ void foo ( void ) GENOFFSET(X86,x86,FS); GENOFFSET(X86,x86,GS); GENOFFSET(X86,x86,SS); - GENOFFSET(X86,x86,SETC); // amd64 GENOFFSET(AMD64,amd64,RAX); @@ -118,7 +117,6 @@ void foo ( void ) GENOFFSET(AMD64,amd64,R14); GENOFFSET(AMD64,amd64,R15); GENOFFSET(AMD64,amd64,RIP); - GENOFFSET(AMD64,amd64,SETC); // ppc32 GENOFFSET(PPC32,ppc32,GPR0); @@ -174,7 +172,6 @@ void foo ( void ) GENOFFSET(ARM64,arm64,X8); GENOFFSET(ARM64,arm64,XSP); GENOFFSET(ARM64,arm64,PC); - GENOFFSET(ARM64,arm64,SETC); // s390x GENOFFSET(S390X,s390x,r2); @@ -186,7 +183,6 @@ void foo ( void ) GENOFFSET(S390X,s390x,r15); GENOFFSET(S390X,s390x,IA); GENOFFSET(S390X,s390x,SYSNO); - GENOFFSET(S390X,s390x,IP_AT_SYSCALL); GENOFFSET(S390X,s390x,fpc); GENOFFSET(S390X,s390x,CC_OP); GENOFFSET(S390X,s390x,CC_DEP1); diff --git a/VEX/priv/guest_amd64_defs.h b/VEX/priv/guest_amd64_defs.h index 35c74dcb83..0937a8607f 100644 --- a/VEX/priv/guest_amd64_defs.h +++ b/VEX/priv/guest_amd64_defs.h @@ -146,10 +146,6 @@ extern ULong amd64g_calc_crc32w ( ULong crcIn, ULong w ); extern ULong amd64g_calc_crc32l ( ULong crcIn, ULong l ); extern ULong amd64g_calc_crc32q ( ULong crcIn, ULong q ); -extern ULong amd64g_calc_mpsadbw ( ULong sHi, ULong sLo, - ULong dHi, ULong dLo, - ULong imm_and_return_control_bit ); - extern ULong amd64g_calculate_pext ( ULong, ULong ); extern ULong amd64g_calculate_pdep ( ULong, ULong ); diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c index ca33f7c818..69446a4130 100644 --- a/VEX/priv/guest_amd64_helpers.c +++ b/VEX/priv/guest_amd64_helpers.c @@ -42,6 +42,7 @@ #include "guest_generic_bb_to_IR.h" #include "guest_amd64_defs.h" #include "guest_generic_x87.h" +#include "guest_generic_helpers.h" /* This file contains helper functions for amd64 guest code. @@ -1989,6 +1990,14 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, // vassert(0); //} + /*---------------- SHLB ----------------*/ + if (isU64(cc_op, AMD64G_CC_OP_SHLB) && isU64(cond, AMD64CondZ)) { + /* SHLB, then Z --> test dep1 == 0 */ + return unop(Iop_1Uto64, + binop(Iop_CmpEQ8, unop(Iop_64to8, cc_dep1), + mkU8(0))); + } + /*---------------- COPY ----------------*/ /* This can happen, as a result of amd64 FP compares: "comisd ... ; jbe" for example. */ @@ -4028,10 +4037,6 @@ ULong amd64g_dirtyhelper_RDSEED ( void ) { /*--- Helpers for MMX/SSE/SSE2. ---*/ /*---------------------------------------------------------------*/ -static inline UChar abdU8 ( UChar xx, UChar yy ) { - return toUChar(xx>yy ? xx-yy : yy-xx); -} - static inline ULong mk32x2 ( UInt w1, UInt w0 ) { return (((ULong)w1) << 32) | ((ULong)w0); } @@ -4053,39 +4058,6 @@ static inline UShort sel16x4_0 ( ULong w64 ) { return toUShort(lo32); } -static inline UChar sel8x8_7 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 24); -} -static inline UChar sel8x8_6 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 16); -} -static inline UChar sel8x8_5 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 8); -} -static inline UChar sel8x8_4 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 0); -} -static inline UChar sel8x8_3 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 24); -} -static inline UChar sel8x8_2 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 16); -} -static inline UChar sel8x8_1 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 8); -} -static inline UChar sel8x8_0 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 0); -} - /* CALLED FROM GENERATED CODE: CLEAN HELPER */ ULong amd64g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) { @@ -4167,60 +4139,6 @@ ULong amd64g_calc_crc32q ( ULong crcIn, ULong q ) return amd64g_calc_crc32l(crc, q >> 32); } - -/* .. helper for next fn .. */ -static inline ULong sad_8x4 ( ULong xx, ULong yy ) -{ - UInt t = 0; - t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); - t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); - t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); - t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); - return (ULong)t; -} - -/* CALLED FROM GENERATED CODE: CLEAN HELPER */ -ULong amd64g_calc_mpsadbw ( ULong sHi, ULong sLo, - ULong dHi, ULong dLo, - ULong imm_and_return_control_bit ) -{ - UInt imm8 = imm_and_return_control_bit & 7; - Bool calcHi = (imm_and_return_control_bit >> 7) & 1; - UInt srcOffsL = imm8 & 3; /* src offs in 32-bit (L) chunks */ - UInt dstOffsL = (imm8 >> 2) & 1; /* dst offs in ditto chunks */ - /* For src we only need 32 bits, so get them into the - lower half of a 64 bit word. */ - ULong src = ((srcOffsL & 2) ? sHi : sLo) >> (32 * (srcOffsL & 1)); - /* For dst we need to get hold of 56 bits (7 bytes) from a total of - 11 bytes. If calculating the low part of the result, need bytes - dstOffsL * 4 + (0 .. 6); if calculating the high part, - dstOffsL * 4 + (4 .. 10). */ - ULong dst; - /* dstOffL = 0, Lo -> 0 .. 6 - dstOffL = 1, Lo -> 4 .. 10 - dstOffL = 0, Hi -> 4 .. 10 - dstOffL = 1, Hi -> 8 .. 14 - */ - if (calcHi && dstOffsL) { - /* 8 .. 14 */ - dst = dHi & 0x00FFFFFFFFFFFFFFULL; - } - else if (!calcHi && !dstOffsL) { - /* 0 .. 6 */ - dst = dLo & 0x00FFFFFFFFFFFFFFULL; - } - else { - /* 4 .. 10 */ - dst = (dLo >> 32) | ((dHi & 0x00FFFFFFULL) << 32); - } - ULong r0 = sad_8x4( dst >> 0, src ); - ULong r1 = sad_8x4( dst >> 8, src ); - ULong r2 = sad_8x4( dst >> 16, src ); - ULong r3 = sad_8x4( dst >> 24, src ); - ULong res = (r3 << 48) | (r2 << 32) | (r1 << 16) | r0; - return res; -} - /* CALLED FROM GENERATED CODE: CLEAN HELPER */ ULong amd64g_calculate_pext ( ULong src_masked, ULong mask ) { @@ -4820,8 +4738,6 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state ) vex_state->guest_EMNOTE = EmNote_NONE; - vex_state->guest_SETC = 0; - /* These should not ever be either read or written, but we initialise them anyway. */ vex_state->guest_CMSTART = 0; @@ -4831,7 +4747,6 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state ) vex_state->guest_SC_CLASS = 0; vex_state->guest_GS_CONST = 0; - vex_state->guest_IP_AT_SYSCALL = 0; vex_state->guest_TLSBASE = 0; } @@ -4905,7 +4820,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 16, + .n_alwaysDefd = 15, /* flags thunk: OP and NDEP are always defd, whereas DEP1 and DEP2 have to be tracked. See detailed comment in @@ -4933,8 +4848,7 @@ VexGuestLayout /* 11 */ ALWAYSDEFD(guest_SSEROUND), /* 12 */ ALWAYSDEFD(guest_CMSTART), /* 13 */ ALWAYSDEFD(guest_CMLEN), - /* 14 */ ALWAYSDEFD(guest_SC_CLASS), - /* 15 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) + /* 14 */ ALWAYSDEFD(guest_SC_CLASS) } }; diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index 34ebcbdf9a..c30bd173d3 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -292,6 +292,13 @@ static IRExpr* mkU ( IRType ty, ULong i ) } } +static IRExpr* mkV128 ( UShort mask ) +{ + return IRExpr_Const(IRConst_V128(mask)); +} + +#include "guest_generic_sse.h" + static void storeLE ( IRExpr* addr, IRExpr* data ) { stmt( IRStmt_Store(Iend_LE, addr, data) ); @@ -1668,11 +1675,6 @@ static void putYMMRegLane32 ( UInt ymmreg, Int laneno, IRExpr* e ) stmt( IRStmt_Put( ymmGuestRegLane32offset(ymmreg,laneno), e ) ); } -static IRExpr* mkV128 ( UShort mask ) -{ - return IRExpr_Const(IRConst_V128(mask)); -} - /* Write the low half of a YMM reg and zero out the upper half. */ static void putYMMRegLoAndZU ( UInt ymmreg, IRExpr* e ) { @@ -5967,6 +5969,10 @@ ULong dis_FPU ( /*OUT*/Bool* decode_ok, put_ST_UNCHECKED(r_src, mkexpr(t1)); break; + case 0xD0: /* FNOP */ + DIP("fnop\n"); + break; + case 0xE0: /* FCHS */ DIP("fchs\n"); put_ST_UNCHECKED(0, unop(Iop_NegF64, get_ST(0))); @@ -11229,30 +11235,6 @@ static IRTemp math_SHUFPD_256 ( IRTemp sV, IRTemp dV, UInt imm8 ) } -static IRTemp math_BLENDPD_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) -{ - UShort imm8_mask_16; - IRTemp imm8_mask = newTemp(Ity_V128); - - switch( imm8 & 3 ) { - case 0: imm8_mask_16 = 0x0000; break; - case 1: imm8_mask_16 = 0x00FF; break; - case 2: imm8_mask_16 = 0xFF00; break; - case 3: imm8_mask_16 = 0xFFFF; break; - default: vassert(0); break; - } - assign( imm8_mask, mkV128( imm8_mask_16 ) ); - - IRTemp res = newTemp(Ity_V128); - assign ( res, binop( Iop_OrV128, - binop( Iop_AndV128, mkexpr(sV), - mkexpr(imm8_mask) ), - binop( Iop_AndV128, mkexpr(dV), - unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) ); - return res; -} - - static IRTemp math_BLENDPD_256 ( IRTemp sV, IRTemp dV, UInt imm8 ) { IRTemp sVhi = IRTemp_INVALID, sVlo = IRTemp_INVALID; @@ -11266,26 +11248,6 @@ static IRTemp math_BLENDPD_256 ( IRTemp sV, IRTemp dV, UInt imm8 ) return rV; } - -static IRTemp math_BLENDPS_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) -{ - UShort imm8_perms[16] = { 0x0000, 0x000F, 0x00F0, 0x00FF, 0x0F00, - 0x0F0F, 0x0FF0, 0x0FFF, 0xF000, 0xF00F, - 0xF0F0, 0xF0FF, 0xFF00, 0xFF0F, 0xFFF0, - 0xFFFF }; - IRTemp imm8_mask = newTemp(Ity_V128); - assign( imm8_mask, mkV128( imm8_perms[ (imm8 & 15) ] ) ); - - IRTemp res = newTemp(Ity_V128); - assign ( res, binop( Iop_OrV128, - binop( Iop_AndV128, mkexpr(sV), - mkexpr(imm8_mask) ), - binop( Iop_AndV128, mkexpr(dV), - unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) ); - return res; -} - - static IRTemp math_BLENDPS_256 ( IRTemp sV, IRTemp dV, UInt imm8 ) { IRTemp sVhi = IRTemp_INVALID, sVlo = IRTemp_INVALID; @@ -11300,29 +11262,6 @@ static IRTemp math_BLENDPS_256 ( IRTemp sV, IRTemp dV, UInt imm8 ) } -static IRTemp math_PBLENDW_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) -{ - /* Make w be a 16-bit version of imm8, formed by duplicating each - bit in imm8. */ - Int i; - UShort imm16 = 0; - for (i = 0; i < 8; i++) { - if (imm8 & (1 << i)) - imm16 |= (3 << (2*i)); - } - IRTemp imm16_mask = newTemp(Ity_V128); - assign( imm16_mask, mkV128( imm16 )); - - IRTemp res = newTemp(Ity_V128); - assign ( res, binop( Iop_OrV128, - binop( Iop_AndV128, mkexpr(sV), - mkexpr(imm16_mask) ), - binop( Iop_AndV128, mkexpr(dV), - unop( Iop_NotV128, mkexpr(imm16_mask) ) ) ) ); - return res; -} - - static IRTemp math_PMULUDQ_128 ( IRTemp sV, IRTemp dV ) { /* This is a really poor translation -- could be improved if @@ -16692,29 +16631,6 @@ Long dis_ESC_0F__SSE4 ( Bool* decode_OK, /*--- ---*/ /*------------------------------------------------------------*/ -static IRTemp math_PBLENDVB_128 ( IRTemp vecE, IRTemp vecG, - IRTemp vec0/*controlling mask*/, - UInt gran, IROp opSAR ) -{ - /* The tricky bit is to convert vec0 into a suitable mask, by - copying the most significant bit of each lane into all positions - in the lane. */ - IRTemp sh = newTemp(Ity_I8); - assign(sh, mkU8(8 * gran - 1)); - - IRTemp mask = newTemp(Ity_V128); - assign(mask, binop(opSAR, mkexpr(vec0), mkexpr(sh))); - - IRTemp notmask = newTemp(Ity_V128); - assign(notmask, unop(Iop_NotV128, mkexpr(mask))); - - IRTemp res = newTemp(Ity_V128); - assign(res, binop(Iop_OrV128, - binop(Iop_AndV128, mkexpr(vecE), mkexpr(mask)), - binop(Iop_AndV128, mkexpr(vecG), mkexpr(notmask)))); - return res; -} - static IRTemp math_PBLENDVB_256 ( IRTemp vecE, IRTemp vecG, IRTemp vec0/*controlling mask*/, UInt gran, IROp opSAR128 ) @@ -19111,60 +19027,6 @@ static IRTemp math_DPPS_128 ( IRTemp src_vec, IRTemp dst_vec, UInt imm8 ) return res; } - -static IRTemp math_MPSADBW_128 ( IRTemp dst_vec, IRTemp src_vec, UInt imm8 ) -{ - /* Mask out bits of the operands we don't need. This isn't - strictly necessary, but it does ensure Memcheck doesn't - give us any false uninitialised value errors as a - result. */ - UShort src_mask[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; - UShort dst_mask[2] = { 0x07FF, 0x7FF0 }; - - IRTemp src_maskV = newTemp(Ity_V128); - IRTemp dst_maskV = newTemp(Ity_V128); - assign(src_maskV, mkV128( src_mask[ imm8 & 3 ] )); - assign(dst_maskV, mkV128( dst_mask[ (imm8 >> 2) & 1 ] )); - - IRTemp src_masked = newTemp(Ity_V128); - IRTemp dst_masked = newTemp(Ity_V128); - assign(src_masked, binop(Iop_AndV128, mkexpr(src_vec), mkexpr(src_maskV))); - assign(dst_masked, binop(Iop_AndV128, mkexpr(dst_vec), mkexpr(dst_maskV))); - - /* Generate 4 64 bit values that we can hand to a clean helper */ - IRTemp sHi = newTemp(Ity_I64); - IRTemp sLo = newTemp(Ity_I64); - assign( sHi, unop(Iop_V128HIto64, mkexpr(src_masked)) ); - assign( sLo, unop(Iop_V128to64, mkexpr(src_masked)) ); - - IRTemp dHi = newTemp(Ity_I64); - IRTemp dLo = newTemp(Ity_I64); - assign( dHi, unop(Iop_V128HIto64, mkexpr(dst_masked)) ); - assign( dLo, unop(Iop_V128to64, mkexpr(dst_masked)) ); - - /* Compute halves of the result separately */ - IRTemp resHi = newTemp(Ity_I64); - IRTemp resLo = newTemp(Ity_I64); - - IRExpr** argsHi - = mkIRExprVec_5( mkexpr(sHi), mkexpr(sLo), mkexpr(dHi), mkexpr(dLo), - mkU64( 0x80 | (imm8 & 7) )); - IRExpr** argsLo - = mkIRExprVec_5( mkexpr(sHi), mkexpr(sLo), mkexpr(dHi), mkexpr(dLo), - mkU64( 0x00 | (imm8 & 7) )); - - assign(resHi, mkIRExprCCall( Ity_I64, 0/*regparm*/, - "amd64g_calc_mpsadbw", - &amd64g_calc_mpsadbw, argsHi )); - assign(resLo, mkIRExprCCall( Ity_I64, 0/*regparm*/, - "amd64g_calc_mpsadbw", - &amd64g_calc_mpsadbw, argsLo )); - - IRTemp res = newTemp(Ity_V128); - assign(res, binop(Iop_64HLtoV128, mkexpr(resHi), mkexpr(resLo))); - return res; -} - static Long dis_EXTRACTPS ( const VexAbiInfo* vbi, Prefix pfx, Long delta, Bool isAvx ) { @@ -20786,8 +20648,8 @@ Long dis_ESC_NONE ( dis_REP_op ( dres, AMD64CondAlways, dis_MOVS, sz, guest_RIP_curr_instr, guest_RIP_bbstart+delta, "rep movs", pfx ); - dres->whatNext = Dis_StopHere; - return delta; + vassert(dres->whatNext == Dis_StopHere); + return delta; } /* A4: movsb */ if (!haveF3(pfx) && !haveF2(pfx)) { @@ -20800,14 +20662,31 @@ Long dis_ESC_NONE ( case 0xA6: case 0xA7: - /* F3 A6/A7: repe cmps/rep cmps{w,l,q} */ - if (haveF3(pfx) && !haveF2(pfx)) { + /* F2 A6/A7: repne cmpsb/repne cmps{w,l,q} */ + if (haveF2(pfx) && !haveF3(pfx)) { + if (opc == 0xA6) + sz = 1; + dis_REP_op ( dres, AMD64CondNZ, dis_CMPS, sz, + guest_RIP_curr_instr, + guest_RIP_bbstart+delta, "repne cmps", pfx ); + vassert(dres->whatNext == Dis_StopHere); + return delta; + } + /* F3 A6/A7: repe cmpsb/repe cmps{w,l,q} */ + if (!haveF2(pfx) && haveF3(pfx)) { if (opc == 0xA6) sz = 1; dis_REP_op ( dres, AMD64CondZ, dis_CMPS, sz, guest_RIP_curr_instr, guest_RIP_bbstart+delta, "repe cmps", pfx ); - dres->whatNext = Dis_StopHere; + vassert(dres->whatNext == Dis_StopHere); + return delta; + } + /* A6/A7: cmpsb/cmps{w,l,q} */ + if (!haveF2(pfx) && !haveF3(pfx)) { + if (opc == 0xA6) + sz = 1; + dis_string_op ( dis_CMPS, sz, "cmps", pfx ); return delta; } goto decode_failure; diff --git a/VEX/priv/guest_arm64_helpers.c b/VEX/priv/guest_arm64_helpers.c index d6a03fe364..5068a1a675 100644 --- a/VEX/priv/guest_arm64_helpers.c +++ b/VEX/priv/guest_arm64_helpers.c @@ -2109,7 +2109,6 @@ void LibVEX_GuestARM64_initialise ( /*OUT*/VexGuestARM64State* vex_state ) //ZZ vex_state->guest_CMSTART = 0; //ZZ vex_state->guest_CMLEN = 0; //ZZ vex_state->guest_NRADDR = 0; -//ZZ vex_state->guest_IP_AT_SYSCALL = 0; //ZZ //ZZ vex_state->guest_D0 = 0; //ZZ vex_state->guest_D1 = 0; @@ -2240,7 +2239,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 9, + .n_alwaysDefd = 8, /* flags thunk: OP is always defd, whereas DEP1 and DEP2 have to be tracked. See detailed comment in gdefs.h on @@ -2253,8 +2252,7 @@ VexGuestLayout /* 4 */ ALWAYSDEFD(guest_CMSTART), /* 5 */ ALWAYSDEFD(guest_CMLEN), /* 6 */ ALWAYSDEFD(guest_NRADDR), - /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), - /* 8 */ ALWAYSDEFD(guest_TPIDR_EL0) + /* 7 */ ALWAYSDEFD(guest_TPIDR_EL0) } }; diff --git a/VEX/priv/guest_arm_helpers.c b/VEX/priv/guest_arm_helpers.c index f573405717..3478d0c8a6 100644 --- a/VEX/priv/guest_arm_helpers.c +++ b/VEX/priv/guest_arm_helpers.c @@ -1291,7 +1291,7 @@ void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state ) vex_state->guest_CMSTART = 0; vex_state->guest_CMLEN = 0; vex_state->guest_NRADDR = 0; - vex_state->guest_IP_AT_SYSCALL = 0; + vex_state->padding1 = 0; vex_state->guest_D0 = 0; vex_state->guest_D1 = 0; @@ -1423,7 +1423,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 10, + .n_alwaysDefd = 9, /* flags thunk: OP is always defd, whereas DEP1 and DEP2 have to be tracked. See detailed comment in gdefs.h on @@ -1436,9 +1436,8 @@ VexGuestLayout /* 4 */ ALWAYSDEFD(guest_CMSTART), /* 5 */ ALWAYSDEFD(guest_CMLEN), /* 6 */ ALWAYSDEFD(guest_NRADDR), - /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), - /* 8 */ ALWAYSDEFD(guest_TPIDRURO), - /* 9 */ ALWAYSDEFD(guest_ITSTATE) + /* 7 */ ALWAYSDEFD(guest_TPIDRURO), + /* 8 */ ALWAYSDEFD(guest_ITSTATE) } }; diff --git a/VEX/priv/guest_generic_helpers.h b/VEX/priv/guest_generic_helpers.h new file mode 100644 index 0000000000..76d04c289d --- /dev/null +++ b/VEX/priv/guest_generic_helpers.h @@ -0,0 +1,132 @@ +/*---------------------------------------------------------------*/ +/*--- begin guest_generic_helpers.h ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2026 Alexandra Hájková + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ + +/* This file contains small helper functions shared between the x86 + and amd64 guest front ends and their corresponding helper files. + These are pure C utilities (no VEX IR dependencies) used by both + IR-building code (via guest_generic_sse.h) and runtime clean + helpers (via guest_{amd64,x86}_helpers.c). +*/ + +#ifndef __VEX_GUEST_GENERIC_HELPERS_H +#define __VEX_GUEST_GENERIC_HELPERS_H + +#include "libvex_basictypes.h" + +static inline UChar abdU8 ( UChar xx, UChar yy ) { + return toUChar(xx>yy ? xx-yy : yy-xx); +} + +static inline UChar sel8x8_7 ( ULong w64 ) { + UInt hi32 = toUInt(w64 >> 32); + return toUChar(hi32 >> 24); +} +static inline UChar sel8x8_6 ( ULong w64 ) { + UInt hi32 = toUInt(w64 >> 32); + return toUChar(hi32 >> 16); +} +static inline UChar sel8x8_5 ( ULong w64 ) { + UInt hi32 = toUInt(w64 >> 32); + return toUChar(hi32 >> 8); +} +static inline UChar sel8x8_4 ( ULong w64 ) { + UInt hi32 = toUInt(w64 >> 32); + return toUChar(hi32 >> 0); +} +static inline UChar sel8x8_3 ( ULong w64 ) { + UInt lo32 = toUInt(w64); + return toUChar(lo32 >> 24); +} +static inline UChar sel8x8_2 ( ULong w64 ) { + UInt lo32 = toUInt(w64); + return toUChar(lo32 >> 16); +} +static inline UChar sel8x8_1 ( ULong w64 ) { + UInt lo32 = toUInt(w64); + return toUChar(lo32 >> 8); +} +static inline UChar sel8x8_0 ( ULong w64 ) { + UInt lo32 = toUInt(w64); + return toUChar(lo32 >> 0); +} + +static inline ULong sad_8x4 ( ULong xx, ULong yy ) +{ + UInt t = 0; + t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); + t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); + t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); + t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); + return (ULong)t; +} + +/* CALLED FROM GENERATED CODE: CLEAN HELPER */ +static inline ULong g_calc_mpsadbw ( ULong sHi, ULong sLo, + ULong dHi, ULong dLo, + ULong imm_and_return_control_bit ) +{ + UInt imm8 = imm_and_return_control_bit & 7; + Bool calcHi = (imm_and_return_control_bit >> 7) & 1; + UInt srcOffsL = imm8 & 3; /* src offs in 32-bit (L) chunks */ + UInt dstOffsL = (imm8 >> 2) & 1; /* dst offs in ditto chunks */ + /* For src we only need 32 bits, so get them into the + lower half of a 64 bit word. */ + ULong src = ((srcOffsL & 2) ? sHi : sLo) >> (32 * (srcOffsL & 1)); + /* For dst we need to get hold of 56 bits (7 bytes) from a total of + 11 bytes. If calculating the low part of the result, need bytes + dstOffsL * 4 + (0 .. 6); if calculating the high part, + dstOffsL * 4 + (4 .. 10). */ + ULong dst; + /* dstOffL = 0, Lo -> 0 .. 6 + dstOffL = 1, Lo -> 4 .. 10 + dstOffL = 0, Hi -> 4 .. 10 + dstOffL = 1, Hi -> 8 .. 14 + */ + if (calcHi && dstOffsL) { + /* 8 .. 14 */ + dst = dHi & 0x00FFFFFFFFFFFFFFULL; + } + else if (!calcHi && !dstOffsL) { + /* 0 .. 6 */ + dst = dLo & 0x00FFFFFFFFFFFFFFULL; + } + else { + /* 4 .. 10 */ + dst = (dLo >> 32) | ((dHi & 0x00FFFFFFULL) << 32); + } + ULong r0 = sad_8x4( dst >> 0, src ); + ULong r1 = sad_8x4( dst >> 8, src ); + ULong r2 = sad_8x4( dst >> 16, src ); + ULong r3 = sad_8x4( dst >> 24, src ); + ULong res = (r3 << 48) | (r2 << 32) | (r1 << 16) | r0; + return res; +} + +#endif /* ndef __VEX_GUEST_GENERIC_HELPERS_H */ + +/*---------------------------------------------------------------*/ +/*--- end guest_generic_helpers.h ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest_generic_sse.h b/VEX/priv/guest_generic_sse.h new file mode 100644 index 0000000000..a7e7d563e7 --- /dev/null +++ b/VEX/priv/guest_generic_sse.h @@ -0,0 +1,213 @@ +/*---------------------------------------------------------------*/ +/*--- begin guest_generic_sse.h ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2025-2026 Alexandra Hájková + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ + +/* This file contains functions for SSE/SSE2/SSE3/SSE4-specific + operations. Both the amd64 and x86 front ends (guests) call + these functions. By putting them here, code duplication is + avoided. Some of these functions are tricky and hard to verify, + so there is much to be said for only having one copy thereof. + + IMPORTANT: This header must be included AFTER the following + helper functions/macros are defined in the including file: + - newTemp(IRType) - allocate a new IRTemp + - assign(IRTemp, IRExpr*) - create assignment statement + - mkV128(UShort) - create V128 constant expression + - binop(IROp, IRExpr*, IRExpr*) - create binary operation + - unop(IROp, IRExpr*) - create unary operation + - mkexpr(IRTemp) - create IRTemp expression + - vassert(Bool) - assertion macro + + These helper functions are defined locally in each guest_*_toIR.c + file because they rely on file-local global state, particularly + the 'irsb' variable (the IR super block being built). Moving them + to a shared header would require either passing 'irsb' as a + parameter to each call (breaking thousands of call sites) or + making 'irsb' a shared extern (architecturally problematic). + + Therefore, this header is included after those helpers are defined, + typically around line 300 in guest_*_toIR.c files. +*/ + +#ifndef __VEX_GUEST_GENERIC_SSE_H +#define __VEX_GUEST_GENERIC_SSE_H + +#include "libvex_basictypes.h" +#include "libvex_ir.h" +#include "libvex.h" +#include "guest_generic_helpers.h" + + +/* BLENDPD 128-bit */ +static inline IRTemp math_BLENDPD_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) +{ + UShort imm8_mask_16; + IRTemp imm8_mask = newTemp(Ity_V128); + + switch( imm8 & 3 ) { + case 0: imm8_mask_16 = 0x0000; break; + case 1: imm8_mask_16 = 0x00FF; break; + case 2: imm8_mask_16 = 0xFF00; break; + case 3: imm8_mask_16 = 0xFFFF; break; + default: vassert(0); break; + } + assign( imm8_mask, mkV128( imm8_mask_16 ) ); + + IRTemp res = newTemp(Ity_V128); + assign ( res, binop( Iop_OrV128, + binop( Iop_AndV128, mkexpr(sV), + mkexpr(imm8_mask) ), + binop( Iop_AndV128, mkexpr(dV), + unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) ); + return res; +} + +static inline IRTemp math_BLENDPS_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) +{ + UShort imm8_perms[16] = { 0x0000, 0x000F, 0x00F0, 0x00FF, 0x0F00, + 0x0F0F, 0x0FF0, 0x0FFF, 0xF000, 0xF00F, + 0xF0F0, 0xF0FF, 0xFF00, 0xFF0F, 0xFFF0, + 0xFFFF }; + IRTemp imm8_mask = newTemp(Ity_V128); + assign( imm8_mask, mkV128( imm8_perms[ (imm8 & 15) ] ) ); + + IRTemp res = newTemp(Ity_V128); + assign ( res, binop( Iop_OrV128, + binop( Iop_AndV128, mkexpr(sV), + mkexpr(imm8_mask) ), + binop( Iop_AndV128, mkexpr(dV), + unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) ); + return res; +} + +/*------------------------------------------------------------*/ +/*--- ---*/ +/*--- Top-level SSE4: dis_ESC_0F38__SSE4 ---*/ +/*--- ---*/ +/*------------------------------------------------------------*/ + +static inline IRTemp math_PBLENDVB_128 ( IRTemp vecE, IRTemp vecG, + IRTemp vec0/*controlling mask*/, + UInt gran, IROp opSAR ) +{ + /* The tricky bit is to convert vec0 into a suitable mask, by + copying the most significant bit of each lane into all positions + in the lane. */ + IRTemp sh = newTemp(Ity_I8); + assign(sh, mkU8(8 * gran - 1)); + + IRTemp mask = newTemp(Ity_V128); + assign(mask, binop(opSAR, mkexpr(vec0), mkexpr(sh))); + + IRTemp notmask = newTemp(Ity_V128); + assign(notmask, unop(Iop_NotV128, mkexpr(mask))); + + IRTemp res = newTemp(Ity_V128); + assign(res, binop(Iop_OrV128, + binop(Iop_AndV128, mkexpr(vecE), mkexpr(mask)), + binop(Iop_AndV128, mkexpr(vecG), mkexpr(notmask)))); + return res; +} + +static inline IRTemp math_PBLENDW_128 ( IRTemp sV, IRTemp dV, UInt imm8 ) +{ + /* Make w be a 16-bit version of imm8, formed by duplicating each + bit in imm8. */ + Int i; + UShort imm16 = 0; + for (i = 0; i < 8; i++) { + if (imm8 & (1 << i)) + imm16 |= (3 << (2*i)); + } + IRTemp imm16_mask = newTemp(Ity_V128); + assign( imm16_mask, mkV128( imm16 )); + + IRTemp res = newTemp(Ity_V128); + assign ( res, binop( Iop_OrV128, + binop( Iop_AndV128, mkexpr(sV), + mkexpr(imm16_mask) ), + binop( Iop_AndV128, mkexpr(dV), + unop( Iop_NotV128, mkexpr(imm16_mask) ) ) ) ); + return res; +} + +static IRTemp math_MPSADBW_128 ( IRTemp dst_vec, IRTemp src_vec, UInt imm8 ) +{ + /* Mask out bits of the operands we don't need. This isn't + strictly necessary, but it does ensure Memcheck doesn't + give us any false uninitialised value errors as a + result. */ + UShort src_mask[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; + UShort dst_mask[2] = { 0x07FF, 0x7FF0 }; + + IRTemp src_maskV = newTemp(Ity_V128); + IRTemp dst_maskV = newTemp(Ity_V128); + assign(src_maskV, mkV128( src_mask[ imm8 & 3 ] )); + assign(dst_maskV, mkV128( dst_mask[ (imm8 >> 2) & 1 ] )); + + IRTemp src_masked = newTemp(Ity_V128); + IRTemp dst_masked = newTemp(Ity_V128); + assign(src_masked, binop(Iop_AndV128, mkexpr(src_vec), mkexpr(src_maskV))); + assign(dst_masked, binop(Iop_AndV128, mkexpr(dst_vec), mkexpr(dst_maskV))); + + /* Generate 4 64 bit values that we can hand to a clean helper */ + IRTemp sHi = newTemp(Ity_I64); + IRTemp sLo = newTemp(Ity_I64); + assign( sHi, unop(Iop_V128HIto64, mkexpr(src_masked)) ); + assign( sLo, unop(Iop_V128to64, mkexpr(src_masked)) ); + + IRTemp dHi = newTemp(Ity_I64); + IRTemp dLo = newTemp(Ity_I64); + assign( dHi, unop(Iop_V128HIto64, mkexpr(dst_masked)) ); + assign( dLo, unop(Iop_V128to64, mkexpr(dst_masked)) ); + + /* Compute halves of the result separately */ + IRTemp resHi = newTemp(Ity_I64); + IRTemp resLo = newTemp(Ity_I64); + + IRExpr** argsHi + = mkIRExprVec_5( mkexpr(sHi), mkexpr(sLo), mkexpr(dHi), mkexpr(dLo), + mkU64( 0x80 | (imm8 & 7) )); + IRExpr** argsLo + = mkIRExprVec_5( mkexpr(sHi), mkexpr(sLo), mkexpr(dHi), mkexpr(dLo), + mkU64( 0x00 | (imm8 & 7) )); + + assign(resHi, mkIRExprCCall( Ity_I64, 0/*regparm*/, + "g_calc_mpsadbw", + &g_calc_mpsadbw, argsHi )); + assign(resLo, mkIRExprCCall( Ity_I64, 0/*regparm*/, + "g_calc_mpsadbw", + &g_calc_mpsadbw, argsLo )); + + IRTemp res = newTemp(Ity_V128); + assign(res, binop(Iop_64HLtoV128, mkexpr(resHi), mkexpr(resLo))); + return res; +} + +#endif /* ndef __VEX_GUEST_GENERIC_SSE_H */ + +/*---------------------------------------------------------------*/ +/*--- end guest_generic_sse.h ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest_mips_helpers.c b/VEX/priv/guest_mips_helpers.c index f7e6f39d2b..164dddebee 100644 --- a/VEX/priv/guest_mips_helpers.c +++ b/VEX/priv/guest_mips_helpers.c @@ -187,8 +187,6 @@ void LibVEX_GuestMIPS32_initialise( /*OUT*/ VexGuestMIPS32State * vex_state) vex_state->guest_w1.w64[1] = 0; vex_state->guest_w2.w64[0] = 0; vex_state->guest_w2.w64[1] = 0; - - vex_state->guest_IP_AT_SYSCALL = 0; } void LibVEX_GuestMIPS64_initialise ( /*OUT*/ VexGuestMIPS64State * vex_state ) @@ -296,8 +294,6 @@ void LibVEX_GuestMIPS64_initialise ( /*OUT*/ VexGuestMIPS64State * vex_state ) vex_state->guest_LLaddr = 0xFFFFFFFFFFFFFFFFULL; vex_state->guest_LLdata = 0; - vex_state->guest_IP_AT_SYSCALL = 0; - vex_state->guest_MSACSR = 0; } diff --git a/VEX/priv/guest_ppc_helpers.c b/VEX/priv/guest_ppc_helpers.c index 106f57e738..a48164a16a 100644 --- a/VEX/priv/guest_ppc_helpers.c +++ b/VEX/priv/guest_ppc_helpers.c @@ -2825,7 +2825,6 @@ void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state ) for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++) vex_state->guest_REDIR_STACK[i] = 0; - vex_state->guest_IP_AT_SYSCALL = 0; vex_state->guest_SPRG3_RO = 0; vex_state->guest_PPR = 0x4ULL << 50; // medium priority vex_state->guest_PSPB = 0x100; // an arbitrary non-zero value to start with @@ -3002,7 +3001,6 @@ void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state ) for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++) vex_state->guest_REDIR_STACK[i] = 0; - vex_state->guest_IP_AT_SYSCALL = 0; vex_state->guest_SPRG3_RO = 0; vex_state->guest_TFHAR = 0; vex_state->guest_TFIAR = 0; @@ -3136,7 +3134,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 12, + .n_alwaysDefd = 11, .alwaysDefd = { /* 0 */ ALWAYSDEFD32(guest_CIA), @@ -3149,8 +3147,7 @@ VexGuestLayout /* 7 */ ALWAYSDEFD32(guest_NRADDR_GPR2), /* 8 */ ALWAYSDEFD32(guest_REDIR_SP), /* 9 */ ALWAYSDEFD32(guest_REDIR_STACK), - /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL), - /* 11 */ ALWAYSDEFD32(guest_C_FPCC) + /* 10 */ ALWAYSDEFD32(guest_C_FPCC) } }; @@ -3178,7 +3175,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 12, + .n_alwaysDefd = 11, .alwaysDefd = { /* 0 */ ALWAYSDEFD64(guest_CIA), @@ -3191,8 +3188,7 @@ VexGuestLayout /* 7 */ ALWAYSDEFD64(guest_NRADDR_GPR2), /* 8 */ ALWAYSDEFD64(guest_REDIR_SP), /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK), - /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL), - /* 11 */ ALWAYSDEFD64(guest_C_FPCC) + /* 10 */ ALWAYSDEFD64(guest_C_FPCC) } }; diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index 231e914e5d..a5134e683a 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -316,7 +316,6 @@ static Bool OV32_CA32_supported = False; offsetof(VexGuestPPC32State, _x)) #define OFFB_CIA offsetofPPCGuestState(guest_CIA) -#define OFFB_IP_AT_SYSCALL offsetofPPCGuestState(guest_IP_AT_SYSCALL) #define OFFB_SPRG3_RO offsetofPPCGuestState(guest_SPRG3_RO) #define OFFB_LR offsetofPPCGuestState(guest_LR) #define OFFB_CTR offsetofPPCGuestState(guest_CTR) @@ -520,7 +519,6 @@ typedef enum { PPC_GST_EMWARN, // Emulation warnings PPC_GST_CMSTART,// For icbi: start of area to invalidate PPC_GST_CMLEN, // For icbi: length of area to invalidate - PPC_GST_IP_AT_SYSCALL, // the CIA of the most recently executed SC insn PPC_GST_SPRG3_RO, // SPRG3 PPC_GST_TFHAR, // Transactional Failure Handler Address Register PPC_GST_TFIAR, // Transactional Failure Instruction Address Register @@ -3659,10 +3657,6 @@ static void putGST ( PPC_GST reg, IRExpr* src ) IRType ty_src = typeOfIRExpr(irsb->tyenv,src ); vassert( reg < PPC_GST_MAX ); switch (reg) { - case PPC_GST_IP_AT_SYSCALL: - vassert( ty_src == ty ); - stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, src ) ); - break; case PPC_GST_CIA: vassert( ty_src == ty ); stmt( IRStmt_Put( OFFB_CIA, src ) ); @@ -10790,11 +10784,6 @@ static Bool dis_syslink ( UInt prefix, UInt theInstr, return False; } - /* Copy CIA into the IP_AT_SYSCALL pseudo-register, so that on Darwin - Valgrind can back the guest up to this instruction if it needs - to restart the syscall. */ - putGST( PPC_GST_IP_AT_SYSCALL, getGST( PPC_GST_CIA ) ); - /* It's important that all ArchRegs carry their up-to-date value at this point. So we declare an end-of-block here, which forces any TempRegs caching ArchRegs to be flushed. */ @@ -31513,14 +31502,14 @@ static Bool dis_VSR_byte_mask ( UInt prefix, UInt theInstr, immediate16_hi = (immediate16 >> 8) & 0xFF; immediate16_lo = immediate16 & 0xFF; - immediate64_hi = ((immediate16_hi << 32) | (immediate16_hi << 56) | + immediate64_hi = ((immediate16_hi << 56) | (immediate16_hi << 48) | (immediate16_hi << 40) | - (immediate16_hi << 32) | (immediate16_hi << 16) | + (immediate16_hi << 32) | (immediate16_hi << 24) | (immediate16_hi << 16) | (immediate16_hi << 8) | immediate16_hi); - immediate64_lo = ((immediate16_lo << 32) | (immediate16_lo << 56) | + immediate64_lo = ((immediate16_lo << 56) | (immediate16_lo << 48) | (immediate16_lo << 40) | - (immediate16_lo << 32) | (immediate16_lo << 16) | + (immediate16_lo << 32) | (immediate16_lo << 24) | (immediate16_lo << 16) | (immediate16_lo << 8) | immediate16_lo); /* Shift the bits in each element so the bit corresponding to the diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h index a780e83881..1d3a2be94d 100644 --- a/VEX/priv/guest_s390_defs.h +++ b/VEX/priv/guest_s390_defs.h @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2020 + Copyright IBM Corp. 2010-2026 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -267,13 +267,8 @@ typedef enum { S390_VEC_OP_INVALID = 0, S390_VEC_OP_VPKS, S390_VEC_OP_VPKLS, - S390_VEC_OP_VCEQ, S390_VEC_OP_VGFM, S390_VEC_OP_VGFMA, - S390_VEC_OP_VMAH, - S390_VEC_OP_VMALH, - S390_VEC_OP_VCH, - S390_VEC_OP_VCHL, S390_VEC_OP_VFTCI, S390_VEC_OP_VFMIN, S390_VEC_OP_VFMAX, diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index 3d6fec5c18..f5e8267145 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2020 + Copyright IBM Corp. 2010-2026 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -120,7 +120,7 @@ VexGuestLayout s390xGuest_layout = { /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 9, + .n_alwaysDefd = 8, /* Flags thunk: OP and NDEP are always defined, whereas DEP1 and DEP2 have to be tracked. See detailed comment in @@ -131,10 +131,9 @@ VexGuestLayout s390xGuest_layout = { /* 2 */ ALWAYSDEFD(guest_EMNOTE), /* generic */ /* 3 */ ALWAYSDEFD(guest_CMSTART), /* generic */ /* 4 */ ALWAYSDEFD(guest_CMLEN), /* generic */ - /* 5 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), /* generic */ - /* 6 */ ALWAYSDEFD(guest_IA), /* control reg */ - /* 7 */ ALWAYSDEFD(guest_fpc), /* control reg */ - /* 8 */ ALWAYSDEFD(guest_counter), /* internal usage register */ + /* 5 */ ALWAYSDEFD(guest_IA), /* control reg */ + /* 6 */ ALWAYSDEFD(guest_fpc), /* control reg */ + /* 7 */ ALWAYSDEFD(guest_counter), /* internal usage register */ } }; @@ -784,6 +783,10 @@ decode_bfp_rounding_mode(UInt irrm) case Irrm_ZERO: return S390_BFP_ROUND_ZERO; case Irrm_NEAREST_TIE_AWAY_0: return S390_BFP_ROUND_NEAREST_AWAY; case Irrm_PREPARE_SHORTER: return S390_BFP_ROUND_PREPARE_SHORT; + case Irrm_AWAY_FROM_ZERO: + case Irrm_NEAREST_TIE_TOWARD_0: + /* These cannot occur as they are DFP specific */ + break; } vpanic("decode_bfp_rounding_mode"); } @@ -1013,7 +1016,6 @@ decode_bfp_rounding_mode(UInt irrm) break; \ case S390_BFP_ROUND_PREPARE_SHORT: \ cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ - cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,3); \ break; \ case S390_BFP_ROUND_NEAREST_EVEN: \ cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ @@ -2402,13 +2404,8 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, {0x00, 0x00}, /* invalid */ [S390_VEC_OP_VPKS] = {0xe7, 0x97}, [S390_VEC_OP_VPKLS] = {0xe7, 0x95}, - [S390_VEC_OP_VCEQ] = {0xe7, 0xf8}, [S390_VEC_OP_VGFM] = {0xe7, 0xb4}, [S390_VEC_OP_VGFMA] = {0xe7, 0xbc}, - [S390_VEC_OP_VMAH] = {0xe7, 0xab}, - [S390_VEC_OP_VMALH] = {0xe7, 0xa9}, - [S390_VEC_OP_VCH] = {0xe7, 0xfb}, - [S390_VEC_OP_VCHL] = {0xe7, 0xf9}, [S390_VEC_OP_VFTCI] = {0xe7, 0x4a}, [S390_VEC_OP_VFMIN] = {0xe7, 0xee}, [S390_VEC_OP_VFMAX] = {0xe7, 0xef}, @@ -2489,10 +2486,7 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, switch(d->op) { case S390_VEC_OP_VPKS: case S390_VEC_OP_VPKLS: - case S390_VEC_OP_VCEQ: case S390_VEC_OP_VGFM: - case S390_VEC_OP_VCH: - case S390_VEC_OP_VCHL: the_insn.VRR.v1 = 1; the_insn.VRR.v2 = 2; the_insn.VRR.v3 = 3; @@ -2502,8 +2496,6 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, break; case S390_VEC_OP_VGFMA: - case S390_VEC_OP_VMAH: - case S390_VEC_OP_VMALH: case S390_VEC_OP_VMSL: the_insn.VRRd.v1 = 1; the_insn.VRRd.v2 = 2; diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index d98802829d..8ad8358edf 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2024 + Copyright IBM Corp. 2010-2026 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -49,17 +49,6 @@ static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *); static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp); static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp); -static const HChar *s390_irgen_BIC(UChar, IRTemp); -static const HChar *s390_irgen_VPDI(UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VFLR(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VFI(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VFPSO(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VCGD(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VCDG(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VCDLG(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_VCLGD(UChar, UChar, UChar, UChar, UChar); -static const HChar *s390_irgen_KMA(UChar, UChar, UChar); -static const HChar *s390_irgen_KMCTR(UChar, UChar, UChar); /*------------------------------------------------------------*/ /*--- Globals ---*/ @@ -113,25 +102,29 @@ typedef enum { #define RR_r2(insn) ((insn) & 0xf) #define RI_r1(insn) (((insn) >> 20) & 0xf) #define RI_i2(insn) ((insn) & 0xffff) +#define RRD_r1(insn) (((insn) >> 12) & 0xf) +#define RRD_r3(insn) (((insn) >> 4) & 0xf) +#define RRD_r2(insn) ((insn) & 0xf) #define RRE_r1(insn) (((insn) >> 4) & 0xf) #define RRE_r2(insn) ((insn) & 0xf) -#define RRF_r1(insn) (((insn) >> 12) & 0xf) -#define RRF_r3(insn) (((insn) >> 4) & 0xf) -#define RRF_r2(insn) ((insn) & 0xf) -#define RRF2_m3(insn) (((insn) >> 12) & 0xf) -#define RRF2_m4(insn) (((insn) >> 8) & 0xf) -#define RRF2_r1(insn) (((insn) >> 4) & 0xf) -#define RRF2_r2(insn) ((insn) & 0xf) -#define RRF3_r3(insn) (((insn) >> 12) & 0xf) -#define RRF3_r1(insn) (((insn) >> 4) & 0xf) -#define RRF3_r2(insn) ((insn) & 0xf) -#define RRF4_r3(insn) (((insn) >> 12) & 0xf) -#define RRF4_m4(insn) (((insn) >> 8) & 0xf) -#define RRF4_r1(insn) (((insn) >> 4) & 0xf) -#define RRF4_r2(insn) ((insn) & 0xf) -#define RRF5_m4(insn) (((insn) >> 8) & 0xf) -#define RRF5_r1(insn) (((insn) >> 4) & 0xf) -#define RRF5_r2(insn) ((insn) & 0xf) +#define RRFa_r3(insn) (((insn) >> 12) & 0xf) +#define RRFa_m4(insn) (((insn) >> 8) & 0xf) +#define RRFa_r1(insn) (((insn) >> 4) & 0xf) +#define RRFa_r2(insn) ((insn) & 0xf) +#define RRFb_r3(insn) (((insn) >> 12) & 0xf) +#define RRFb_m4(insn) (((insn) >> 8) & 0xf) +#define RRFb_r1(insn) (((insn) >> 4) & 0xf) +#define RRFb_r2(insn) ((insn) & 0xf) +#define RRFc_m3(insn) (((insn) >> 12) & 0xf) +#define RRFc_r1(insn) (((insn) >> 4) & 0xf) +#define RRFc_r2(insn) ((insn) & 0xf) +#define RRFd_m4(insn) (((insn) >> 8) & 0xf) +#define RRFd_r1(insn) (((insn) >> 4) & 0xf) +#define RRFd_r2(insn) ((insn) & 0xf) +#define RRFe_m3(insn) (((insn) >> 12) & 0xf) +#define RRFe_m4(insn) (((insn) >> 8) & 0xf) +#define RRFe_r1(insn) (((insn) >> 4) & 0xf) +#define RRFe_r2(insn) ((insn) & 0xf) #define RS_r1(insn) (((insn) >> 20) & 0xf) #define RS_r3(insn) (((insn) >> 16) & 0xf) #define RS_b2(insn) (((insn) >> 12) & 0xf) @@ -139,52 +132,38 @@ typedef enum { #define RSI_r1(insn) (((insn) >> 20) & 0xf) #define RSI_r3(insn) (((insn) >> 16) & 0xf) #define RSI_i2(insn) ((insn) & 0xffff) -#define RX_r1(insn) (((insn) >> 20) & 0xf) -#define RX_x2(insn) (((insn) >> 16) & 0xf) -#define RX_b2(insn) (((insn) >> 12) & 0xf) -#define RX_d2(insn) ((insn) & 0xfff) #define S_b2(insn) (((insn) >> 12) & 0xf) #define S_d2(insn) ((insn) & 0xfff) -#define SI_i2(insn) (((insn) >> 16) & 0xff) -#define SI_b1(insn) (((insn) >> 12) & 0xf) -#define SI_d1(insn) ((insn) & 0xfff) -#define SMI_m1(insn) (((insn) >> 52) & 0xf) -#define SMI_b3(insn) (((insn) >> 44) & 0xf) -#define SMI_d3(insn) (((insn) >> 32) & 0xfff) -#define SMI_i2(insn) (((insn) >> 16) & 0xffff) -#define RIE_r1(insn) (((insn) >> 52) & 0xf) -#define RIE_r3(insn) (((insn) >> 48) & 0xf) -#define RIE_i2(insn) (((insn) >> 32) & 0xffff) -#define RIE_RRUUU_r1(insn) (((insn) >> 52) & 0xf) -#define RIE_RRUUU_r2(insn) (((insn) >> 48) & 0xf) -#define RIE_RRUUU_i3(insn) (((insn) >> 40) & 0xff) -#define RIE_RRUUU_i4(insn) (((insn) >> 32) & 0xff) -#define RIE_RRUUU_i5(insn) (((insn) >> 24) & 0xff) -#define RIE_R0xU_r1(insn) (((insn) >> 52) & 0xf) -#define RIE_R0xU_i2(insn) (((insn) >> 32) & 0xffff) -#define RIE_R0xU_m3(insn) (((insn) >> 28) & 0xf) -#define RIE_RRPU_r1(insn) (((insn) >> 52) & 0xf) -#define RIE_RRPU_r2(insn) (((insn) >> 48) & 0xf) -#define RIE_RRPU_i4(insn) (((insn) >> 32) & 0xffff) -#define RIE_RRPU_m3(insn) (((insn) >> 28) & 0xf) -#define RIEv3_r1(insn) (((insn) >> 52) & 0xf) -#define RIEv3_m3(insn) (((insn) >> 48) & 0xf) -#define RIEv3_i4(insn) (((insn) >> 32) & 0xffff) -#define RIEv3_i2(insn) (((insn) >> 24) & 0xff) +#define RIEd_r1(insn) (((insn) >> 52) & 0xf) +#define RIEd_r3(insn) (((insn) >> 48) & 0xf) +#define RIEd_i2(insn) (((insn) >> 32) & 0xffff) +#define RIEe_r1(insn) (((insn) >> 52) & 0xf) +#define RIEe_r3(insn) (((insn) >> 48) & 0xf) +#define RIEe_i2(insn) (((insn) >> 32) & 0xffff) +#define RIEf_r1(insn) (((insn) >> 52) & 0xf) +#define RIEf_r2(insn) (((insn) >> 48) & 0xf) +#define RIEf_i3(insn) (((insn) >> 40) & 0xff) +#define RIEf_i4(insn) (((insn) >> 32) & 0xff) +#define RIEf_i5(insn) (((insn) >> 24) & 0xff) +#define RIEa_r1(insn) (((insn) >> 52) & 0xf) +#define RIEa_i2(insn) (((insn) >> 32) & 0xffff) +#define RIEa_m3(insn) (((insn) >> 28) & 0xf) +#define RIEb_r1(insn) (((insn) >> 52) & 0xf) +#define RIEb_r2(insn) (((insn) >> 48) & 0xf) +#define RIEb_i4(insn) (((insn) >> 32) & 0xffff) +#define RIEb_m3(insn) (((insn) >> 28) & 0xf) +#define RIEc_r1(insn) (((insn) >> 52) & 0xf) +#define RIEc_m3(insn) (((insn) >> 48) & 0xf) +#define RIEc_i4(insn) (((insn) >> 32) & 0xffff) +#define RIEc_i2(insn) (((insn) >> 24) & 0xff) +#define RIEg_r1(insn) (((insn) >> 52) & 0xf) +#define RIEg_m3(insn) (((insn) >> 48) & 0xf) +#define RIEg_i2(insn) (((insn) >> 32) & 0xffff) #define RIL_r1(insn) (((insn) >> 52) & 0xf) #define RIL_i2(insn) (((insn) >> 16) & 0xffffffff) -#define RIS_r1(insn) (((insn) >> 52) & 0xf) -#define RIS_m3(insn) (((insn) >> 48) & 0xf) -#define RIS_b4(insn) (((insn) >> 44) & 0xf) -#define RIS_d4(insn) (((insn) >> 32) & 0xfff) -#define RIS_i2(insn) (((insn) >> 24) & 0xff) -#define RRS_r1(insn) (((insn) >> 52) & 0xf) -#define RRS_r2(insn) (((insn) >> 48) & 0xf) -#define RRS_b4(insn) (((insn) >> 44) & 0xf) -#define RRS_d4(insn) (((insn) >> 32) & 0xfff) -#define RRS_m3(insn) (((insn) >> 28) & 0xf) #define RSY_r1(insn) (((insn) >> 52) & 0xf) #define RSY_r3(insn) (((insn) >> 48) & 0xf) +#define RSY_m3(insn) (((insn) >> 48) & 0xf) #define RSY_b2(insn) (((insn) >> 44) & 0xf) #define RSY_dl2(insn) (((insn) >> 32) & 0xfff) #define RSY_dh2(insn) (((insn) >> 24) & 0xff) @@ -193,117 +172,45 @@ typedef enum { #define RXE_b2(insn) (((insn) >> 44) & 0xf) #define RXE_d2(insn) (((insn) >> 32) & 0xfff) #define RXE_m3(insn) (((insn) >> 28) & 0xf) -#define RXF_r3(insn) (((insn) >> 52) & 0xf) -#define RXF_x2(insn) (((insn) >> 48) & 0xf) -#define RXF_b2(insn) (((insn) >> 44) & 0xf) -#define RXF_d2(insn) (((insn) >> 32) & 0xfff) -#define RXF_r1(insn) (((insn) >> 28) & 0xf) #define RXY_r1(insn) (((insn) >> 52) & 0xf) #define RXY_x2(insn) (((insn) >> 48) & 0xf) #define RXY_b2(insn) (((insn) >> 44) & 0xf) #define RXY_dl2(insn) (((insn) >> 32) & 0xfff) #define RXY_dh2(insn) (((insn) >> 24) & 0xff) -#define SIY_i2(insn) (((insn) >> 48) & 0xff) -#define SIY_b1(insn) (((insn) >> 44) & 0xf) -#define SIY_dl1(insn) (((insn) >> 32) & 0xfff) -#define SIY_dh1(insn) (((insn) >> 24) & 0xff) -#define SS_l(insn) (((insn) >> 48) & 0xff) -#define SS_b1(insn) (((insn) >> 44) & 0xf) -#define SS_d1(insn) (((insn) >> 32) & 0xfff) -#define SS_b2(insn) (((insn) >> 28) & 0xf) -#define SS_d2(insn) (((insn) >> 16) & 0xfff) -#define SIL_b1(insn) (((insn) >> 44) & 0xf) -#define SIL_d1(insn) (((insn) >> 32) & 0xfff) -#define SIL_i2(insn) (((insn) >> 16) & 0xffff) -#define VRX_v1(insn) (((insn) >> 52) & 0xf) -#define VRX_x2(insn) (((insn) >> 48) & 0xf) -#define VRX_b2(insn) (((insn) >> 44) & 0xf) -#define VRX_d2(insn) (((insn) >> 32) & 0xfff) -#define VRX_m3(insn) (((insn) >> 28) & 0xf) -#define VRX_rxb(insn) (((insn) >> 24) & 0xf) +#define SSa_l(insn) (((insn) >> 48) & 0xff) +#define SSa_b1(insn) (((insn) >> 44) & 0xf) +#define SSa_d1(insn) (((insn) >> 32) & 0xfff) +#define SSa_b2(insn) (((insn) >> 28) & 0xf) +#define SSa_d2(insn) (((insn) >> 16) & 0xfff) +#define V_rxb(insn) (((insn) >> 24) & 0xf) #define VRR_v1(insn) (((insn) >> 52) & 0xf) #define VRR_v2(insn) (((insn) >> 48) & 0xf) #define VRR_r2(insn) (((insn) >> 48) & 0xf) #define VRR_r3(insn) (((insn) >> 44) & 0xf) #define VRR_v3(insn) (((insn) >> 44) & 0xf) -#define VRR_m5(insn) (((insn) >> 36) & 0xf) -#define VRR_m4(insn) (((insn) >> 28) & 0xf) #define VRR_v4(insn) (((insn) >> 28) & 0xf) -#define VRR_rxb(insn) (((insn) >> 24) & 0xf) -#define VRRa_v1(insn) (((insn) >> 52) & 0xf) -#define VRRa_v2(insn) (((insn) >> 48) & 0xf) -#define VRRa_v3(insn) (((insn) >> 44) & 0xf) #define VRRa_m5(insn) (((insn) >> 36) & 0xf) #define VRRa_m4(insn) (((insn) >> 32) & 0xf) #define VRRa_m3(insn) (((insn) >> 28) & 0xf) -#define VRRa_rxb(insn) (((insn) >> 24) & 0xf) -#define VRRd_v1(insn) (((insn) >> 52) & 0xf) -#define VRRd_v2(insn) (((insn) >> 48) & 0xf) -#define VRRd_v3(insn) (((insn) >> 44) & 0xf) +#define VRRc_m6(insn) (((insn) >> 36) & 0xf) +#define VRRc_m5(insn) (((insn) >> 32) & 0xf) +#define VRRc_m4(insn) (((insn) >> 28) & 0xf) #define VRRd_m5(insn) (((insn) >> 40) & 0xf) #define VRRd_m6(insn) (((insn) >> 36) & 0xf) -#define VRRd_v4(insn) (((insn) >> 28) & 0xf) -#define VRRd_rxb(insn) (((insn) >> 24) & 0xf) -#define VRRe_v1(insn) (((insn) >> 52) & 0xf) -#define VRRe_v2(insn) (((insn) >> 48) & 0xf) -#define VRRe_v3(insn) (((insn) >> 44) & 0xf) -#define VRRe_m6(insn) (((insn) >> 40) & 0xf) -#define VRRe_m5(insn) (((insn) >> 32) & 0xf) -#define VRRe_v4(insn) (((insn) >> 28) & 0xf) -#define VRRe_rxb(insn) (((insn) >> 24) & 0xf) -#define VRI_v1(insn) (((insn) >> 52) & 0xf) -#define VRI_v3(insn) (((insn) >> 48) & 0xf) -#define VRI_i2(insn) (((insn) >> 32) & 0xffff) -#define VRI_m3(insn) (((insn) >> 28) & 0xf) -#define VRI_rxb(insn) (((insn) >> 24) & 0xf) -#define VRIb_v1(insn) (((insn) >> 52) & 0xf) -#define VRIb_i2(insn) (((insn) >> 40) & 0xff) -#define VRIb_i3(insn) (((insn) >> 32) & 0xff) -#define VRIb_m4(insn) (((insn) >> 28) & 0xf) -#define VRIb_rxb(insn) (((insn) >> 24) & 0xf) -#define VRIc_v1(insn) (((insn) >> 52) & 0xf) -#define VRIc_v3(insn) (((insn) >> 48) & 0xf) -#define VRIc_i2(insn) (((insn) >> 32) & 0xffff) -#define VRIc_m4(insn) (((insn) >> 28) & 0xf) -#define VRIc_rxb(insn) (((insn) >> 24) & 0xf) +#define VRIa_v1(insn) (((insn) >> 52) & 0xf) +#define VRIa_v3(insn) (((insn) >> 48) & 0xf) +#define VRIa_i2(insn) (((insn) >> 32) & 0xffff) +#define VRIa_m3(insn) (((insn) >> 28) & 0xf) #define VRId_v1(insn) (((insn) >> 52) & 0xf) #define VRId_v2(insn) (((insn) >> 48) & 0xf) #define VRId_v3(insn) (((insn) >> 44) & 0xf) #define VRId_i4(insn) (((insn) >> 32) & 0xff) #define VRId_m5(insn) (((insn) >> 28) & 0xf) -#define VRId_rxb(insn) (((insn) >> 24) & 0xf) -#define VRIe_v1(insn) (((insn) >> 52) & 0xf) -#define VRIe_v2(insn) (((insn) >> 48) & 0xf) -#define VRIe_i3(insn) (((insn) >> 36) & 0xfff) -#define VRIe_m5(insn) (((insn) >> 32) & 0xf) -#define VRIe_m4(insn) (((insn) >> 28) & 0xf) -#define VRIe_rxb(insn) (((insn) >> 24) & 0xf) -#define VRS_v1(insn) (((insn) >> 52) & 0xf) -#define VRS_v3(insn) (((insn) >> 48) & 0xf) -#define VRS_r3(insn) (((insn) >> 48) & 0xf) -#define VRS_b2(insn) (((insn) >> 44) & 0xf) -#define VRS_d2(insn) (((insn) >> 32) & 0xfff) -#define VRS_m4(insn) (((insn) >> 28) & 0xf) -#define VRS_rxb(insn) (((insn) >> 24) & 0xf) -#define VRSc_r1(insn) (((insn) >> 52) & 0xf) -#define VRSc_v3(insn) (((insn) >> 48) & 0xf) -#define VRSc_b2(insn) (((insn) >> 44) & 0xf) -#define VRSc_d2(insn) (((insn) >> 32) & 0xfff) -#define VRSc_m4(insn) (((insn) >> 28) & 0xf) -#define VRSc_rxb(insn) (((insn) >> 24) & 0xf) -#define VRSd_v1(insn) (((insn) >> 28) & 0xf) -#define VRSd_r3(insn) (((insn) >> 48) & 0xf) -#define VSI_i3(insn) (((insn) >> 48) & 0xff) -#define VSI_b2(insn) (((insn) >> 44) & 0xf) -#define VSI_d2(insn) (((insn) >> 32) & 0xfff) -#define VSI_v1(insn) (((insn) >> 28) & 0xf) -#define VSI_rxb(insn) (((insn) >> 24) & 0xf) -#define VRV_v1(insn) (((insn) >> 52) & 0xf) -#define VRV_x2(insn) (((insn) >> 48) & 0xf) -#define VRV_b2(insn) (((insn) >> 44) & 0xf) -#define VRV_d2(insn) (((insn) >> 32) & 0xfff) -#define VRV_m3(insn) (((insn) >> 28) & 0xf) -#define VRV_rxb(insn) (((insn) >> 24) & 0xf) +#define VRSb_v1(insn) (((insn) >> 52) & 0xf) +#define VRSb_r3(insn) (((insn) >> 48) & 0xf) +#define VRSb_b2(insn) (((insn) >> 44) & 0xf) +#define VRSb_d2(insn) (((insn) >> 32) & 0xfff) +#define VRSb_m4(insn) (((insn) >> 28) & 0xf) /*------------------------------------------------------------*/ @@ -575,10 +482,6 @@ system_call(IRExpr *sysno) /* Store the system call number in the pseudo register. */ stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno)); - /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */ - stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL), - mkU64(guest_IA_curr_instr))); - put_IA(mkaddr_expr(guest_IA_next_instr)); /* It's important that all ArchRegs carry their up-to-date value @@ -599,10 +502,6 @@ extension(ULong id, ULong variant) ULong ext_id = id | (variant << S390_EXT_ID_NBITS); stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), mkU64(ext_id))); - /* Store the current IA into guest_IP_AT_SYSCALL. */ - stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL), - mkU64(guest_IA_curr_instr))); - put_IA(mkaddr_expr(guest_IA_next_instr)); dis_res->whatNext = Dis_StopHere; @@ -661,12 +560,12 @@ yield_if(IRExpr *condition) /* Convenience macro to yield a specification exception if the given condition is not met. Used to pass this type of decoding error up through the call chain. */ -#define s390_insn_assert(mnm, cond) \ +#define s390_insn_assert(cond) \ do { \ if (!(cond)) { \ dis_res->whatNext = Dis_StopHere; \ dis_res->jk_StopHere = Ijk_NoDecode; \ - return (mnm); \ + return; \ } \ } while (0) @@ -2043,196 +1942,385 @@ s390_vr_get_ftype(const UChar m) */ #define s390_vr_is_single_element_control_set(m) (((m) & 0x8) != 0) -/* Generates arg1 < arg2 (or arg1 <= arg2 if allow_equal == True) expression. - Arguments must have V128 type and are treated as unsigned 128-bit numbers. -*/ -static IRExpr* -s390_V128_compareLT128x1(IRExpr* arg1, IRExpr* arg2, Bool allow_equal) -{ - /* If high halves are equal - then we compare lower ones - otherwise we compare high halves. - */ - IRExpr* result; - result = mkite(binop(Iop_CmpEQ64, - unop(Iop_V128HIto64, arg1), - unop(Iop_V128HIto64, arg2) - ), - unop(Iop_1Uto64, - binop(allow_equal ? Iop_CmpLE64U : Iop_CmpLT64U, - unop(Iop_V128to64, arg1), - unop(Iop_V128to64, arg2) - ) - ), - unop(Iop_1Uto64, - binop(Iop_CmpLT64U, - unop(Iop_V128HIto64, arg1), - unop(Iop_V128HIto64, arg2) - ) - ) - ); - - return result; -} - -/* Generates arg1 == 0 expression. - Argument must have V128 type and is treated as unsigned 128-bit number. -*/ +/* Return a vector that consists of copies of the same value */ static IRExpr* -s390_V128_isZero(IRExpr* arg) +s390_V128_fill(IRExpr* elem) { - IRExpr* high_or_low = binop(Iop_Or64, - unop(Iop_V128to64, arg), - unop(Iop_V128HIto64, arg) - ); + IRType o2type = typeOfIRExpr(irsb->tyenv, elem); + switch (o2type) { + case Ity_I8: + return unop(Iop_Dup8x16, elem); + case Ity_I16: + return unop(Iop_Dup16x8, elem); + case Ity_I32: + return unop(Iop_Dup32x4, elem); + case Ity_I64: { + IRTemp val = newTemp(Ity_I64); + assign(val, elem); + return binop(Iop_64HLtoV128, mkexpr(val), mkexpr(val)); + } + default: + ppIRType(o2type); + vpanic("s390_V128_fill: invalid IRType"); + } +} - return unop(Iop_1Uto64, binop(Iop_CmpEQ64, high_or_low, mkU64(0ULL))); +/* Widen a 64-bit vector, sign- or zero-extending its integer lanes */ +static IRExpr* +s390_V128_unpack(IRExpr* a, UChar es, Bool is_signed) +{ + vassert(es <= 3); + if (es <= 2) { + const IROp sops[] = {Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, + Iop_Widen32Sto64x2}; + const IROp uops[] = {Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, + Iop_Widen32Uto64x2}; + return unop((is_signed ? sops : uops)[es], a); + } else { + IRTemp lo = newTemp(Ity_I64); + IRExpr* hi; + assign(lo, a); + if (is_signed) { + hi = binop(Iop_Sar64, mkexpr(lo), mkU8(63)); + } else { + hi = mkU64(0); + } + return binop(Iop_64HLtoV128, hi, mkexpr(lo)); + } } -/* Generate the two's complement for arg. - Arg should be V128. -*/ +/* Return a vector that consists of copies of a 16-bit integer, sign-extended or + reduced to the lane size as appropriate */ static IRExpr* -s390_V128_get_complement(IRExpr* arg, IRType type) +s390_V128_fillnum(Short num, UChar es) { - IRExpr* notArg = unop(Iop_NotV128, arg); - IRExpr* ones; - IRExpr* result; - switch(type) { - case Ity_I8: - ones = unop(Iop_Dup8x16, mkU8(0x01)); - result = binop(Iop_Add8x16, notArg, ones); - break; - case Ity_I16: - ones = unop(Iop_Dup16x8, mkU16(0x0001)); - result = binop(Iop_Add16x8, notArg, ones); - break; - case Ity_I32: - ones = unop(Iop_Dup32x4, mkU32(0x00000001)); - result = binop(Iop_Add32x4, notArg, ones); - break; - case Ity_I64: - ones = binop(Iop_64HLtoV128, mkU64(0x1ULL), mkU64(0x1ULL)); - result = binop(Iop_Add64x2, notArg, ones); - break; - case Ity_V128: - ones = binop(Iop_64HLtoV128, mkU64(0x0ULL), mkU64(0x1ULL)); - result = binop(Iop_Add128x1, notArg, ones); - break; + switch (es) { + case 0: + return unop(Iop_Dup8x16, mkU8((UChar)num)); + case 1: + return unop(Iop_Dup16x8, mkU16((UShort)num)); + case 2: + return unop(Iop_Dup32x4, mkU32((UInt)num)); + case 3: + return s390_V128_fill(mkU64((ULong)num)); + case 4: + return binop(Iop_64HLtoV128, mkU64((num < 0) ? -1 : 0), + mkU64((ULong)num)); default: - vpanic("s390_V128_get_complement: unknown type"); + vpanic("s390_V128_fillnum: unknown element size"); } +} - return result; +/* Replicate highest bit within each lane */ +static IRExpr* +s390_V128_high_set(IRExpr* v1, UChar es) +{ + static const IROp ops[] = {Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, + Iop_SarN64x2, Iop_SarV128}; + vassert(es < sizeof(ops) / sizeof(ops[0])); + UChar bitwidth = 8 << es; + return binop(ops[es], v1, mkU8(bitwidth - 1)); } -/* # Elements are treated as 128-bit unsigned integers - For i = 0; i < elemCount; i++ do: - sum = arg1[i] + arg2[i] - result[i] = carry_out_bit(sum) - end - return result +/* Bitwise vCond ? v1 : v2 + All args are V128. */ static IRExpr* -s390_V128_calculate_carry_out(IRExpr* arg1, IRExpr* arg2, IRType type, - Bool allow_equal) +s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2) { - IRTemp sum = newTemp(Ity_V128); - IRExpr* mask; - IRExpr* comparison; - IRExpr* result; - switch(type){ - case Ity_I8: - assign(sum, binop(Iop_Add8x16, arg1, arg2)); - mask = unop(Iop_Dup8x16, mkU8(0x1)); - comparison = binop(Iop_CmpGT8Ux16, arg1, mkexpr(sum)); - if(allow_equal) { - comparison = binop(Iop_OrV128, binop(Iop_CmpEQ8x16, arg1, mkexpr(sum)), - comparison); - } - result = binop(Iop_AndV128, comparison, mask); - break; - case Ity_I16: - assign(sum, binop(Iop_Add16x8, arg1, arg2)); - mask = unop(Iop_Dup16x8, mkU16(0x1)); - comparison = binop(Iop_CmpGT16Ux8, arg1, mkexpr(sum)); - if(allow_equal) { - comparison = binop(Iop_OrV128, binop(Iop_CmpEQ16x8, arg1, mkexpr(sum)), - comparison); - } - result = binop(Iop_AndV128, comparison, mask); - break; - case Ity_I32: - assign(sum, binop(Iop_Add32x4, arg1, arg2)); - mask = unop(Iop_Dup32x4, mkU32(0x1)); - comparison = binop(Iop_CmpGT32Ux4, arg1, mkexpr(sum)); - if(allow_equal) { - comparison = binop(Iop_OrV128, binop(Iop_CmpEQ32x4, arg1, mkexpr(sum)), - comparison); - } - result = binop(Iop_AndV128, comparison, mask); - break; - case Ity_I64: - assign(sum, binop(Iop_Add64x2, arg1, arg2)); - mask = binop(Iop_64HLtoV128, mkU64(0x1), mkU64(0x1)); - comparison = binop(Iop_CmpGT64Ux2, arg1, mkexpr(sum)); - if(allow_equal) { - comparison = binop(Iop_OrV128, binop(Iop_CmpEQ64x2, arg1, mkexpr(sum)), - comparison); - } - result = binop(Iop_AndV128, comparison, mask); - break; - case Ity_V128: - assign(sum, binop(Iop_Add128x1, arg1, arg2)); - comparison = s390_V128_compareLT128x1(mkexpr(sum), arg1, allow_equal); - result = binop(Iop_64HLtoV128, mkU64(0x0), comparison); - break; - default: - ppIRType(type); - vpanic("s390_V128_calculate_carry_out: unknown type"); + IRTemp vc = newTemp(Ity_V128); + assign(vc, vCond); + /* result = (v1 & vCond) | (v2 & ~vCond) */ + return binop(Iop_OrV128, + binop(Iop_AndV128, v1, mkexpr(vc)), + binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc)))); +} + +/* Return a == b (lane-wise) for the given element size */ +static IRExpr* +s390_V128_CmpEQ(IRExpr *a, IRExpr *b, UChar es) +{ + if (es < 4) { + const IROp op_cmp[] = {Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, + Iop_CmpEQ64x2}; + return binop(op_cmp[es], a, b); + } else { + IRTemp t = newTemp(Ity_V128); + assign(t, binop(Iop_CmpEQ64x2, a, b)); + return binop(Iop_AndV128, s390_V128_fill(unop(Iop_V128to64, mkexpr(t))), + s390_V128_fill(unop(Iop_V128HIto64, mkexpr(t)))); } +} - return result; +/* Return a > b for a 128-bit integer in a vector */ +static IRExpr* +s390_V128_CmpGT128x1(IRExpr* a, IRExpr* b, Bool is_signed, Bool lsb_only) +{ + IRTemp ta = newTemp(Ity_V128); + IRTemp tb = newTemp(Ity_V128); + assign(ta, a); + assign(tb, b); + IRExpr* result = + s390_V128_bitwiseITE(binop(Iop_XorV128, mkexpr(ta), mkexpr(tb)), + is_signed ? mkexpr(tb) : mkexpr(ta), + binop(Iop_Sub128x1, mkexpr(tb), mkexpr(ta))); + return binop(lsb_only ? Iop_ShrV128 : Iop_SarV128, result, mkU8(127)); } -/* # elemCount = 1 for now (elements are 128-bit unsigned integers) - For i = 0; i < elemCount; i++ do: - sum = arg1[i] + arg2[i] + arg3[i] & 0x1 - result[i] = carry_out_bit(sum) - end - return result - */ +/* Return a > b (unsigned, lane-wise) for the given element size */ static IRExpr* -s390_V128_calculate_carry_out_with_carry(IRExpr* arg1, IRExpr* arg2, IRExpr* arg3) +s390_V128_CmpGTU(IRExpr* a, IRExpr* b, UChar es) { - IRTemp sum = newTemp(Ity_V128); - assign(sum, binop(Iop_Add128x1, arg1, arg2)); + if (es < 4) { + const IROp ops[] = {Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, + Iop_CmpGT64Ux2}; + return binop(ops[es], a, b); + } else { + return s390_V128_CmpGT128x1(a, b, False, False); + } +} - IRTemp overflow_before = newTemp(Ity_I64); - assign(overflow_before, s390_V128_compareLT128x1(mkexpr(sum), arg1, False)); +/* Return a > b (signed, lane-wise) for the given element size */ +static IRExpr* +s390_V128_CmpGTS(IRExpr* a, IRExpr* b, UChar es) +{ + if (es < 4) { + const IROp ops[] = {Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, + Iop_CmpGT64Sx2}; + return binop(ops[es], a, b); + } else { + return s390_V128_CmpGT128x1(a, b, True, False); + } +} - IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1)); - IRTemp carry_in = newTemp(Ity_V128); - assign(carry_in, binop(Iop_AndV128, arg3, mask)); +/* For a given vector comparison result, set the condition code accordingly */ +static void +s390_V128_setcc_for_cmp(IRTemp cmp_res, UChar es) +{ + IRTemp cc = newTemp(Ity_I64); + IRTemp lo = newTemp(Ity_I64); + assign(lo, unop(Iop_V128to64, mkexpr(cmp_res))); + if (es == 4) { + // Full-sized single lane + assign(cc, mkite(binop(Iop_CmpEQ64, mkexpr(lo), mkU64(0)), mkU64(3), + mkU64(0))); + } else { + IRTemp hi = newTemp(Ity_I64); + assign(hi, unop(Iop_V128HIto64, mkexpr(cmp_res))); + IRExpr* allZero = + binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(lo), mkexpr(hi)), mkU64(0)); + IRExpr* allOnes = binop( + Iop_CmpEQ64, binop(Iop_And64, mkexpr(lo), mkexpr(hi)), mkU64(-1ULL)); + assign(cc, mkite(allZero, mkU64(3), mkite(allOnes, mkU64(0), mkU64(1)))); + } + s390_cc_set(cc); +} + +/* Return a + b for the given element size */ +static IRExpr* +s390_V128_add(IRExpr* a, IRExpr* b, UChar es) +{ + const IROp add_op[] = {Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, Iop_Add64x2, + Iop_Add128x1}; + vassert(es <= 4); + return binop(add_op[es], a, b); +} + +/* Return a - b for the given element size */ +static IRExpr* +s390_V128_sub(IRExpr* a, IRExpr* b, UChar es) +{ + const IROp sub_op[] = {Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, Iop_Sub64x2, + Iop_Sub128x1}; + vassert(es <= 4); + return binop(sub_op[es], a, b); +} + +/* Return the two's complement of arg for the given element size */ +static IRExpr* +s390_V128_get_complement(IRExpr* arg, UChar es) +{ + return s390_V128_sub(mkV128(0), arg, es); +} + +/* Return the carry of a + b + (c & 1) with 128-bit integers */ +static IRExpr* +s390_V128_calculate_carry_out_with_carry(IRExpr* a, IRExpr* b, IRExpr* c) +{ + IRTemp ta = newTemp(Ity_V128); + IRTemp sum = newTemp(Ity_V128); + IRTemp carry = newTemp(Ity_V128); + assign(ta, a); + assign(sum, binop(Iop_Add128x1, mkexpr(ta), b)); + assign(carry, + binop(Iop_AndV128, c, binop(Iop_64HLtoV128, mkU64(0), mkU64(1)))); - IRExpr* carry_is_not_zero = unop(Iop_1Uto64, - binop(Iop_CmpNE64, - unop(Iop_V128to64, mkexpr(carry_in)), - mkU64(0ULL) - ) - ); + return binop(Iop_OrV128, + s390_V128_CmpGT128x1(mkexpr(ta), mkexpr(sum), False, True), + binop(Iop_AndV128, mkexpr(carry), + s390_V128_CmpEQ(mkexpr(sum), mkV128(0xffff), 4))); +} + +/* Multiply lane-wise */ +static IRExpr* +s390_V128_mul(IRExpr* a, IRExpr* b, UChar es) +{ + vassert(es <= 4); + if (es <= 2) { + const IROp ops[] = {Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4}; + return binop(ops[es], a, b); + } + + IRTemp ta = newTemp(Ity_V128); + IRTemp tb = newTemp(Ity_V128); + IRTemp a_h = newTemp(Ity_V128); + IRTemp b_h = newTemp(Ity_V128); + IRTemp a_l = newTemp(Ity_V128); + IRTemp b_l = newTemp(Ity_V128); + assign(ta, a); + assign(tb, b); + assign(a_l, unop(Iop_V128to64, mkexpr(ta))); + assign(b_l, unop(Iop_V128to64, mkexpr(tb))); + assign(a_h, unop(Iop_V128HIto64, mkexpr(ta))); + assign(b_h, unop(Iop_V128HIto64, mkexpr(tb))); + + if (es == 3) { + return binop(Iop_64HLtoV128, binop(Iop_Mul64, mkexpr(a_h), mkexpr(b_h)), + binop(Iop_Mul64, mkexpr(a_l), mkexpr(b_l))); + } + + return binop( + Iop_Add128x1, + unop(Iop_ReinterpI128asV128, + binop(Iop_MullU64, mkexpr(a_l), mkexpr(b_l))), + binop(Iop_64HLtoV128, + binop(Iop_Add64, binop(Iop_Mul64, mkexpr(a_h), mkexpr(b_l)), + binop(Iop_Mul64, mkexpr(b_h), mkexpr(a_l))), + mkU64(0))); +} + +/* Widening multiply from high (even) or low (odd) */ +static IRExpr* +s390_V128_mul_widen(IRExpr* a, IRExpr* b, UChar es, Bool is_signed, Bool is_high) +{ + vassert(es <= 3); + if (es <= 2) { + const IROp sops[] = {Iop_MullEven8Sx16, Iop_MullEven16Sx8, + Iop_MullEven32Sx4}; + const IROp uops[] = {Iop_MullEven8Ux16, Iop_MullEven16Ux8, + Iop_MullEven32Ux4}; + if (is_high) { + a = binop(Iop_ShrV128, a, mkU8(8 << es)); + b = binop(Iop_ShrV128, b, mkU8(8 << es)); + } + return binop((is_signed ? sops : uops)[es], a, b); + } + IROp to64 = is_high ? Iop_V128HIto64 : Iop_V128to64; + return unop(Iop_ReinterpI128asV128, + binop(is_signed ? Iop_MullS64 : Iop_MullU64, unop(to64, a), + unop(to64, b))); +} - IRTemp sum_plus_carry = newTemp(Ity_V128); - assign(sum_plus_carry, binop(Iop_Add128x1, mkexpr(sum), mkexpr(carry_in))); +/* Multiply and optional add, high result */ +static IRExpr* +s390_V128_mula_high(IRExpr* a, IRExpr* b, IRExpr* c, UChar es, Bool is_signed) +{ + vassert(es <= 4); - IRExpr* overflow_after = binop(Iop_And64, - carry_is_not_zero, - s390_V128_isZero(mkexpr(sum_plus_carry)) - ); + IRTemp op1 = newTemp(Ity_V128); + IRTemp op2 = newTemp(Ity_V128); + IRTemp op3 = newTemp(Ity_V128); + assign(op1, a); + assign(op2, b); + assign(op3, c == NULL ? mkV128(0) : c); + + if (es <= 2) { + const IROp sops[] = {Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4}; + const IROp uops[] = {Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4}; + IRExpr* res = + binop((is_signed ? sops : uops)[es], mkexpr(op1), mkexpr(op2)); + + if (c != NULL) { + IRTemp low = newTemp(Ity_V128); + assign(low, s390_V128_add(s390_V128_mul(mkexpr(op1), mkexpr(op2), es), + mkexpr(op3), es)); + res = s390_V128_sub( + res, s390_V128_CmpGTU(mkexpr(op3), mkexpr(low), es), es); + if (is_signed) { + res = s390_V128_add(res, s390_V128_high_set(mkexpr(op3), es), es); + } + } + return res; + } + + if (es == 3) { + /* Calculate full (128-bit) results, then concatenate high halves */ + IRExpr* res0 = + s390_V128_mul_widen(mkexpr(op1), mkexpr(op2), es, is_signed, True); + IRExpr* res1 = + s390_V128_mul_widen(mkexpr(op1), mkexpr(op2), es, is_signed, False); + + if (c != NULL) { + /* Add the appropriately-extended 3rd operand */ + res0 = binop( + Iop_Add128x1, res0, + s390_V128_unpack(unop(Iop_V128HIto64, mkexpr(op3)), es, is_signed)); + res1 = binop( + Iop_Add128x1, res1, + s390_V128_unpack(unop(Iop_V128to64, mkexpr(op3)), es, is_signed)); + } + return binop(Iop_64HLtoV128, unop(Iop_V128HIto64, res0), + unop(Iop_V128HIto64, res1)); + } + + /* 128-bit input operands */ + IRTemp ah = newTemp(Ity_I64); + IRTemp al = newTemp(Ity_I64); + IRTemp bh = newTemp(Ity_I64); + IRTemp bl = newTemp(Ity_I64); + IRTemp low = newTemp(Ity_V128); + IRTemp m0 = newTemp(Ity_V128); + IRTemp mid = newTemp(Ity_V128); + IRExpr* t; - IRExpr* result = binop(Iop_Or64, mkexpr(overflow_before), overflow_after); - result = binop(Iop_64HLtoV128, mkU64(0Ull), result); - return result; + assign(ah, unop(Iop_V128HIto64, mkexpr(op1))); + assign(al, unop(Iop_V128to64, mkexpr(op1))); + assign(bh, unop(Iop_V128HIto64, mkexpr(op2))); + assign(bl, unop(Iop_V128to64, mkexpr(op2))); + // The following addition can overflow; remember `low' for carry + assign(low, binop(Iop_Add128x1, mkexpr(op3), + unop(Iop_ReinterpI128asV128, + binop(Iop_MullU64, mkexpr(al), mkexpr(bl))))); + t = binop(Iop_ShrV128, mkexpr(low), mkU8(64)); + // This addition can't overflow, but the next can, so keep `m0'... + assign(m0, binop(Iop_Add128x1, t, + unop(Iop_ReinterpI128asV128, + binop(Iop_MullU64, mkexpr(al), mkexpr(bh))))); + // ... and the sum `mid' + assign(mid, binop(Iop_Add128x1, mkexpr(m0), + unop(Iop_ReinterpI128asV128, + binop(Iop_MullU64, mkexpr(ah), mkexpr(bl))))); + t = binop(Iop_ShrV128, mkexpr(mid), mkU8(64)); + t = binop( + Iop_Add128x1, t, + unop(Iop_ReinterpI128asV128, binop(Iop_MullU64, mkexpr(ah), mkexpr(bh)))); + // Add the carries + t = binop(Iop_Add128x1, t, + s390_V128_CmpGT128x1(mkexpr(op3), mkexpr(low), False, True)); + t = binop(Iop_Add128x1, t, + binop(Iop_ShlV128, + s390_V128_CmpGT128x1(mkexpr(m0), mkexpr(mid), False, True), + mkU8(64))); + if (is_signed) { + t = binop(Iop_Sub128x1, t, + binop(Iop_AndV128, mkexpr(op1), + binop(Iop_SarV128, mkexpr(op2), mkU8(127)))); + t = binop(Iop_Sub128x1, t, + binop(Iop_AndV128, mkexpr(op2), + binop(Iop_SarV128, mkexpr(op1), mkU8(127)))); + t = binop(Iop_Add128x1, t, binop(Iop_SarV128, mkexpr(op3), mkU8(127))); + } + return t; } /* Performs "arg1 + arg2 + carry_out_bit(arg1 + arg2)". @@ -2346,32 +2434,6 @@ s390_vr_getVRindex(UChar v,UChar argNumber, UChar rxb) return v | (((rxb) << argNumber) & 0b00010000); } -static void -s390_vr_fill(UChar v1, IRExpr *o2) -{ - IRType o2type = typeOfIRExpr(irsb->tyenv, o2); - switch (o2type) { - case Ity_I8: - put_vr_qw(v1, unop(Iop_Dup8x16, o2)); - break; - case Ity_I16: - put_vr_qw(v1, unop(Iop_Dup16x8, o2)); - break; - case Ity_I32: - put_vr_qw(v1, unop(Iop_Dup32x4, o2)); - break; - case Ity_I64: { - IRTemp val = newTemp(Ity_I64); - assign(val, o2); - put_vr_qw(v1, binop(Iop_64HLtoV128, mkexpr(val), mkexpr(val))); - break; - } - default: - ppIRType(o2type); - vpanic("s390_vr_fill: invalid IRType"); - } -} - /* Returns Ity_I32 number of bytes till block boundary specified by m */ static IRExpr* s390_getCountToBlockBoundary(IRTemp op2addr, UChar m) @@ -2497,20 +2559,6 @@ s390_vr_storeWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex, Bool rightmost) put_counter_dw0(mkU64(0)); } -/* Bitwise vCond ? v1 : v2 - All args are V128. - */ -static IRExpr* -s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2) -{ - IRTemp vc = newTemp(Ity_V128); - assign(vc, vCond); - /* result = (v1 & vCond) | (v2 & ~vCond) */ - return binop(Iop_OrV128, - binop(Iop_AndV128, v1, mkexpr(vc)), - binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc)))); -} - /*------------------------------------------------------------*/ /*--- Rounding modes ---*/ /*------------------------------------------------------------*/ @@ -2518,14 +2566,15 @@ s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2) /* Extract the bfp rounding mode from the guest FPC reg and encode it as an IRRoundingMode: - rounding mode | s390 | IR - ------------------------- - to nearest | 00 | 00 - to zero | 01 | 11 - to +infinity | 10 | 10 - to -infinity | 11 | 01 + rounding mode | s390 | IR + ---------------------------- + to nearest | 000 | 000 + to zero | 001 | 011 + to +infinity | 010 | 010 + to -infinity | 011 | 001 + prepare shorter | 111 | 101 - So: IR = (4 - s390) & 3 + So: IR = (4 - s390) & (3 | s390) */ static IRExpr * get_bfp_rounding_mode_from_fpc(void) @@ -2538,29 +2587,16 @@ get_bfp_rounding_mode_from_fpc(void) extract the least significant 3 bits. */ assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7))); - /* fixs390: - - - if (! s390_host_has_fpext && rounding_mode > 3) { - emulation warning @ runtime and - set fpc to round nearest - } - */ - - /* For now silently adjust an unsupported rounding mode to "nearest" */ - IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)), - mkexpr(fpc_bits), - mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN)); + IRExpr *rm_s390 = mkexpr(fpc_bits); - // rm_IR = (4 - rm_s390) & 3; - return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3)); + // rm_IR = (4 - rm_s390) & (3 | rm_s390); + return binop(Iop_And32, + binop(Iop_Sub32, mkU32(4), rm_s390), + binop(Iop_Or32, mkU32(3), rm_s390)); } /* Encode the s390 rounding mode as it appears in the m3 field of certain - instructions to VEX's IRRoundingMode. Rounding modes that cannot be - represented in VEX are converted to Irrm_NEAREST. The rationale is, that - Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard - considers the default rounding mode (4.3.3). */ + instructions to VEX's IRRoundingMode. */ static IRTemp encode_bfp_rounding_mode(UChar mode) { @@ -2728,971 +2764,274 @@ convert_vex_dfpcc_to_s390(IRTemp vex_cc) /*--- Build IR for formats ---*/ /*------------------------------------------------------------*/ static void -s390_format_I(const HChar *(*irgen)(UChar i), - UChar i) -{ - const HChar *mnm = irgen(i); +s390_format_RIS(void (*irgen)(UChar r1, UChar m3, UChar i2, IRTemp op4addr), + ULong ovl) +{ + UChar r1 = (ovl >> 52) & 0xf; + UChar m3 = (ovl >> 48) & 0xf; + UChar b4 = (ovl >> 44) & 0xf; + UShort d4 = (ovl >> 32) & 0xfff; + UChar i2 = (ovl >> 24) & 0xff; + IRTemp op4addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(i)); + assign(op4addr, + binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : mkU64(0))); + + irgen(r1, m3, i2, op4addr); } static void -s390_format_IE(const HChar *(*irgen)(UChar i1, UChar i2), - UChar i1, UChar i2) -{ - const HChar *mnm = irgen(i1, i2); +s390_format_RRS(void (*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr), + ULong ovl) +{ + UChar r1 = (ovl >> 52) & 0xf; + UChar r2 = (ovl >> 48) & 0xf; + UChar b4 = (ovl >> 44) & 0xf; + UShort d4 = (ovl >> 32) & 0xfff; + UChar m3 = (ovl >> 28) & 0xf; + IRTemp op4addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(i1), UINT(i2)); + assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : + mkU64(0))); + + irgen(r1, r2, m3, op4addr); } static void -s390_format_E(const HChar *(*irgen)(void)) +s390_format_RS0(void (*irgen)(UChar r1, IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(); + UChar r1 = RS_r1(ovl); + UChar b2 = RS_b2(ovl); + UShort d2 = RS_d2(ovl); + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm)); + assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); + + irgen(r1, op2addr); } static void -s390_format_MII_UPP(const HChar *(*irgen)(UChar m1, UShort i2, UInt i3), - UChar m1, UShort i2, UInt i3) +s390_format_RS(void (*irgen)(UChar r1, UChar r3, IRTemp op2addr), ULong ovl) { - const HChar *mnm; + UChar r1 = RS_r1(ovl); + UChar r3 = RS_r3(ovl); + UChar b2 = RS_b2(ovl); + UShort d2 = RS_d2(ovl); + IRTemp op2addr = newTemp(Ity_I64); - mnm = irgen(m1, i2, i3); + assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(m1), PCREL((Int)((Short)(i2 << 4) >> 4)), - PCREL((Int)(i3 << 8) >> 8)); + irgen(r1, r3, op2addr); } static void -s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2), - UChar r1, UShort i2) +s390_format_RSY(void (*irgen)(UChar r1, UChar r3, IRTemp op2addr), ULong ovl) { - irgen(r1, i2); -} + UChar r1 = RSY_r1(ovl); + UChar r3 = RSY_r3(ovl); + UChar b2 = RSY_b2(ovl); + UShort dl2 = RSY_dl2(ovl); + UChar dh2 = RSY_dh2(ovl); + IRTemp op2addr = newTemp(Ity_I64); + IRTemp d2 = newTemp(Ity_I64); -static void -s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2), - UChar r1, UShort i2) -{ - const HChar *mnm = irgen(r1, i2); + assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); + assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UINT(i2)); + irgen(r1, r3, op2addr); } static void -s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2), - UChar r1, UShort i2) +s390_format_RSYcond(void (*irgen)(UChar r1, IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(r1, i2); + UChar r1 = RSY_r1(ovl); + UChar m3 = RSY_m3(ovl); + UChar b2 = RSY_b2(ovl); + UShort dl2 = RSY_dl2(ovl); + UChar dh2 = RSY_dh2(ovl); + IRTemp op2addr = newTemp(Ity_I64); + IRTemp d2 = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), INT((Int)(Short)i2)); -} + next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); -static void -s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2), - UChar r1, UShort i2) -{ - const HChar *mnm = irgen(r1, i2); + assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); + assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), PCREL((Int)(Short)i2)); + irgen(r1, op2addr); + + vassert(dis_res->whatNext == Dis_Continue); } static void -s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), - UChar r1, UChar r3, UShort i2) +s390_format_RX(void (*irgen)(UChar r1, IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(r1, r3, i2); + UChar r1 = (ovl >> 20) & 0xf; + UChar x2 = (ovl >> 16) & 0xf; + UChar b2 = (ovl >> 12) & 0xf; + UShort d2 = ovl & 0xfff; + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), PCREL((Int)(Short)i2)); + assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), + b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : + mkU64(0))); + + irgen(r1, op2addr); } static void -s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), - UChar r1, UChar r3, UShort i2) +s390_format_RXE0(void (*irgen)(UChar r1, IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(r1, r3, i2); + UChar r1 = RXE_r1(ovl); + UChar x2 = RXE_x2(ovl); + UChar b2 = RXE_b2(ovl); + UShort d2 = RXE_d2(ovl); + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), INT((Int)(Short)i2)); + assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), + b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : + mkU64(0))); + + irgen(r1, op2addr); } static void -s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3, - UChar i4, UChar i5), - UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) +s390_format_RXE(void (*irgen)(UChar r1, IRTemp op2addr, UChar m3), ULong ovl) { - const HChar *mnm = irgen(r1, r2, i3, i4, i5); + UChar r1 = RXE_r1(ovl); + UChar x2 = RXE_x2(ovl); + UChar b2 = RXE_b2(ovl); + UShort d2 = RXE_d2(ovl); + UChar m3 = RXE_m3(ovl); + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, rotate_disasm), GPR(r1), GPR(r2), MASK(i3), MASK(i4), MASK(i5)); + assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), + b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : + mkU64(0))); + + irgen(r1, op2addr, m3); } static void -s390_format_R0UU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3), - UChar r1, UShort i2, UChar m3) +s390_format_RXF(void (*irgen)(UChar, IRTemp, UChar), ULong ovl) { - const HChar *mnm = irgen(r1, i2, m3); + UChar r3 = (ovl >> 52) & 0xf; + UChar x2 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar r1 = (ovl >> 28) & 0xf; + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), INT(i2), MASK(m3)); + assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), + b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : + mkU64(0))); + + irgen(r3, op2addr, r1); } static void -s390_format_R0IU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3), - UChar r1, UShort i2, UChar m3) +s390_format_RXY(void (*irgen)(UChar r1, IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(r1, i2, m3); + UChar r1 = (ovl >> 52) & 0xf; + UChar x2 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort dl2 = (ovl >> 32) & 0xfff; + UChar dh2 = (ovl >> 24) & 0xff; + IRTemp op2addr = newTemp(Ity_I64); + IRTemp d2 = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), INT((Int)(Short)i2), MASK(m3)); + assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); + assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), + b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : + mkU64(0))); + + irgen(r1, op2addr); } static void -s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4, - UChar m3), - UChar r1, UChar r2, UShort i4, UChar m3) +s390_format_RXYc( + void (*irgen)(UChar r1, UChar x2, UChar b2, UInt dx), ULong ovl) { - const HChar *mnm = irgen(r1, r2, i4, m3); + UChar r1 = (ovl >> 52) & 0xf; + UChar x2 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort dxl2 = (ovl >> 32) & 0xfff; + UChar dxh2 = (ovl >> 24) & 0xff; + UInt dx = (((UInt)(Int)(Char)dxh2) << 12) | dxl2; - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), GPR(r2), MASK(m3), PCREL((Int)(Short)i4)); + irgen(r1, x2, b2, dx); } static void -s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4, - UChar i2), - UChar r1, UChar m3, UShort i4, UChar i2) +s390_format_S(void (*irgen)(IRTemp op2addr), ULong ovl) { - const HChar *mnm = irgen(r1, m3, i4, i2); + UChar b2 = S_b2(ovl); + UShort d2 = S_d2(ovl); + IRTemp op2addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), UINT(i2), MASK(m3), PCREL((Int)(Short)i4)); + assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); + + irgen(op2addr); } static void -s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4, - UChar i2), - UChar r1, UChar m3, UShort i4, UChar i2) +s390_format_SI(void (*irgen)(UChar i2, IRTemp op1addr), ULong ovl) { - const HChar *mnm = irgen(r1, m3, i4, i2); + UChar i2 = (ovl >> 16) & 0xff; + UChar b1 = (ovl >> 12) & 0xf; + UShort d1 = ovl & 0xfff; + IRTemp op1addr = newTemp(Ity_I64); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), INT((Int)(Char)i2), MASK(m3), PCREL((Int)(Short)i4)); + assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : + mkU64(0))); + + irgen(i2, op1addr); } static void -s390_format_RIE_RUPIX(const HChar *(*irgen)(UChar r1, UChar m3, UShort i2), - UChar r1, UChar m3, UShort i2) +s390_format_SIY(void (*irgen)(UChar i2, IRTemp op1addr), ULong ovl) { - const HChar *mnm = irgen(r1, m3, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cls_disasm), GPR(r1), INT((Int)(Short)i2), MASK(m3)); -} - -static void -s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2), - UChar r1, UInt i2) -{ - irgen(r1, i2); -} - -static void -s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2), - UChar r1, UInt i2) -{ - const HChar *mnm = irgen(r1, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UINT(i2)); -} - -static void -s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2), - UChar r1, UInt i2) -{ - const HChar *mnm = irgen(r1, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), INT(i2)); -} - -static void -s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2), - UChar r1, UInt i2) -{ - const HChar *mnm = irgen(r1, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), PCREL(i2)); -} - -static void -s390_format_RIL_UP(const HChar *(*irgen)(void), - UChar r1, UInt i2) -{ - const HChar *mnm = irgen(); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(r1), PCREL(i2)); -} - -static void -s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2, - IRTemp op4addr), - UChar r1, UChar m3, UChar b4, UShort d4, UChar i2) -{ - const HChar *mnm; - IRTemp op4addr = newTemp(Ity_I64); - - assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : - mkU64(0))); - - mnm = irgen(r1, m3, i2, op4addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), INT((Int)(Char)i2), MASK(m3), UDXB(d4, 0, b4)); -} - -static void -s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2, - IRTemp op4addr), - UChar r1, UChar m3, UChar b4, UShort d4, UChar i2) -{ - const HChar *mnm; - IRTemp op4addr = newTemp(Ity_I64); - - assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : - mkU64(0))); - - mnm = irgen(r1, m3, i2, op4addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), UINT(i2), MASK(m3), UDXB(d4, 0, b4)); -} - -static void -s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - irgen(r1, r2); -} - -static void -s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r2)); -} - -static void -s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r2)); -} - -static void -s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - irgen(r1, r2); -} - -static void -s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r2)); -} - -static void -s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r2)); -} - -static void -s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), FPR(r2)); -} - -static void -s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2), - UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), GPR(r2)); -} - -static void -s390_format_RRE_R0(const HChar *(*irgen)(UChar r1), - UChar r1) -{ - const HChar *mnm = irgen(r1); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1)); -} - -static void -s390_format_RRE_F0(const HChar *(*irgen)(UChar r1), - UChar r1) -{ - const HChar *mnm = irgen(r1); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1)); -} - -static void -s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2), - UChar m3, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, mask0_disasm), GPR(r1), GPR(r2), MASK(m3)); -} - -static void -s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar), - UChar r1, UChar r3, UChar r2) -{ - const HChar *mnm = irgen(r1, r3, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), FPR(r2)); -} - -static void -s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar), - UChar r3, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), GPR(r2)); -} - -static void -s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, - UChar r2), - UChar m3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); -} - -static void -s390_format_RRF_UUFF2(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, - UChar r2), - UChar m3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, fp_convt_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); -} - -static void -s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2), - UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r2), UINT(m4)); -} - -static void -s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, - UChar r2), - UChar m3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); -} - -static void -s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, - UChar r2), - UChar m3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); -} - - -static void -s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2), - UChar m3, UChar r1, UChar r2, HChar *(*handler)(const s390_opnd *, HChar *)) -{ - const HChar *mnm = irgen(m3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, handler), GPR(r1), GPR(r2), MASK(m3)); -} - -static void -s390_format_RRFa_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2), - UChar m3, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(m3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { - if (m3 != 0) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r2), UINT(m3)); - else - S390_DISASM(MNM(mnm), GPR(r1), GPR(r2)); - } -} - -static void -s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar), - UChar r3, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), FPR(r2)); -} - -static void -s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar), - UChar r3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), GPR(r2), UINT(m4)); -} - -static void -s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar), - UChar r3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), FPR(r2), UINT(m4)); -} - -static void -s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar), - UChar r3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); -} - -static void -s390_format_RRF_RURR(const HChar *(*irgen)(UChar, UChar, UChar, UChar), - UChar r3, UChar m4, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, m4, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cls_disasm), GPR(r1), GPR(r2), GPR(r3), MASK(m4)); -} - -static void -s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2), - UChar r3, UChar r1, UChar r2) -{ - const HChar *mnm = irgen(r3, r1, r2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { - if (irgen == s390_irgen_KMA || irgen == s390_irgen_KMCTR) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), GPR(r2)); - else - S390_DISASM(MNM(mnm), GPR(r1), GPR(r2), GPR(r3)); - } -} - -static void -s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3, - IRTemp op4addr), - UChar r1, UChar r2, UChar b4, UShort d4, UChar m3) -{ - const HChar *mnm; - IRTemp op4addr = newTemp(Ity_I64); - - assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : - mkU64(0))); - - mnm = irgen(r1, r2, m3, op4addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), GPR(r2), MASK(m3), UDXB(d4, 0, b4)); -} - -static void -s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UDXB(d2, 0, b2)); -} - -static void -s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), - UChar r1, UChar r3, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), UDXB(d2, 0, b2)); -} - -static void -s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), - UChar r1, UChar r3, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UINT(r3), UDXB(d2, 0, b2)); -} - -static void -s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp), - UChar r1, UChar r3, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), AR(r1), AR(r3), UDXB(d2, 0, b2)); -} - -static void -s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), - UChar r1, UChar r3, UShort i2) -{ - const HChar *mnm = irgen(r1, r3, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), PCREL((Int)(Short)i2)); -} - -static void -s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), - UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); -} - -static void -s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp), - UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), AR(r1), AR(r3), SDXB(dh2, dl2, 0, b2)); -} - -static void -s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar m3, IRTemp op2addr), - UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, m3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UINT(m3), SDXB(dh2, dl2, 0, b2)); -} - -static void -s390_format_RSY_R0RD(const HChar *(*irgen)(UChar r1, UChar m3, IRTemp op2addr), - UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(r1, m3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cabt_disasm), GPR(r1), MASK(m3), SDXB(dh2, dl2, 0, b2)); -} - -static void -s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) -{ - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - const HChar *mnm = irgen(r1, op2addr); - - vassert(dis_res->whatNext == Dis_Continue); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, cls_disasm), GPR(r1), SDXB(dh2, dl2, 0, b2), MASK(m3)); -} - -static void -s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2, - IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort d2) -{ - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - irgen(r1, x2, b2, d2, op2addr); -} - -static void -s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UDXB(d2, x2, b2)); -} - -static void -s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), UDXB(d2, x2, b2)); -} - -static void -s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), UDXB(d2, x2, b2)); -} - -static void -s390_format_RXE_RRRDR(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar m3), - UChar r1, UChar x2, UChar b2, UShort d2, UChar m3) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UDXB(d2, x2, b2), UINT(m3)); -} - -static void -s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar), - UChar r3, UChar x2, UChar b2, UShort d2, UChar r1) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r3, op2addr, r1); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), FPR(r3), UDXB(d2, x2, b2)); -} - -static void -s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { - if (irgen == s390_irgen_BIC) - S390_DISASM(XMNM(mnm, bic_disasm), MASK(r1), SDXB(dh2, dl2, x2, b2)); - else - S390_DISASM(MNM(mnm), GPR(r1), SDXB(dh2, dl2, x2, b2)); - } -} - -static void -s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), - UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(r1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), FPR(r1), SDXB(dh2, dl2, x2, b2)); -} - -static void -s390_format_RXY_URRD(const HChar *(*irgen)(void), - UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - IRTemp d2 = newTemp(Ity_I64); - - assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - mnm = irgen(); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(r1), SDXB(dh2, dl2, x2, b2)); -} - -static void -s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr), - UChar b2, UShort d2) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - mnm = irgen(op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d2, 0, b2)); -} - -static void -s390_format_S_RD_raw(const HChar *(*irgen)(UChar b2, UShort d2), - UChar b2, UShort d2) -{ - const HChar *mnm; - - mnm = irgen(b2, d2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d2, 0, b2)); -} - -static void -s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), - UChar i2, UChar b1, UShort d1) -{ - const HChar *mnm; - IRTemp op1addr = newTemp(Ity_I64); - - assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : - mkU64(0))); - - mnm = irgen(i2, op1addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d1, 0, b1), UINT(i2)); -} - -static void -s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), - UChar i2, UChar b1, UShort dl1, UChar dh1) -{ - const HChar *mnm; - IRTemp op1addr = newTemp(Ity_I64); - IRTemp d1 = newTemp(Ity_I64); - - assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1))); - assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) : - mkU64(0))); - - mnm = irgen(i2, op1addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), SDXB(dh1, dl1, 0, b1), UINT(i2)); -} - -static void -s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), - UChar i2, UChar b1, UShort dl1, UChar dh1) -{ - const HChar *mnm; + UChar i2 = (ovl >> 48) & 0xff; + UChar b1 = (ovl >> 44) & 0xf; + UShort dl1 = (ovl >> 32) & 0xfff; + UChar dh1 = (ovl >> 24) & 0xff; IRTemp op1addr = newTemp(Ity_I64); - IRTemp d1 = newTemp(Ity_I64); + IRTemp d1 = newTemp(Ity_I64); assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1))); assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) : mkU64(0))); - mnm = irgen(i2, op1addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), SDXB(dh1, dl1, 0, b1), INT((Int)(Char)i2)); + irgen(i2, op1addr); } static void -s390_format_SMI_U0RDP(const HChar *(*irgen)(UChar m1, UShort i2, IRTemp op3addr), - UChar m1, UShort i2, UChar b3, UShort d3) +s390_format_SMI(void (*irgen)(UChar m1, UShort i2, IRTemp op3addr), ULong ovl) { - const HChar *mnm; + UChar m1 = (ovl >> 52) & 0xf; + UChar b3 = (ovl >> 44) & 0xf; + UShort d3 = (ovl >> 32) & 0xfff; + UShort i2 = (ovl >> 16) & 0xffff; IRTemp op3addr = newTemp(Ity_I64); assign(op3addr, binop(Iop_Add64, mkU64(d3), b3 != 0 ? get_gpr_dw0(b3) : mkU64(0))); - mnm = irgen(m1, i2, op3addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UINT(m1), PCREL((Int)(Short)i2), UDXB(d3, 0, b3)); + irgen(m1, i2, op3addr); } static void -s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp), - UChar l, UChar b1, UShort d1, UChar b2, UShort d2) +s390_format_SSa(void (*irgen)(UChar, IRTemp, IRTemp), ULong ovl) { - const HChar *mnm; + UChar l = SSa_l(ovl); + UChar b1 = SSa_b1(ovl); + UShort d1 = SSa_d1(ovl); + UChar b2 = SSa_b2(ovl); + UShort d2 = SSa_d2(ovl); IRTemp op1addr = newTemp(Ity_I64); IRTemp op2addr = newTemp(Ity_I64); @@ -3701,17 +3040,16 @@ s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp), assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : mkU64(0))); - mnm = irgen(l, op1addr, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDLB(d1, l, b1), UDXB(d2, 0, b2)); + irgen(l, op1addr, op2addr); } static void -s390_format_SSE_RDRD(const HChar *(*irgen)(IRTemp, IRTemp), - UChar b1, UShort d1, UChar b2, UShort d2) +s390_format_SSE(void (*irgen)(IRTemp, IRTemp), ULong ovl) { - const HChar *mnm; + UChar b1 = SSa_b1(ovl); + UShort d1 = SSa_d1(ovl); + UChar b2 = SSa_b2(ovl); + UShort d2 = SSa_d2(ovl); IRTemp op1addr = newTemp(Ity_I64); IRTemp op2addr = newTemp(Ity_I64); @@ -3720,74 +3058,32 @@ s390_format_SSE_RDRD(const HChar *(*irgen)(IRTemp, IRTemp), assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : mkU64(0))); - mnm = irgen(op1addr, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d1, 0, b1), UDXB(d2, 0, b2)); -} - -static void -s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr), - UChar b1, UShort d1, UShort i2) -{ - const HChar *mnm; - IRTemp op1addr = newTemp(Ity_I64); - - assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : - mkU64(0))); - - mnm = irgen(i2, op1addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d1, 0, b1), INT((Int)(Short)i2)); + irgen(op1addr, op2addr); } static void -s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr), - UChar b1, UShort d1, UShort i2) +s390_format_SIL(void (*irgen)(UShort i2, IRTemp op1addr), ULong ovl) { - const HChar *mnm; + UChar b1 = (ovl >> 44) & 0xf; + UShort d1 = (ovl >> 32) & 0xfff; + UShort i2 = (ovl >> 16) & 0xffff; IRTemp op1addr = newTemp(Ity_I64); assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : mkU64(0))); - mnm = irgen(i2, op1addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), UDXB(d1, 0, b1), UINT(i2)); -} - -static void -s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr), - UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - if (! s390_host_has_vx) { - emulation_failure(EmFail_S390X_vx); - return; - } - - assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), - b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : - mkU64(0))); - - v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(m3)); + irgen(i2, op1addr); } - static void -s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3), - UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb, - HChar *(*handler)(const s390_opnd *, HChar *)) -{ - const HChar *mnm; +s390_format_VRX(void (*irgen)(UChar v1, IRTemp op2addr, UChar m3), ULong ovl) +{ + UChar v1 = (ovl >> 52) & 0xf; + UChar x2 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar m3 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -3800,22 +3096,16 @@ s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3), mkU64(0))); v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, op2addr, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { - if (handler) - S390_DISASM(XMNM(mnm, handler), VR(v1), UDXB(d2, x2, b2), MASK(m3)); - else - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, x2, b2), UINT(m3)); - } + irgen(v1, op2addr, m3); } static void -s390_format_VRR_VV(const HChar *(*irgen)(UChar v1, UChar v2), - UChar v1, UChar v2, UChar rxb) +s390_format_VRRa0(void (*irgen)(UChar v1, UChar v2), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3824,18 +3114,17 @@ s390_format_VRR_VV(const HChar *(*irgen)(UChar v1, UChar v2), v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2)); + irgen(v1, v2); } static void -s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3), - UChar v1, UChar v2, UChar v3, UChar rxb) +s390_format_VRRc0(void (*irgen)(UChar v1, UChar v2, UChar v3), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3845,18 +3134,18 @@ s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3), v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3)); + irgen(v1, v2, v3); } - static void -s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4), - UChar v1, UChar v2, UChar v3, UChar m4, UChar rxb) +s390_format_VRRc1(void (*irgen)(UChar v1, UChar v2, UChar v3, UChar m4), + ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar m4 = VRRc_m4(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3866,23 +3155,19 @@ s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { - if (irgen == s390_irgen_VPDI) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4)); - else - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - } + irgen(v1, v2, v3, m4); } - static void -s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5), - UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb, - HChar *(*handler)(const s390_opnd *, HChar *)) +s390_format_VRRb( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar m4 = (ovl >> 28) & 0xf; + UChar m5 = (ovl >> 36) & 0xf; + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3892,18 +3177,18 @@ s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, m4, m5); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5)); + irgen(v1, v2, v3, m4, m5); } - static void -s390_format_VRR_VVVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v4), - UChar v1, UChar v2, UChar v3, UChar v4, UChar rxb) +s390_format_VRRe0(void (*irgen)(UChar v1, UChar v2, UChar v3, UChar v4), + ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar v4 = VRR_v4(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3914,18 +3199,16 @@ s390_format_VRR_VVVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); v4 = s390_vr_getVRindex(v4, 4, rxb); - mnm = irgen(v1, v2, v3, v4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), VR(v4)); + irgen(v1, v2, v3, v4); } - static void -s390_format_VRR_VRR(const HChar *(*irgen)(UChar v1, UChar r2, UChar r3), - UChar v1, UChar r2, UChar r3, UChar rxb) +s390_format_VRRf(void (*irgen)(UChar v1, UChar r2, UChar r3), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar r2 = VRR_r2(ovl); + UChar r3 = VRR_r3(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3933,18 +3216,17 @@ s390_format_VRR_VRR(const HChar *(*irgen)(UChar v1, UChar r2, UChar r3), } v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, r2, r3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), GPR(r2), GPR(r3)); + irgen(v1, r2, r3); } static void -s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3), - UChar v1, UChar v2, UChar m3, UChar rxb) +s390_format_VRRa1(void (*irgen)(UChar v1, UChar v2, UChar m3), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar m3 = VRRa_m3(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3953,39 +3235,16 @@ s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3), v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), MASK(m3)); -} - - -static void -s390_format_VRI_V0U(const HChar *(*irgen)(UChar v1, UShort i2), - UChar v1, UShort i2, UChar rxb, - HChar *(*handler)(const s390_opnd *, HChar *)) -{ - const HChar *mnm; - - if (! s390_host_has_vx) { - emulation_failure(EmFail_S390X_vx); - return; - } - - v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, i2); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, handler), VR(v1), UINT(i2)); + irgen(v1, v2, m3); } static void -s390_format_VRI_V0UUU(const HChar *(*irgen)(UChar v1, UChar i2, UChar i3, - UChar m4), - UChar v1, UChar i2, UChar i3, UChar m4, UChar rxb) +s390_format_VRIa0(void (*irgen)(UChar v1, UShort i2), ULong ovl) { - const HChar *mnm; + UChar v1 = VRIa_v1(ovl); + UShort i2 = VRIa_i2(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -3993,18 +3252,19 @@ s390_format_VRI_V0UUU(const HChar *(*irgen)(UChar v1, UChar i2, UChar i3, } v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, i2, i3, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), UINT(i2), UINT(i3), MASK(m4)); + irgen(v1, i2); } static void -s390_format_VRI_V0IU(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), - UChar v1, UShort i2, UChar m3, UChar rxb) +s390_format_VRIb(void (*irgen)(UChar v1, UChar i2, UChar i3, UChar m4), + ULong ovl) { - const HChar *mnm; + UChar v1 = (ovl >> 52) & 0xf; + UShort i2 = (ovl >> 40) & 0xff; + UChar i3 = (ovl >> 32) & 0xff; + UChar m4 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4012,18 +3272,17 @@ s390_format_VRI_V0IU(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), } v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, i2, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), INT((Short)i2), MASK(m3)); + irgen(v1, i2, i3, m4); } static void -s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), - UChar v1, UShort i2, UChar m3, UChar rxb) +s390_format_VRIa(void (*irgen)(UChar v1, UShort i2, UChar m3), ULong ovl) { - const HChar *mnm; + UChar v1 = VRIa_v1(ovl); + UShort i2 = VRIa_i2(ovl); + UChar m3 = VRIa_m3(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4031,18 +3290,19 @@ s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), } v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, i2, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), INT((Short)i2), UINT(m3)); + irgen(v1, i2, m3); } static void -s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar m4), - UChar v1, UChar v3, UShort i2, UChar m4, UChar rxb) +s390_format_VRIc(void (*irgen)(UChar v1, UChar v3, UShort i2, UChar m4), + ULong ovl) { - const HChar *mnm; + UChar v1 = (ovl >> 52) & 0xf; + UChar v3 = (ovl >> 48) & 0xf; + UShort i2 = (ovl >> 32) & 0xffff; + UChar m4 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4051,19 +3311,19 @@ s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar v1 = s390_vr_getVRindex(v1, 1, rxb); v3 = s390_vr_getVRindex(v3, 2, rxb); - mnm = irgen(v1, v3, i2, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v3), UINT(i2), MASK(m4)); + irgen(v1, v3, i2, m4); } static void -s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3, - UChar m4, UChar m5), - UChar v1, UChar v2, UShort i3, UChar m4, UChar m5, - UChar rxb) +s390_format_VRIe( + void (*irgen)(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = (ovl >> 52) & 0xf; + UChar v2 = (ovl >> 48) & 0xf; + UShort i3 = (ovl >> 36) & 0xfff; + UChar m4 = (ovl >> 28) & 0xf; + UChar m5 = (ovl >> 32) & 0xf; + UChar rxb = V_rxb(ovl); if (!s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4072,18 +3332,19 @@ s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2, i3, m4, m5); - - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(XMNM(mnm, vfmix_like_disasm), VR(v1), VR(v2), UINT(i3), MASK(m4), MASK(m5)); + irgen(v1, v2, i3, m4, m5); } static void -s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3, - UChar m4), UChar r1, UChar b2, UShort d2, UChar v3, - UChar m4, UChar rxb) -{ - const HChar *mnm; +s390_format_VRSc(void (*irgen)(UChar r1, IRTemp op2addr, UChar v3, UChar m4), + ULong ovl) +{ + UChar r1 = (ovl >> 52) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar v3 = (ovl >> 48) & 0xf; + UChar m4 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4095,17 +3356,17 @@ s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3, mkU64(0))); v3 = s390_vr_getVRindex(v3, 2, rxb); - mnm = irgen(r1, op2addr, v3, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), GPR(r1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); + irgen(r1, op2addr, v3, m4); } static void -s390_format_VRS_RRDV(const HChar *(*irgen)(UChar v1, UChar r3, IRTemp op2addr), - UChar v1, UChar r3, UChar b2, UShort d2, UChar rxb) +s390_format_VRSd(void (*irgen)(UChar v1, UChar r3, IRTemp op2addr), ULong ovl) { - const HChar *mnm; + UChar r3 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar v1 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4117,43 +3378,20 @@ s390_format_VRS_RRDV(const HChar *(*irgen)(UChar v1, UChar r3, IRTemp op2addr), mkU64(0))); v1 = s390_vr_getVRindex(v1, 4, rxb); - mnm = irgen(v1, r3, op2addr); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), GPR(r3), UDXB(d2, 0, b2)); -} - - -static void -s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3, - UChar m4), UChar v1, UChar b2, UShort d2, UChar v3, - UChar m4, UChar rxb) -{ - const HChar *mnm; - IRTemp op2addr = newTemp(Ity_I64); - - if (! s390_host_has_vx) { - emulation_failure(EmFail_S390X_vx); - return; - } - - assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : - mkU64(0))); - - v1 = s390_vr_getVRindex(v1, 1, rxb); - v3 = s390_vr_getVRindex(v3, 2, rxb); - mnm = irgen(v1, op2addr, v3, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); + irgen(v1, r3, op2addr); } static void -s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3), - UChar v1, UChar b2, UShort d2, UChar v3, UChar m4, UChar rxb) -{ - const HChar *mnm; +s390_format_VRSa(void (*irgen)(UChar v1, IRTemp op2addr, UChar v3, UChar m4), + ULong ovl) +{ + UChar v1 = (ovl >> 52) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar v3 = (ovl >> 48) & 0xf; + UChar m4 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4166,19 +3404,20 @@ s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3), v1 = s390_vr_getVRindex(v1, 1, rxb); v3 = s390_vr_getVRindex(v3, 2, rxb); - mnm = irgen(v1, op2addr, v3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, mask0_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); + irgen(v1, op2addr, v3, m4); } static void -s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3, - UChar m4), - UChar v1, UChar b2, UShort d2, UChar r3, UChar m4, UChar rxb) -{ - const HChar *mnm; +s390_format_VRSbm(void (*irgen)(UChar v1, IRTemp op2addr, UChar r3, UChar m4), + ULong ovl) +{ + UChar v1 = VRSb_v1(ovl); + UChar b2 = VRSb_b2(ovl); + UShort d2 = VRSb_d2(ovl); + UChar r3 = VRSb_r3(ovl); + UChar m4 = VRSb_m4(ovl); + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4190,18 +3429,18 @@ s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3, mkU64(0))); v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, op2addr, r3, m4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), GPR(r3), UDXB(d2, 0, b2), MASK(m4)); + irgen(v1, op2addr, r3, m4); } static void -s390_format_VRS_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3), - UChar v1, UChar b2, UShort d2, UChar r3, UChar rxb) +s390_format_VRSb(void (*irgen)(UChar v1, IRTemp op2addr, UChar r3), ULong ovl) { - const HChar *mnm; + UChar v1 = VRSb_v1(ovl); + UChar b2 = VRSb_b2(ovl); + UShort d2 = VRSb_d2(ovl); + UChar r3 = VRSb_r3(ovl); + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4213,19 +3452,20 @@ s390_format_VRS_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3), mkU64(0))); v1 = s390_vr_getVRindex(v1, 1, rxb); - mnm = irgen(v1, op2addr, r3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), GPR(r3), UDXB(d2, 0, b2)); + irgen(v1, op2addr, r3); } static void -s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3), - UChar v1, UChar v2, UChar b2, UShort d2, UChar m3, UChar rxb, - IRType type) -{ - const HChar *mnm; +s390_format_VRV(void (*irgen)(UChar v1, IRTemp op2addr, UChar m3), ULong ovl, + IRType type) +{ + UChar v1 = (ovl >> 52) & 0xf; + UChar v2 = (ovl >> 48) & 0xf; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar m3 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (! s390_host_has_vx) { @@ -4239,29 +3479,31 @@ s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3) vassert(type == Ity_I32 || type == Ity_I64); IRExpr *x2; if(type == Ity_I32) { + s390_insn_assert(m3 < 4); x2 = unop(Iop_32Uto64, get_vr(v2, type, m3)); } else { + s390_insn_assert(m3 < 2); x2 = get_vr(v2, type, m3); } assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2)); - mnm = irgen(v1, op2addr, m3); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UDVB(d2, v2, b2), UINT(m3)); + irgen(v1, op2addr, m3); } - static void -s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar v4, UChar m5, UChar m6), - UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, - UChar m6, UChar rxb, - HChar *(*handler)(const s390_opnd *, HChar *)) -{ - const HChar *mnm; +s390_format_VRRd( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6), + ULong ovl) +{ + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar v4 = VRR_v4(ovl); + UChar m5 = VRRd_m5(ovl); + UChar m6 = VRRd_m6(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4272,19 +3514,21 @@ s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); v4 = s390_vr_getVRindex(v4, 4, rxb); - mnm = irgen(v1, v2, v3, v4, m5, m6); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); + irgen(v1, v2, v3, v4, m5, m6); } - static void -s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, - UChar m5), - UChar v1, UChar v2, UChar m3, UChar m5, UChar rxb) -{ - const HChar *mnm; +s390_format_VRRe( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6), + ULong ovl) +{ + UChar v1 = (ovl >> 52) & 0xf; + UChar v2 = (ovl >> 48) & 0xf; + UChar v3 = (ovl >> 44) & 0xf; + UChar m6 = (ovl >> 40) & 0xf; + UChar m5 = (ovl >> 32) & 0xf; + UChar v4 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4293,20 +3537,21 @@ s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2, m3, m5); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, vch_like_disasm), VR(v1), VR(v2), MASK(m3), MASK(m5)); + v3 = s390_vr_getVRindex(v3, 3, rxb); + v4 = s390_vr_getVRindex(v4, 4, rxb); + irgen(v1, v2, v3, v4, m5, m6); } - static void -s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar i4, UChar m5), - UChar v1, UChar v2, UChar v3, UChar i4, UChar m5, - UChar rxb) +s390_format_VRIdm( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = VRId_v1(ovl); + UChar v2 = VRId_v2(ovl); + UChar v3 = VRId_v3(ovl); + UChar i4 = VRId_i4(ovl); + UChar m5 = VRId_m5(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4316,19 +3561,18 @@ s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, i4, m5); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), UINT(i4), MASK(m5)); + irgen(v1, v2, v3, i4, m5); } - static void -s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar i4), - UChar v1, UChar v2, UChar v3, UChar i4, UChar rxb) +s390_format_VRId(void (*irgen)(UChar v1, UChar v2, UChar v3, UChar i4), + ULong ovl) { - const HChar *mnm; + UChar v1 = VRId_v1(ovl); + UChar v2 = VRId_v2(ovl); + UChar v3 = VRId_v3(ovl); + UChar i4 = VRId_i4(ovl); + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4338,20 +3582,19 @@ s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, i4); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(i4)); + irgen(v1, v2, v3, i4); } - static void -s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar v4, UChar m5), - UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, - UChar rxb) +s390_format_VRIk( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar v4, UChar i5), ULong ovl) { - const HChar *mnm; + UChar v1 = (ovl >> 52) & 0xf; + UChar v2 = (ovl >> 48) & 0xf; + UChar v3 = (ovl >> 44) & 0xf; + UChar v4 = (ovl >> 28) & 0xf; + UChar i5 = (ovl >> 32) & 0xff; + UChar rxb = V_rxb(ovl); if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4362,57 +3605,42 @@ s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); v4 = s390_vr_getVRindex(v4, 4, rxb); - mnm = irgen(v1, v2, v3, v4, m5); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5)); + irgen(v1, v2, v3, v4, i5); } - static void -s390_format_VRRa_VVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, - UChar m4, UChar m5), - UChar v1, UChar v2, UChar m3, UChar m4, UChar m5, - UChar rxb) +s390_format_VRRd1( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar v4 = VRR_v4(ovl); + UChar m5 = VRRd_m5(ovl); + UChar rxb = V_rxb(ovl); - if (!s390_host_has_vx) { + if (! s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); return; } - v1 = s390_vr_getVRindex(v1, 1, rxb); - v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2, m3, m4, m5); - - if (vex_traceflags & VEX_TRACE_FE) { - if (irgen == s390_irgen_VFLR) - S390_DISASM(XMNM(mnm, vflr_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), UINT(m5)); - else if (irgen == s390_irgen_VFI) - S390_DISASM(XMNM(mnm, vfi_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), UINT(m5)); - else if (irgen == s390_irgen_VFPSO) - S390_DISASM(XMNM(mnm, vfpso_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); - else if (irgen == s390_irgen_VCGD) - S390_DISASM(XMNM(mnm, vcgd_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); - else if (irgen == s390_irgen_VCDG) - S390_DISASM(XMNM(mnm, vcdg_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); - else if (irgen == s390_irgen_VCLGD) - S390_DISASM(XMNM(mnm, vclgd_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); - else if (irgen == s390_irgen_VCDLG) - S390_DISASM(XMNM(mnm, vcgld_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); - else - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4), UINT(m5)); - } + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + v4 = s390_vr_getVRindex(v4, 4, rxb); + irgen(v1, v2, v3, v4, m5); } static void -s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar m4, UChar m5), - UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, - UChar rxb, HChar *(*handler)(const s390_opnd *, HChar *)) +s390_format_VRRa( + void (*irgen)(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar m3 = VRRa_m3(ovl); + UChar m4 = VRRa_m4(ovl); + UChar m5 = VRRa_m5(ovl); + UChar rxb = V_rxb(ovl); if (!s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4421,24 +3649,19 @@ s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, m4, m5); - - if (vex_traceflags & VEX_TRACE_FE) { - if (handler) - S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5)); - else - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); - } + irgen(v1, v2, m3, m4, m5); } static void -s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, - UChar m4), - UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb, - HChar *(*handler)(const s390_opnd *, HChar *)) +s390_format_VRRc2( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5), ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar m4 = VRRc_m4(ovl); + UChar m5 = VRRc_m5(ovl); + UChar rxb = V_rxb(ovl); if (!s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4447,23 +3670,19 @@ s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - mnm = irgen(v1, v2, m3, m4); - - if (vex_traceflags & VEX_TRACE_FE) { - if (handler) - S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), MASK(m3), MASK(m4)); - else - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4)); - } + v3 = s390_vr_getVRindex(v3, 3, rxb); + irgen(v1, v2, v3, m4, m5); } static void -s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar m4, UChar m5, UChar m6), - UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, - UChar m6, UChar rxb) +s390_format_VRRa2(void (*irgen)(UChar v1, UChar v2, UChar m3, UChar m4), + ULong ovl) { - const HChar *mnm; + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar m3 = VRRa_m3(ovl); + UChar m4 = VRRa_m4(ovl); + UChar rxb = V_rxb(ovl); if (!s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4472,21 +3691,21 @@ s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); - v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, m4, m5, m6); - - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(XMNM(mnm, vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); + irgen(v1, v2, m3, m4); } - static void -s390_format_VRRa_VVVMMM2(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar m4, UChar m5, UChar m6), - UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, - UChar m6, UChar rxb) -{ - const HChar *mnm; +s390_format_VRRc( + void (*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6), + ULong ovl) +{ + UChar v1 = VRR_v1(ovl); + UChar v2 = VRR_v2(ovl); + UChar v3 = VRR_v3(ovl); + UChar m4 = VRRc_m4(ovl); + UChar m5 = VRRc_m5(ovl); + UChar m6 = VRRc_m6(ovl); + UChar rxb = V_rxb(ovl); if (!s390_host_has_vx) { emulation_failure(EmFail_S390X_vx); @@ -4496,17 +3715,17 @@ s390_format_VRRa_VVVMMM2(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v1 = s390_vr_getVRindex(v1, 1, rxb); v2 = s390_vr_getVRindex(v2, 2, rxb); v3 = s390_vr_getVRindex(v3, 3, rxb); - mnm = irgen(v1, v2, v3, m4, m5, m6); - - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(XMNM(mnm, vfmix_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), UINT(m6)); + irgen(v1, v2, v3, m4, m5, m6); } static void -s390_format_VSI_URDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar i3), - UChar v1, UChar b2, UShort d2, UChar i3, UChar rxb) +s390_format_VSI(void (*irgen)(UChar v1, IRTemp op2addr, UChar i3), ULong ovl) { - const HChar *mnm; + UChar i3 = (ovl >> 48) & 0xff; + UChar b2 = (ovl >> 44) & 0xf; + UShort d2 = (ovl >> 32) & 0xfff; + UChar v1 = (ovl >> 28) & 0xf; + UChar rxb = V_rxb(ovl); IRTemp op2addr = newTemp(Ity_I64); if (!s390_host_has_vx) { @@ -4519,17 +3738,14 @@ s390_format_VSI_URDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar i3), assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : mkU64(0))); - mnm = irgen(v1, op2addr, i3); - - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, 0, b2), UINT(i3)); + irgen(v1, op2addr, i3); } /*------------------------------------------------------------*/ /*--- Build IR for opcodes ---*/ /*------------------------------------------------------------*/ -static const HChar * +static void s390_irgen_AR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -4541,11 +3757,9 @@ s390_irgen_AR(UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "ar"; } -static const HChar * +static void s390_irgen_AGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -4557,11 +3771,9 @@ s390_irgen_AGR(UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "agr"; } -static const HChar * +static void s390_irgen_AGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -4573,11 +3785,9 @@ s390_irgen_AGFR(UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "agfr"; } -static const HChar * +static void s390_irgen_ARK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -4589,11 +3799,9 @@ s390_irgen_ARK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); put_gpr_w1(r1, mkexpr(result)); - - return "ark"; } -static const HChar * +static void s390_irgen_AGRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -4605,11 +3813,9 @@ s390_irgen_AGRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3); put_gpr_dw0(r1, mkexpr(result)); - - return "agrk"; } -static const HChar * +static void s390_irgen_A(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4621,11 +3827,9 @@ s390_irgen_A(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "a"; } -static const HChar * +static void s390_irgen_AY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4637,11 +3841,9 @@ s390_irgen_AY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "ay"; } -static const HChar * +static void s390_irgen_AG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -4653,11 +3855,9 @@ s390_irgen_AG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "ag"; } -static const HChar * +static void s390_irgen_AGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -4669,11 +3869,9 @@ s390_irgen_AGF(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "agf"; } -static const HChar * +static void s390_irgen_AFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -4686,11 +3884,9 @@ s390_irgen_AFI(UChar r1, UInt i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32((UInt)op2))); put_gpr_w1(r1, mkexpr(result)); - - return "afi"; } -static const HChar * +static void s390_irgen_AGFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -4703,11 +3899,9 @@ s390_irgen_AGFI(UChar r1, UInt i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, mkU64((ULong)op2))); put_gpr_dw0(r1, mkexpr(result)); - - return "agfi"; } -static const HChar * +static void s390_irgen_AHIK(UChar r1, UChar r3, UShort i2) { Int op2; @@ -4720,11 +3914,9 @@ s390_irgen_AHIK(UChar r1, UChar r3, UShort i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt) op2)), op3); put_gpr_w1(r1, mkexpr(result)); - - return "ahik"; } -static const HChar * +static void s390_irgen_AGH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -4736,11 +3928,9 @@ s390_irgen_AGH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "agh"; } -static const HChar * +static void s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2) { Long op2; @@ -4753,11 +3943,9 @@ s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong) op2)), op3); put_gpr_dw0(r1, mkexpr(result)); - - return "aghik"; } -static const HChar * +static void s390_irgen_ASI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4770,11 +3958,9 @@ s390_irgen_ASI(UChar i2, IRTemp op1addr) store(mkexpr(op1addr), mkexpr(result)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32((UInt)op2))); - - return "asi"; } -static const HChar * +static void s390_irgen_AGSI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I64); @@ -4787,11 +3973,9 @@ s390_irgen_AGSI(UChar i2, IRTemp op1addr) store(mkexpr(op1addr), mkexpr(result)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, mkU64((ULong)op2))); - - return "agsi"; } -static const HChar * +static void s390_irgen_AH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4803,11 +3987,9 @@ s390_irgen_AH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "ah"; } -static const HChar * +static void s390_irgen_AHY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4819,11 +4001,9 @@ s390_irgen_AHY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "ahy"; } -static const HChar * +static void s390_irgen_AHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I32); @@ -4836,11 +4016,9 @@ s390_irgen_AHI(UChar r1, UShort i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32((UInt)op2))); put_gpr_w1(r1, mkexpr(result)); - - return "ahi"; } -static const HChar * +static void s390_irgen_AGHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I64); @@ -4853,11 +4031,9 @@ s390_irgen_AGHI(UChar r1, UShort i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, mkU64((ULong)op2))); put_gpr_dw0(r1, mkexpr(result)); - - return "aghi"; } -static const HChar * +static void s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -4869,11 +4045,9 @@ s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "ahhhr"; } -static const HChar * +static void s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -4885,11 +4059,9 @@ s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "ahhlr"; } -static const HChar * +static void s390_irgen_AIH(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -4902,11 +4074,9 @@ s390_irgen_AIH(UChar r1, UInt i2) s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32((UInt)op2))); put_gpr_w0(r1, mkexpr(result)); - - return "aih"; } -static const HChar * +static void s390_irgen_ALR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -4918,11 +4088,9 @@ s390_irgen_ALR(UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "alr"; } -static const HChar * +static void s390_irgen_ALGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -4934,11 +4102,9 @@ s390_irgen_ALGR(UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "algr"; } -static const HChar * +static void s390_irgen_ALGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -4950,11 +4116,9 @@ s390_irgen_ALGFR(UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "algfr"; } -static const HChar * +static void s390_irgen_ALRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -4966,11 +4130,9 @@ s390_irgen_ALRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); put_gpr_w1(r1, mkexpr(result)); - - return "alrk"; } -static const HChar * +static void s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -4982,11 +4144,9 @@ s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3); put_gpr_dw0(r1, mkexpr(result)); - - return "algrk"; } -static const HChar * +static void s390_irgen_AL(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -4998,11 +4158,9 @@ s390_irgen_AL(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "al"; } -static const HChar * +static void s390_irgen_ALY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5014,11 +4172,9 @@ s390_irgen_ALY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "aly"; } -static const HChar * +static void s390_irgen_ALG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5030,11 +4186,9 @@ s390_irgen_ALG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "alg"; } -static const HChar * +static void s390_irgen_ALGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5046,11 +4200,9 @@ s390_irgen_ALGF(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "algf"; } -static const HChar * +static void s390_irgen_ALFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -5063,11 +4215,9 @@ s390_irgen_ALFI(UChar r1, UInt i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32(op2))); put_gpr_w1(r1, mkexpr(result)); - - return "alfi"; } -static const HChar * +static void s390_irgen_ALGFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -5080,11 +4230,9 @@ s390_irgen_ALGFI(UChar r1, UInt i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64, mkU64(op2))); put_gpr_dw0(r1, mkexpr(result)); - - return "algfi"; } -static const HChar * +static void s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -5096,11 +4244,9 @@ s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "alhhhr"; } -static const HChar * +static void s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -5112,11 +4258,9 @@ s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "alhhlr"; } -static const HChar * +static void s390_irgen_ALCR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -5131,11 +4275,9 @@ s390_irgen_ALCR(UChar r1, UChar r2) mkexpr(carry_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in); put_gpr_w1(r1, mkexpr(result)); - - return "alcr"; } -static const HChar * +static void s390_irgen_ALCGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -5151,11 +4293,9 @@ s390_irgen_ALCGR(UChar r1, UChar r2) mkexpr(carry_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in); put_gpr_dw0(r1, mkexpr(result)); - - return "alcgr"; } -static const HChar * +static void s390_irgen_ALC(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5170,11 +4310,9 @@ s390_irgen_ALC(UChar r1, IRTemp op2addr) mkexpr(carry_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in); put_gpr_w1(r1, mkexpr(result)); - - return "alc"; } -static const HChar * +static void s390_irgen_ALCG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5190,11 +4328,9 @@ s390_irgen_ALCG(UChar r1, IRTemp op2addr) mkexpr(carry_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in); put_gpr_dw0(r1, mkexpr(result)); - - return "alcg"; } -static const HChar * +static void s390_irgen_ALSI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5207,11 +4343,9 @@ s390_irgen_ALSI(UChar i2, IRTemp op1addr) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32(op2))); store(mkexpr(op1addr), mkexpr(result)); - - return "alsi"; } -static const HChar * +static void s390_irgen_ALGSI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5224,11 +4358,9 @@ s390_irgen_ALGSI(UChar i2, IRTemp op1addr) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64, mkU64(op2))); store(mkexpr(op1addr), mkexpr(result)); - - return "algsi"; } -static const HChar * +static void s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2) { UInt op2; @@ -5241,11 +4373,9 @@ s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)), op3); put_gpr_w1(r1, mkexpr(result)); - - return "alhsik"; } -static const HChar * +static void s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2) { ULong op2; @@ -5258,11 +4388,9 @@ s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)), op3); put_gpr_dw0(r1, mkexpr(result)); - - return "alghsik"; } -static const HChar * +static void s390_irgen_ALSIH(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -5275,11 +4403,9 @@ s390_irgen_ALSIH(UChar r1, UInt i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, mkU32(op2))); put_gpr_w0(r1, mkexpr(result)); - - return "alsih"; } -static const HChar * +static void s390_irgen_ALSIHN(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -5290,11 +4416,9 @@ s390_irgen_ALSIHN(UChar r1, UInt i2) op2 = i2; assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2))); put_gpr_w0(r1, mkexpr(result)); - - return "alsihn"; } -static const HChar * +static void s390_irgen_NR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -5306,11 +4430,9 @@ s390_irgen_NR(UChar r1, UChar r2) assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "nr"; } -static const HChar * +static void s390_irgen_NGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -5322,16 +4444,14 @@ s390_irgen_NGR(UChar r1, UChar r2) assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "ngr"; } /* Helper for bitwise logical instructions with two 32-bit input operands and a 32-bit output operand. `inv3' and `inv' indicate whether to invert (build bitwise complement of) operand 3 or the result, respectively. */ -static const HChar * +static void s390_irgen_logicalK32(UChar r3, UChar r1, UChar r2, - const HChar *mnem, IROp op, Bool inv3, Bool inv) + IROp op, Bool inv3, Bool inv) { IRTemp op2 = newTemp(Ity_I32); IRTemp op3 = newTemp(Ity_I32); @@ -5344,14 +4464,12 @@ s390_irgen_logicalK32(UChar r3, UChar r1, UChar r2, assign(result, inv ? unop(Iop_Not32, tmp) : tmp); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return mnem; } /* Same as s390_irgen_logicalK32, but for 64-bit operands. */ -static const HChar * +static void s390_irgen_logicalK64(UChar r3, UChar r1, UChar r2, - const HChar *mnem, IROp op, Bool inv3, Bool inv) + IROp op, Bool inv3, Bool inv) { IRTemp op2 = newTemp(Ity_I64); IRTemp op3 = newTemp(Ity_I64); @@ -5364,47 +4482,45 @@ s390_irgen_logicalK64(UChar r3, UChar r1, UChar r2, assign(result, inv ? unop(Iop_Not64, tmp) : tmp); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return mnem; } -static const HChar * +static void s390_irgen_NRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "nrk", Iop_And32, False, False); + s390_irgen_logicalK32(r3, r1, r2, Iop_And32, False, False); } -static const HChar * +static void s390_irgen_NGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "ngrk", Iop_And64, False, False); + s390_irgen_logicalK64(r3, r1, r2, Iop_And64, False, False); } -static const HChar * +static void s390_irgen_NCRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "ncrk", Iop_And32, True, False); + s390_irgen_logicalK32(r3, r1, r2, Iop_And32, True, False); } -static const HChar * +static void s390_irgen_NCGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "ncgrk", Iop_And64, True, False); + s390_irgen_logicalK64(r3, r1, r2, Iop_And64, True, False); } -static const HChar * +static void s390_irgen_NNRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "nnrk", Iop_And32, False, True); + s390_irgen_logicalK32(r3, r1, r2, Iop_And32, False, True); } -static const HChar * +static void s390_irgen_NNGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "nngrk", Iop_And64, False, True); + s390_irgen_logicalK64(r3, r1, r2, Iop_And64, False, True); } -static const HChar * +static void s390_irgen_N(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5416,11 +4532,9 @@ s390_irgen_N(UChar r1, IRTemp op2addr) assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "n"; } -static const HChar * +static void s390_irgen_NY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5432,11 +4546,9 @@ s390_irgen_NY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "ny"; } -static const HChar * +static void s390_irgen_NG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5448,11 +4560,9 @@ s390_irgen_NG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "ng"; } -static const HChar * +static void s390_irgen_NI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -5464,11 +4574,9 @@ s390_irgen_NI(UChar i2, IRTemp op1addr) assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "ni"; } -static const HChar * +static void s390_irgen_NIY(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -5480,11 +4588,9 @@ s390_irgen_NIY(UChar i2, IRTemp op1addr) assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "niy"; } -static const HChar * +static void s390_irgen_NIHF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -5496,11 +4602,9 @@ s390_irgen_NIHF(UChar r1, UInt i2) assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w0(r1, mkexpr(result)); - - return "nihf"; } -static const HChar * +static void s390_irgen_NIHH(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -5512,11 +4616,9 @@ s390_irgen_NIHH(UChar r1, UShort i2) assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw0(r1, mkexpr(result)); - - return "nihh"; } -static const HChar * +static void s390_irgen_NIHL(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -5528,11 +4630,9 @@ s390_irgen_NIHL(UChar r1, UShort i2) assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw1(r1, mkexpr(result)); - - return "nihl"; } -static const HChar * +static void s390_irgen_NILF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -5544,11 +4644,9 @@ s390_irgen_NILF(UChar r1, UInt i2) assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "nilf"; } -static const HChar * +static void s390_irgen_NILH(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -5560,11 +4658,9 @@ s390_irgen_NILH(UChar r1, UShort i2) assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw2(r1, mkexpr(result)); - - return "nilh"; } -static const HChar * +static void s390_irgen_NILL(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -5576,11 +4672,9 @@ s390_irgen_NILL(UChar r1, UShort i2) assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw3(r1, mkexpr(result)); - - return "nill"; } -static const HChar * +static void s390_irgen_BASR(UChar r1, UChar r2) { IRTemp target = newTemp(Ity_I64); @@ -5597,11 +4691,9 @@ s390_irgen_BASR(UChar r1, UChar r2) call_function(mkexpr(target)); } } - - return "basr"; } -static const HChar * +static void s390_irgen_BAS(UChar r1, IRTemp op2addr) { IRTemp target = newTemp(Ity_I64); @@ -5609,11 +4701,9 @@ s390_irgen_BAS(UChar r1, IRTemp op2addr) put_gpr_dw0(r1, mkU64(guest_IA_next_instr)); assign(target, mkexpr(op2addr)); call_function(mkexpr(target)); - - return "bas"; } -static const HChar * +static void s390_irgen_BCR(UChar m1, UChar r2) { IRTemp cond = newTemp(Ity_I32); @@ -5632,14 +4722,10 @@ s390_irgen_BCR(UChar m1, UChar r2) get_gpr_dw0(r2)); } } - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM("bcr", bcr_disasm), MASK(m1), GPR(r2)); - - return "bcr"; } -static const HChar * -s390_irgen_BC(UChar m1, UChar x2, UChar b2, UShort d2, IRTemp op2addr) +static void +s390_irgen_BC(UChar m1, IRTemp op2addr) { IRTemp cond = newTemp(Ity_I32); @@ -5653,13 +4739,9 @@ s390_irgen_BC(UChar m1, UChar x2, UChar b2, UShort d2, IRTemp op2addr) mkexpr(op2addr)); } } - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM("bc", bc_disasm), MASK(m1), UDXB(d2, x2, b2)); - - return "bc"; } -static const HChar * +static void s390_irgen_BCTR(UChar r1, UChar r2) { put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); @@ -5667,11 +4749,9 @@ s390_irgen_BCTR(UChar r1, UChar r2) if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), get_gpr_dw0(r2)); } - - return "bctr"; } -static const HChar * +static void s390_irgen_BCTGR(UChar r1, UChar r2) { put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); @@ -5679,31 +4759,25 @@ s390_irgen_BCTGR(UChar r1, UChar r2) if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), get_gpr_dw0(r2)); } - - return "bctgr"; } -static const HChar * +static void s390_irgen_BCT(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), mkexpr(op2addr)); - - return "bct"; } -static const HChar * +static void s390_irgen_BCTG(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), mkexpr(op2addr)); - - return "bctg"; } -static const HChar * +static void s390_irgen_BIC(UChar r1, IRTemp op2addr) { IRTemp cond = newTemp(Ity_I32); @@ -5717,11 +4791,9 @@ s390_irgen_BIC(UChar r1, IRTemp op2addr) if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), load(Ity_I64, mkexpr(op2addr))); } - - return "bic"; } -static const HChar * +static void s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr) { IRTemp value = newTemp(Ity_I32); @@ -5730,11 +4802,9 @@ s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr) put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)), mkexpr(op2addr)); - - return "bxh"; } -static const HChar * +static void s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp value = newTemp(Ity_I64); @@ -5743,11 +4813,9 @@ s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr) put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)), mkexpr(op2addr)); - - return "bxhg"; } -static const HChar * +static void s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr) { IRTemp value = newTemp(Ity_I32); @@ -5756,11 +4824,9 @@ s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr) put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)), mkexpr(op2addr)); - - return "bxle"; } -static const HChar * +static void s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp value = newTemp(Ity_I64); @@ -5769,29 +4835,23 @@ s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr) put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)), mkexpr(op2addr)); - - return "bxleg"; } -static const HChar * +static void s390_irgen_BRAS(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64(guest_IA_next_instr)); call_function(mkaddr_expr(addr_relative(i2))); - - return "bras"; } -static const HChar * +static void s390_irgen_BRASL(UChar r1, UInt i2) { put_gpr_dw0(r1, mkU64(guest_IA_next_instr)); call_function(mkaddr_expr(addr_rel_long(i2))); - - return "brasl"; } -static const HChar * +static void s390_irgen_BRC(UChar m1, UShort i2) { IRTemp cond = newTemp(Ity_I32); @@ -5807,13 +4867,9 @@ s390_irgen_BRC(UChar m1, UShort i2) } } - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM("brc", brc_disasm), MASK(m1), PCREL((Int)(Short)i2)); - - return "brc"; } -static const HChar * +static void s390_irgen_BRCL(UChar m1, UInt i2) { IRTemp cond = newTemp(Ity_I32); @@ -5828,43 +4884,33 @@ s390_irgen_BRCL(UChar m1, UInt i2) addr_rel_long(i2)); } } - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(XMNM("brcl", brcl_disasm), MASK(m1), PCREL(i2)); - - return "brcl"; } -static const HChar * +static void s390_irgen_BRCT(UChar r1, UShort i2) { put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), addr_relative(i2)); - - return "brct"; } -static const HChar * +static void s390_irgen_BRCTH(UChar r1, UInt i2) { put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1))); if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)), addr_relative(i2)); - - return "brcth"; } -static const HChar * +static void s390_irgen_BRCTG(UChar r1, UShort i2) { put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), addr_relative(i2)); - - return "brctg"; } -static const HChar * +static void s390_irgen_BRXH(UChar r1, UChar r3, UShort i2) { IRTemp value = newTemp(Ity_I32); @@ -5873,11 +4919,9 @@ s390_irgen_BRXH(UChar r1, UChar r3, UShort i2) put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)), addr_relative(i2)); - - return "brxh"; } -static const HChar * +static void s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2) { IRTemp value = newTemp(Ity_I64); @@ -5886,11 +4930,9 @@ s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2) put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)), addr_relative(i2)); - - return "brxhg"; } -static const HChar * +static void s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2) { IRTemp value = newTemp(Ity_I32); @@ -5899,11 +4941,9 @@ s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2) put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)), addr_relative(i2)); - - return "brxle"; } -static const HChar * +static void s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2) { IRTemp value = newTemp(Ity_I64); @@ -5912,11 +4952,9 @@ s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2) put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)), addr_relative(i2)); - - return "brxlg"; } -static const HChar * +static void s390_irgen_CR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -5925,11 +4963,9 @@ s390_irgen_CR(UChar r1, UChar r2) assign(op1, get_gpr_w1(r1)); assign(op2, get_gpr_w1(r2)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cr"; } -static const HChar * +static void s390_irgen_CGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -5938,11 +4974,9 @@ s390_irgen_CGR(UChar r1, UChar r2) assign(op1, get_gpr_dw0(r1)); assign(op2, get_gpr_dw0(r2)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgr"; } -static const HChar * +static void s390_irgen_CGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -5951,11 +4985,9 @@ s390_irgen_CGFR(UChar r1, UChar r2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgfr"; } -static const HChar * +static void s390_irgen_C(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5964,11 +4996,9 @@ s390_irgen_C(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "c"; } -static const HChar * +static void s390_irgen_CY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -5977,11 +5007,9 @@ s390_irgen_CY(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cy"; } -static const HChar * +static void s390_irgen_CG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -5990,11 +5018,9 @@ s390_irgen_CG(UChar r1, IRTemp op2addr) assign(op1, get_gpr_dw0(r1)); assign(op2, load(Ity_I64, mkexpr(op2addr))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cg"; } -static const HChar * +static void s390_irgen_CGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6003,11 +5029,9 @@ s390_irgen_CGF(UChar r1, IRTemp op2addr) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgf"; } -static const HChar * +static void s390_irgen_CFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6017,11 +5041,9 @@ s390_irgen_CFI(UChar r1, UInt i2) op2 = (Int)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32((UInt)op2))); - - return "cfi"; } -static const HChar * +static void s390_irgen_CGFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6031,11 +5053,9 @@ s390_irgen_CGFI(UChar r1, UInt i2) op2 = (Long)(Int)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, mkU64((ULong)op2))); - - return "cgfi"; } -static const HChar * +static void s390_irgen_CRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6044,11 +5064,9 @@ s390_irgen_CRL(UChar r1, UInt i2) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "crl"; } -static const HChar * +static void s390_irgen_CGRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6057,11 +5075,9 @@ s390_irgen_CGRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgrl"; } -static const HChar * +static void s390_irgen_CGFRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6070,11 +5086,9 @@ s390_irgen_CGFRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgfrl"; } -static const HChar * +static void s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6094,11 +5108,9 @@ s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) mkU32(0)), mkexpr(op4addr)); } } - - return "crb"; } -static const HChar * +static void s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6118,11 +5130,9 @@ s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) mkU32(0)), mkexpr(op4addr)); } } - - return "cgrb"; } -static const HChar * +static void s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3) { IRTemp op1 = newTemp(Ity_I32); @@ -6140,14 +5150,11 @@ s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3) op1, op2)); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "crj"; } -static const HChar * +static void s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3) { IRTemp op1 = newTemp(Ity_I64); @@ -6165,14 +5172,11 @@ s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3) op1, op2)); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "cgrj"; } -static const HChar * +static void s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6192,11 +5196,9 @@ s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) mkexpr(op4addr)); } } - - return "cib"; } -static const HChar * +static void s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6216,11 +5218,9 @@ s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) mkexpr(op4addr)); } } - - return "cgib"; } -static const HChar * +static void s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6238,14 +5238,11 @@ s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2) mktemp(Ity_I32, mkU32((UInt)op2)))); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "cij"; } -static const HChar * +static void s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6263,14 +5260,11 @@ s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2) mktemp(Ity_I64, mkU64((ULong)op2)))); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "cgij"; } -static const HChar * +static void s390_irgen_CH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6279,11 +5273,9 @@ s390_irgen_CH(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "ch"; } -static const HChar * +static void s390_irgen_CHY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6292,11 +5284,9 @@ s390_irgen_CHY(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chy"; } -static const HChar * +static void s390_irgen_CGH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6305,11 +5295,9 @@ s390_irgen_CGH(UChar r1, IRTemp op2addr) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgh"; } -static const HChar * +static void s390_irgen_CHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6319,11 +5307,9 @@ s390_irgen_CHI(UChar r1, UShort i2) op2 = (Int)(Short)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32((UInt)op2))); - - return "chi"; } -static const HChar * +static void s390_irgen_CGHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6333,11 +5319,9 @@ s390_irgen_CGHI(UChar r1, UShort i2) op2 = (Long)(Short)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, mkU64((ULong)op2))); - - return "cghi"; } -static const HChar * +static void s390_irgen_CHHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I16); @@ -6347,11 +5331,9 @@ s390_irgen_CHHSI(UShort i2, IRTemp op1addr) op2 = (Short)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16, mkU16((UShort)op2))); - - return "chhsi"; } -static const HChar * +static void s390_irgen_CHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6361,11 +5343,9 @@ s390_irgen_CHSI(UShort i2, IRTemp op1addr) op2 = (Int)(Short)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32((UInt)op2))); - - return "chsi"; } -static const HChar * +static void s390_irgen_CGHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6375,11 +5355,9 @@ s390_irgen_CGHSI(UShort i2, IRTemp op1addr) op2 = (Long)(Short)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, mkU64((ULong)op2))); - - return "cghsi"; } -static const HChar * +static void s390_irgen_CHRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6388,11 +5366,9 @@ s390_irgen_CHRL(UChar r1, UInt i2) assign(op1, get_gpr_w1(r1)); assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chrl"; } -static const HChar * +static void s390_irgen_CGHRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6401,11 +5377,9 @@ s390_irgen_CGHRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cghrl"; } -static const HChar * +static void s390_irgen_CHHR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -6414,11 +5388,9 @@ s390_irgen_CHHR(UChar r1, UChar r2) assign(op1, get_gpr_w0(r1)); assign(op2, get_gpr_w0(r2)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chhr"; } -static const HChar * +static void s390_irgen_CHLR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -6427,11 +5399,9 @@ s390_irgen_CHLR(UChar r1, UChar r2) assign(op1, get_gpr_w0(r1)); assign(op2, get_gpr_w1(r2)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chlr"; } -static const HChar * +static void s390_irgen_CHF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6440,11 +5410,9 @@ s390_irgen_CHF(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w0(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chf"; } -static const HChar * +static void s390_irgen_CIH(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6454,11 +5422,9 @@ s390_irgen_CIH(UChar r1, UInt i2) op2 = (Int)i2; s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32((UInt)op2))); - - return "cih"; } -static const HChar * +static void s390_irgen_CLR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -6467,11 +5433,9 @@ s390_irgen_CLR(UChar r1, UChar r2) assign(op1, get_gpr_w1(r1)); assign(op2, get_gpr_w1(r2)); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clr"; } -static const HChar * +static void s390_irgen_CLGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -6480,11 +5444,9 @@ s390_irgen_CLGR(UChar r1, UChar r2) assign(op1, get_gpr_dw0(r1)); assign(op2, get_gpr_dw0(r2)); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgr"; } -static const HChar * +static void s390_irgen_CLGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -6493,11 +5455,9 @@ s390_irgen_CLGFR(UChar r1, UChar r2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgfr"; } -static const HChar * +static void s390_irgen_CL(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6506,11 +5466,9 @@ s390_irgen_CL(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "cl"; } -static const HChar * +static void s390_irgen_CLY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6519,11 +5477,9 @@ s390_irgen_CLY(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "cly"; } -static const HChar * +static void s390_irgen_CLG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6532,11 +5488,9 @@ s390_irgen_CLG(UChar r1, IRTemp op2addr) assign(op1, get_gpr_dw0(r1)); assign(op2, load(Ity_I64, mkexpr(op2addr))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clg"; } -static const HChar * +static void s390_irgen_CLGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6545,11 +5499,9 @@ s390_irgen_CLGF(UChar r1, IRTemp op2addr) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgf"; } -static const HChar * +static void s390_irgen_CLFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6559,11 +5511,9 @@ s390_irgen_CLFI(UChar r1, UInt i2) op2 = i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32(op2))); - - return "clfi"; } -static const HChar * +static void s390_irgen_CLGFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6573,11 +5523,9 @@ s390_irgen_CLGFI(UChar r1, UInt i2) op2 = (ULong)i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64, mkU64(op2))); - - return "clgfi"; } -static const HChar * +static void s390_irgen_CLI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -6587,11 +5535,9 @@ s390_irgen_CLI(UChar i2, IRTemp op1addr) op2 = i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8, mkU8(op2))); - - return "cli"; } -static const HChar * +static void s390_irgen_CLIY(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -6601,11 +5547,9 @@ s390_irgen_CLIY(UChar i2, IRTemp op1addr) op2 = i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8, mkU8(op2))); - - return "cliy"; } -static const HChar * +static void s390_irgen_CLFHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6615,11 +5559,9 @@ s390_irgen_CLFHSI(UShort i2, IRTemp op1addr) op2 = (UInt)i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32(op2))); - - return "clfhsi"; } -static const HChar * +static void s390_irgen_CLGHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6629,11 +5571,9 @@ s390_irgen_CLGHSI(UShort i2, IRTemp op1addr) op2 = (ULong)i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64, mkU64(op2))); - - return "clghsi"; } -static const HChar * +static void s390_irgen_CLHHSI(UShort i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I16); @@ -6643,11 +5583,9 @@ s390_irgen_CLHHSI(UShort i2, IRTemp op1addr) op2 = i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16, mkU16(op2))); - - return "clhhsi"; } -static const HChar * +static void s390_irgen_CLRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6656,11 +5594,9 @@ s390_irgen_CLRL(UChar r1, UInt i2) assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2)))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clrl"; } -static const HChar * +static void s390_irgen_CLGRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6669,11 +5605,9 @@ s390_irgen_CLGRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2)))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgrl"; } -static const HChar * +static void s390_irgen_CLGFRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6682,11 +5616,9 @@ s390_irgen_CLGFRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgfrl"; } -static const HChar * +static void s390_irgen_CLHRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -6695,11 +5627,9 @@ s390_irgen_CLHRL(UChar r1, UInt i2) assign(op1, get_gpr_w1(r1)); assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clhrl"; } -static const HChar * +static void s390_irgen_CLGHRL(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -6708,11 +5638,9 @@ s390_irgen_CLGHRL(UChar r1, UInt i2) assign(op1, get_gpr_dw0(r1)); assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clghrl"; } -static const HChar * +static void s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I32); @@ -6732,11 +5660,9 @@ s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) mkexpr(op4addr)); } } - - return "clrb"; } -static const HChar * +static void s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I64); @@ -6756,8 +5682,6 @@ s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) mkexpr(op4addr)); } } - - return "clgrb"; } /* Raise the appropriate signal for a compare-and-trap-instruction data @@ -6793,32 +5717,28 @@ s390_irgen_CxRT(UChar m3, UChar r1, UChar r2, IRType type, UInt opc) s390_trap_on_condition(cond); } -static const HChar * +static void s390_irgen_CGRT(UChar m3, UChar r1, UChar r2) { s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_SIGNED_COMPARE); - return "cgrt"; } -static const HChar * +static void s390_irgen_CRT(UChar m3, UChar r1, UChar r2) { s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_SIGNED_COMPARE); - return "crt"; } -static const HChar * +static void s390_irgen_CLGRT(UChar m3, UChar r1, UChar r2) { s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); - return "clgrt"; } -static const HChar * +static void s390_irgen_CLRT(UChar m3, UChar r1, UChar r2) { s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); - return "clrt"; } /* Handle the various flavors of compare (logical) immediate and trap. */ @@ -6851,32 +5771,28 @@ s390_irgen_CxIT(UChar m3, UChar r1, UShort i2, IRType type, UInt opc) s390_trap_on_condition(cond); } -static const HChar * +static void s390_irgen_CGIT(UChar r1, UShort i2, UChar m3) { s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_SIGNED_COMPARE); - return "cgit"; } -static const HChar * +static void s390_irgen_CIT(UChar r1, UShort i2, UChar m3) { s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_SIGNED_COMPARE); - return "cit"; } -static const HChar * +static void s390_irgen_CLGIT(UChar r1, UShort i2, UChar m3) { s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); - return "clgit"; } -static const HChar * +static void s390_irgen_CLFIT(UChar r1, UShort i2, UChar m3) { s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); - return "clfit"; } /* Handle the variants of compare logical and trap with memory operand. */ @@ -6903,61 +5819,55 @@ s390_irgen_CLxT(UChar r1, UChar m3, IRTemp op2addr, IRType type, UInt opc) s390_trap_on_condition(cond); } -static const HChar * +static void s390_irgen_CLT(UChar r1, UChar m3, IRTemp op2addr) { s390_irgen_CLxT(r1, m3, op2addr, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); - return "clt"; } -static const HChar * +static void s390_irgen_CLGT(UChar r1, UChar m3, IRTemp op2addr) { s390_irgen_CLxT(r1, m3, op2addr, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); - return "clgt"; } -static const HChar * +static void s390_irgen_LAT(UChar r1, IRTemp op2addr) { IRTemp val = newTemp(Ity_I32); assign(val, load(Ity_I32, mkexpr(op2addr))); put_gpr_w1(r1, mkexpr(val)); s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0))); - return "lat"; } -static const HChar * +static void s390_irgen_LGAT(UChar r1, IRTemp op2addr) { IRTemp val = newTemp(Ity_I64); assign(val, load(Ity_I64, mkexpr(op2addr))); put_gpr_dw0(r1, mkexpr(val)); s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); - return "lgat"; } -static const HChar * +static void s390_irgen_LFHAT(UChar r1, IRTemp op2addr) { IRTemp val = newTemp(Ity_I32); assign(val, load(Ity_I32, mkexpr(op2addr))); put_gpr_w0(r1, mkexpr(val)); s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0))); - return "lfhat"; } -static const HChar * +static void s390_irgen_LLGFAT(UChar r1, IRTemp op2addr) { IRTemp val = newTemp(Ity_I64); assign(val, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); put_gpr_dw0(r1, mkexpr(val)); s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); - return "llgfat"; } -static const HChar * +static void s390_irgen_LLGTAT(UChar r1, IRTemp op2addr) { IRTemp val = newTemp(Ity_I64); @@ -6965,10 +5875,9 @@ s390_irgen_LLGTAT(UChar r1, IRTemp op2addr) unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))))); put_gpr_dw0(r1, mkexpr(val)); s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); - return "llgtat"; } -static const HChar * +static void s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3) { IRTemp op1 = newTemp(Ity_I32); @@ -6986,14 +5895,11 @@ s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3) op1, op2)); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "clrj"; } -static const HChar * +static void s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3) { IRTemp op1 = newTemp(Ity_I64); @@ -7011,14 +5917,11 @@ s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3) op1, op2)); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "clgrj"; } -static const HChar * +static void s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I32); @@ -7038,11 +5941,9 @@ s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) mkexpr(op4addr)); } } - - return "clib"; } -static const HChar * +static void s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) { IRTemp op1 = newTemp(Ity_I64); @@ -7062,11 +5963,9 @@ s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) mkexpr(op4addr)); } } - - return "clgib"; } -static const HChar * +static void s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2) { IRTemp op1 = newTemp(Ity_I32); @@ -7084,14 +5983,11 @@ s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2) mktemp(Ity_I32, mkU32(op2)))); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "clij"; } -static const HChar * +static void s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2) { IRTemp op1 = newTemp(Ity_I64); @@ -7109,14 +6005,11 @@ s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2) mktemp(Ity_I64, mkU64(op2)))); if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), addr_relative(i4)); - } } - - return "clgij"; } -static const HChar * +static void s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -7174,12 +6067,10 @@ s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr) mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clm"; } -static const HChar * -s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_CLMY(UChar r1, UChar m3, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -7194,7 +6085,7 @@ s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) UChar n; n = 0; - if ((r3 & 8) != 0) { + if ((m3 & 8) != 0) { assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1))); assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); n = n + 1; @@ -7202,7 +6093,7 @@ s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) assign(b0, mkU32(0)); assign(c0, mkU32(0)); } - if ((r3 & 4) != 0) { + if ((m3 & 4) != 0) { assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1))); assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7211,7 +6102,7 @@ s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) assign(b1, mkU32(0)); assign(c1, mkU32(0)); } - if ((r3 & 2) != 0) { + if ((m3 & 2) != 0) { assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1))); assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7220,7 +6111,7 @@ s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) assign(b2, mkU32(0)); assign(c2, mkU32(0)); } - if ((r3 & 1) != 0) { + if ((m3 & 1) != 0) { assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1))); assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7236,12 +6127,10 @@ s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clmy"; } -static const HChar * -s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_CLMH(UChar r1, UChar m3, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -7256,7 +6145,7 @@ s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) UChar n; n = 0; - if ((r3 & 8) != 0) { + if ((m3 & 8) != 0) { assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1))); assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); n = n + 1; @@ -7264,7 +6153,7 @@ s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) assign(b0, mkU32(0)); assign(c0, mkU32(0)); } - if ((r3 & 4) != 0) { + if ((m3 & 4) != 0) { assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1))); assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7273,7 +6162,7 @@ s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) assign(b1, mkU32(0)); assign(c1, mkU32(0)); } - if ((r3 & 2) != 0) { + if ((m3 & 2) != 0) { assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1))); assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7282,7 +6171,7 @@ s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) assign(b2, mkU32(0)); assign(c2, mkU32(0)); } - if ((r3 & 1) != 0) { + if ((m3 & 1) != 0) { assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1))); assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))))); @@ -7298,11 +6187,9 @@ s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clmh"; } -static const HChar * +static void s390_irgen_CLHHR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -7311,11 +6198,9 @@ s390_irgen_CLHHR(UChar r1, UChar r2) assign(op1, get_gpr_w0(r1)); assign(op2, get_gpr_w0(r2)); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clhhr"; } -static const HChar * +static void s390_irgen_CLHLR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -7324,11 +6209,9 @@ s390_irgen_CLHLR(UChar r1, UChar r2) assign(op1, get_gpr_w0(r1)); assign(op2, get_gpr_w1(r2)); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clhlr"; } -static const HChar * +static void s390_irgen_CLHF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -7337,11 +6220,9 @@ s390_irgen_CLHF(UChar r1, IRTemp op2addr) assign(op1, get_gpr_w0(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clhf"; } -static const HChar * +static void s390_irgen_CLIH(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -7351,21 +6232,15 @@ s390_irgen_CLIH(UChar r1, UInt i2) op2 = i2; s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, mkU32(op2))); - - return "clih"; } -static const HChar * +static void s390_irgen_CPYA(UChar r1, UChar r2) { put_ar_w0(r1, get_ar_w0(r2)); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM("cpya"), AR(r1), AR(r2)); - - return "cpya"; } -static const HChar * +static void s390_irgen_XR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -7381,11 +6256,9 @@ s390_irgen_XR(UChar r1, UChar r2) } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "xr"; } -static const HChar * +static void s390_irgen_XGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -7401,35 +6274,33 @@ s390_irgen_XGR(UChar r1, UChar r2) } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "xgr"; } -static const HChar * +static void s390_irgen_XRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "xrk", Iop_Xor32, False, False); + s390_irgen_logicalK32(r3, r1, r2, Iop_Xor32, False, False); } -static const HChar * +static void s390_irgen_XGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "xgrk", Iop_Xor64, False, False); + s390_irgen_logicalK64(r3, r1, r2, Iop_Xor64, False, False); } -static const HChar * +static void s390_irgen_NXRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "nxrk", Iop_Xor32, False, True); + s390_irgen_logicalK32(r3, r1, r2, Iop_Xor32, False, True); } -static const HChar * +static void s390_irgen_NXGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "nxgrk", Iop_Xor64, False, True); + s390_irgen_logicalK64(r3, r1, r2, Iop_Xor64, False, True); } -static const HChar * +static void s390_irgen_X(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -7441,11 +6312,9 @@ s390_irgen_X(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "x"; } -static const HChar * +static void s390_irgen_XY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -7457,11 +6326,9 @@ s390_irgen_XY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "xy"; } -static const HChar * +static void s390_irgen_XG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -7473,11 +6340,9 @@ s390_irgen_XG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "xg"; } -static const HChar * +static void s390_irgen_XI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -7489,11 +6354,9 @@ s390_irgen_XI(UChar i2, IRTemp op1addr) assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "xi"; } -static const HChar * +static void s390_irgen_XIY(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -7505,11 +6368,9 @@ s390_irgen_XIY(UChar i2, IRTemp op1addr) assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "xiy"; } -static const HChar * +static void s390_irgen_XIHF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -7521,11 +6382,9 @@ s390_irgen_XIHF(UChar r1, UInt i2) assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w0(r1, mkexpr(result)); - - return "xihf"; } -static const HChar * +static void s390_irgen_XILF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -7537,37 +6396,27 @@ s390_irgen_XILF(UChar r1, UInt i2) assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "xilf"; } -static const HChar * +static void s390_irgen_EAR(UChar r1, UChar r2) { put_gpr_w1(r1, get_ar_w0(r2)); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM("ear"), GPR(r1), AR(r2)); - - return "ear"; } -static const HChar * +static void s390_irgen_IC(UChar r1, IRTemp op2addr) { put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr))); - - return "ic"; } -static const HChar * +static void s390_irgen_ICY(UChar r1, IRTemp op2addr) { put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr))); - - return "icy"; } -static const HChar * +static void s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr) { UChar n; @@ -7598,19 +6447,17 @@ s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr) assign(result, get_gpr_w1(r1)); s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, mkU32(mask))); - - return "icm"; } -static const HChar * -s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_ICMY(UChar r1, UChar m3, IRTemp op2addr) { UChar n; IRTemp result = newTemp(Ity_I32); UInt mask; n = 0; - mask = (UInt)r3; + mask = (UInt)m3; if ((mask & 8) != 0) { put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr))); n = n + 1; @@ -7633,19 +6480,17 @@ s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr) assign(result, get_gpr_w1(r1)); s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, mkU32(mask))); - - return "icmy"; } -static const HChar * -s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_ICMH(UChar r1, UChar m3, IRTemp op2addr) { UChar n; IRTemp result = newTemp(Ity_I32); UInt mask; n = 0; - mask = (UInt)r3; + mask = (UInt)m3; if ((mask & 8) != 0) { put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr))); n = n + 1; @@ -7668,184 +6513,138 @@ s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr) assign(result, get_gpr_w0(r1)); s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, mkU32(mask))); - - return "icmh"; } -static const HChar * +static void s390_irgen_IIHF(UChar r1, UInt i2) { put_gpr_w0(r1, mkU32(i2)); - - return "iihf"; } -static const HChar * +static void s390_irgen_IIHH(UChar r1, UShort i2) { put_gpr_hw0(r1, mkU16(i2)); - - return "iihh"; } -static const HChar * +static void s390_irgen_IIHL(UChar r1, UShort i2) { put_gpr_hw1(r1, mkU16(i2)); - - return "iihl"; } -static const HChar * +static void s390_irgen_IILF(UChar r1, UInt i2) { put_gpr_w1(r1, mkU32(i2)); - - return "iilf"; } -static const HChar * +static void s390_irgen_IILH(UChar r1, UShort i2) { put_gpr_hw2(r1, mkU16(i2)); - - return "iilh"; } -static const HChar * +static void s390_irgen_IILL(UChar r1, UShort i2) { put_gpr_hw3(r1, mkU16(i2)); - - return "iill"; } -static const HChar * +static void s390_irgen_LR(UChar r1, UChar r2) { put_gpr_w1(r1, get_gpr_w1(r2)); - - return "lr"; } -static const HChar * +static void s390_irgen_LGR(UChar r1, UChar r2) { put_gpr_dw0(r1, get_gpr_dw0(r2)); - - return "lgr"; } -static const HChar * +static void s390_irgen_LGFR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2))); - - return "lgfr"; } -static const HChar * +static void s390_irgen_L(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); - - return "l"; } -static const HChar * +static void s390_irgen_LY(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); - - return "ly"; } -static const HChar * +static void s390_irgen_LG(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); - - return "lg"; } -static const HChar * +static void s390_irgen_LGF(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); - - return "lgf"; } -static const HChar * +static void s390_irgen_LGFI(UChar r1, UInt i2) { put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2)); - - return "lgfi"; } -static const HChar * +static void s390_irgen_LRL(UChar r1, UInt i2) { put_gpr_w1(r1, load(Ity_I32, mkU64(addr_rel_long(i2)))); - - return "lrl"; } -static const HChar * +static void s390_irgen_LGRL(UChar r1, UInt i2) { put_gpr_dw0(r1, load(Ity_I64, mkU64(addr_rel_long(i2)))); - - return "lgrl"; } -static const HChar * +static void s390_irgen_LGFRL(UChar r1, UInt i2) { put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - - return "lgfrl"; } -static const HChar * +static void s390_irgen_LA(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, mkexpr(op2addr)); - - return "la"; } -static const HChar * +static void s390_irgen_LAY(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, mkexpr(op2addr)); - - return "lay"; } -static const HChar * +static void s390_irgen_LAE(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, mkexpr(op2addr)); - - return "lae"; } -static const HChar * +static void s390_irgen_LAEY(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, mkexpr(op2addr)); - - return "laey"; } -static const HChar * +static void s390_irgen_LARL(UChar r1, UInt i2) { put_gpr_dw0(r1, mkU64(addr_rel_long(i2))); - - return "larl"; } /* The IR representation of LAA and friends is an approximation of what @@ -7981,87 +6780,67 @@ s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op) put_gpr_dw0(r1, mkexpr(old_mem)); } -static const HChar * +static void s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */); - - return "laa"; } -static const HChar * +static void s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */); - - return "laag"; } -static const HChar * +static void s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */); - - return "laal"; } -static const HChar * +static void s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */); - - return "laalg"; } -static const HChar * +static void s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32); - - return "lan"; } -static const HChar * +static void s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64); - - return "lang"; } -static const HChar * +static void s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32); - - return "lax"; } -static const HChar * +static void s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64); - - return "laxg"; } -static const HChar * +static void s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32); - - return "lao"; } -static const HChar * +static void s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64); - - return "laog"; } -static const HChar * +static void s390_irgen_LTR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -8069,11 +6848,9 @@ s390_irgen_LTR(UChar r1, UChar r2) assign(op2, get_gpr_w1(r2)); put_gpr_w1(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "ltr"; } -static const HChar * +static void s390_irgen_LTGR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8081,11 +6858,9 @@ s390_irgen_LTGR(UChar r1, UChar r2) assign(op2, get_gpr_dw0(r2)); put_gpr_dw0(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "ltgr"; } -static const HChar * +static void s390_irgen_LTGFR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8093,11 +6868,9 @@ s390_irgen_LTGFR(UChar r1, UChar r2) assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); put_gpr_dw0(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "ltgfr"; } -static const HChar * +static void s390_irgen_LT(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I32); @@ -8105,11 +6878,9 @@ s390_irgen_LT(UChar r1, IRTemp op2addr) assign(op2, load(Ity_I32, mkexpr(op2addr))); put_gpr_w1(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "lt"; } -static const HChar * +static void s390_irgen_LTG(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I64); @@ -8117,11 +6888,9 @@ s390_irgen_LTG(UChar r1, IRTemp op2addr) assign(op2, load(Ity_I64, mkexpr(op2addr))); put_gpr_dw0(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "ltg"; } -static const HChar * +static void s390_irgen_LTGF(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I64); @@ -8129,51 +6898,39 @@ s390_irgen_LTGF(UChar r1, IRTemp op2addr) assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); put_gpr_dw0(r1, mkexpr(op2)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); - - return "ltgf"; } -static const HChar * +static void s390_irgen_LBR(UChar r1, UChar r2) { put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2))); - - return "lbr"; } -static const HChar * +static void s390_irgen_LGBR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2))); - - return "lgbr"; } -static const HChar * +static void s390_irgen_LB(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr)))); - - return "lb"; } -static const HChar * +static void s390_irgen_LGB(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr)))); - - return "lgb"; } -static const HChar * +static void s390_irgen_LBH(UChar r1, IRTemp op2addr) { put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr)))); - - return "lbh"; } -static const HChar * +static void s390_irgen_LCR(UChar r1, UChar r2) { Int op1; @@ -8186,11 +6943,9 @@ s390_irgen_LCR(UChar r1, UChar r2) put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt) op1)), op2); - - return "lcr"; } -static const HChar * +static void s390_irgen_LCGR(UChar r1, UChar r2) { Long op1; @@ -8203,11 +6958,9 @@ s390_irgen_LCGR(UChar r1, UChar r2) put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong) op1)), op2); - - return "lcgr"; } -static const HChar * +static void s390_irgen_LCGFR(UChar r1, UChar r2) { Long op1; @@ -8220,285 +6973,215 @@ s390_irgen_LCGFR(UChar r1, UChar r2) put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong) op1)), op2); - - return "lcgfr"; } -static const HChar * +static void s390_irgen_LHR(UChar r1, UChar r2) { put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2))); - - return "lhr"; } -static const HChar * +static void s390_irgen_LGHR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2))); - - return "lghr"; } -static const HChar * +static void s390_irgen_LH(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); - - return "lh"; } -static const HChar * +static void s390_irgen_LHY(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); - - return "lhy"; } -static const HChar * +static void s390_irgen_LGH(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); - - return "lgh"; } -static const HChar * +static void s390_irgen_LHI(UChar r1, UShort i2) { put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2)); - - return "lhi"; } -static const HChar * +static void s390_irgen_LGHI(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2)); - - return "lghi"; } -static const HChar * +static void s390_irgen_LHRL(UChar r1, UInt i2) { put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "lhrl"; } -static const HChar * +static void s390_irgen_LGHRL(UChar r1, UInt i2) { put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "lghrl"; } -static const HChar * +static void s390_irgen_LHH(UChar r1, IRTemp op2addr) { put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); - - return "lhh"; } -static const HChar * +static void s390_irgen_LFH(UChar r1, IRTemp op2addr) { put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr))); - - return "lfh"; } -static const HChar * +static void s390_irgen_LLGFR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2))); - - return "llgfr"; } -static const HChar * +static void s390_irgen_LLGF(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); - - return "llgf"; } -static const HChar * +static void s390_irgen_LLGFRL(UChar r1, UInt i2) { put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - - return "llgfrl"; } -static const HChar * +static void s390_irgen_LLCR(UChar r1, UChar r2) { put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2))); - - return "llcr"; } -static const HChar * +static void s390_irgen_LLGCR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2))); - - return "llgcr"; } -static const HChar * +static void s390_irgen_LLC(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); - - return "llc"; } -static const HChar * +static void s390_irgen_LLGC(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr)))); - - return "llgc"; } -static const HChar * +static void s390_irgen_LLCH(UChar r1, IRTemp op2addr) { put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); - - return "llch"; } -static const HChar * +static void s390_irgen_LLHR(UChar r1, UChar r2) { put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2))); - - return "llhr"; } -static const HChar * +static void s390_irgen_LLGHR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2))); - - return "llghr"; } -static const HChar * +static void s390_irgen_LLH(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr)))); - - return "llh"; } -static const HChar * +static void s390_irgen_LLGH(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr)))); - - return "llgh"; } -static const HChar * +static void s390_irgen_LLHRL(UChar r1, UInt i2) { put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "llhrl"; } -static const HChar * +static void s390_irgen_LLGHRL(UChar r1, UInt i2) { put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "llghrl"; } -static const HChar * +static void s390_irgen_LLHH(UChar r1, IRTemp op2addr) { put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr)))); - - return "llhh"; } -static const HChar * +static void s390_irgen_LLIHF(UChar r1, UInt i2) { put_gpr_dw0(r1, mkU64(((ULong)i2) << 32)); - - return "llihf"; } -static const HChar * +static void s390_irgen_LLIHH(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64(((ULong)i2) << 48)); - - return "llihh"; } -static const HChar * +static void s390_irgen_LLIHL(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64(((ULong)i2) << 32)); - - return "llihl"; } -static const HChar * +static void s390_irgen_LLILF(UChar r1, UInt i2) { put_gpr_dw0(r1, mkU64(i2)); - - return "llilf"; } -static const HChar * +static void s390_irgen_LLILH(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64(((ULong)i2) << 16)); - - return "llilh"; } -static const HChar * +static void s390_irgen_LLILL(UChar r1, UShort i2) { put_gpr_dw0(r1, mkU64(i2)); - - return "llill"; } -static const HChar * +static void s390_irgen_LLGTR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2), mkU32(2147483647)))); - - return "llgtr"; } -static const HChar * +static void s390_irgen_LLGT(UChar r1, IRTemp op2addr) { put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(2147483647)))); - - return "llgt"; } -static const HChar * +static void s390_irgen_LNR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -8509,11 +7192,9 @@ s390_irgen_LNR(UChar r1, UChar r2) binop(Iop_Sub32, mkU32(0), mkexpr(op2)))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); - - return "lnr"; } -static const HChar * +static void s390_irgen_LNGR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8524,11 +7205,9 @@ s390_irgen_LNGR(UChar r1, UChar r2) binop(Iop_Sub64, mkU64(0), mkexpr(op2)))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); - - return "lngr"; } -static const HChar * +static void s390_irgen_LNGFR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8539,59 +7218,47 @@ s390_irgen_LNGFR(UChar r1, UChar r2) binop(Iop_Sub64, mkU64(0), mkexpr(op2)))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); - - return "lngfr"; } -static const HChar * +static void s390_irgen_LOCR(UChar m3, UChar r1, UChar r2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_w1(r1, get_gpr_w1(r2)); - - return "locr"; } -static const HChar * +static void s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_dw0(r1, get_gpr_dw0(r2)); - - return "locgr"; } -static const HChar * +static void s390_irgen_LOC(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); - - return "loc"; } -static const HChar * +static void s390_irgen_LOCG(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); - - return "locg"; } -static const HChar * +static void s390_irgen_LPQ(UChar r1, IRTemp op2addr) { - s390_insn_assert("lpq", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8)) )); - - return "lpq"; } -static const HChar * +static void s390_irgen_LPR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -8602,11 +7269,9 @@ s390_irgen_LPR(UChar r1, UChar r2) binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2); - - return "lpr"; } -static const HChar * +static void s390_irgen_LPGR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8617,11 +7282,9 @@ s390_irgen_LPGR(UChar r1, UChar r2) binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2); - - return "lpgr"; } -static const HChar * +static void s390_irgen_LPGFR(UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -8632,11 +7295,9 @@ s390_irgen_LPGFR(UChar r1, UChar r2) binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2); - - return "lpgfr"; } -static const HChar * +static void s390_irgen_LRVR(UChar r1, UChar r2) { IRTemp b0 = newTemp(Ity_I8); @@ -8652,11 +7313,9 @@ s390_irgen_LRVR(UChar r1, UChar r2) put_gpr_b5(r1, mkexpr(b2)); put_gpr_b6(r1, mkexpr(b1)); put_gpr_b7(r1, mkexpr(b0)); - - return "lrvr"; } -static const HChar * +static void s390_irgen_LRVGR(UChar r1, UChar r2) { IRTemp b0 = newTemp(Ity_I8); @@ -8684,11 +7343,9 @@ s390_irgen_LRVGR(UChar r1, UChar r2) put_gpr_b5(r1, mkexpr(b2)); put_gpr_b6(r1, mkexpr(b1)); put_gpr_b7(r1, mkexpr(b0)); - - return "lrvgr"; } -static const HChar * +static void s390_irgen_LRVH(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I16); @@ -8696,11 +7353,9 @@ s390_irgen_LRVH(UChar r1, IRTemp op2addr) assign(op2, load(Ity_I16, mkexpr(op2addr))); put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2))); put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2))); - - return "lrvh"; } -static const HChar * +static void s390_irgen_LRV(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I32); @@ -8713,11 +7368,9 @@ s390_irgen_LRV(UChar r1, IRTemp op2addr) mkU8(16)), mkU32(255)))); put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2), mkU8(24)), mkU32(255)))); - - return "lrv"; } -static const HChar * +static void s390_irgen_LRVG(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I64); @@ -8738,54 +7391,42 @@ s390_irgen_LRVG(UChar r1, IRTemp op2addr) mkU8(48)), mkU64(255)))); put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), mkU8(56)), mkU64(255)))); - - return "lrvg"; } -static const HChar * +static void s390_irgen_MVHHI(UShort i2, IRTemp op1addr) { store(mkexpr(op1addr), mkU16(i2)); - - return "mvhhi"; } -static const HChar * +static void s390_irgen_MVHI(UShort i2, IRTemp op1addr) { store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2)); - - return "mvhi"; } -static const HChar * +static void s390_irgen_MVGHI(UShort i2, IRTemp op1addr) { store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2)); - - return "mvghi"; } -static const HChar * +static void s390_irgen_MVI(UChar i2, IRTemp op1addr) { store(mkexpr(op1addr), mkU8(i2)); - - return "mvi"; } -static const HChar * +static void s390_irgen_MVIY(UChar i2, IRTemp op1addr) { store(mkexpr(op1addr), mkU8(i2)); - - return "mviy"; } -static const HChar * +static void s390_irgen_MR(UChar r1, UChar r2) { - s390_insn_assert("mr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -8796,14 +7437,12 @@ s390_irgen_MR(UChar r1, UChar r2) assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "mr"; } -static const HChar * +static void s390_irgen_M(UChar r1, IRTemp op2addr) { - s390_insn_assert("m", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -8814,14 +7453,12 @@ s390_irgen_M(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "m"; } -static const HChar * +static void s390_irgen_MFY(UChar r1, IRTemp op2addr) { - s390_insn_assert("mfy", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -8832,14 +7469,12 @@ s390_irgen_MFY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "mfy"; } -static const HChar * +static void s390_irgen_MG(UChar r1, IRTemp op2addr) { - s390_insn_assert("mg", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I64); IRTemp op2 = newTemp(Ity_I64); @@ -8850,11 +7485,9 @@ s390_irgen_MG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); - - return "mg"; } -static const HChar * +static void s390_irgen_MGH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -8866,14 +7499,12 @@ s390_irgen_MGH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkexpr(op2)) )); put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "mgh"; } -static const HChar * +static void s390_irgen_MGRK(UChar r3, UChar r1, UChar r2) { - s390_insn_assert("mgrk", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); IRTemp op3 = newTemp(Ity_I64); @@ -8884,11 +7515,9 @@ s390_irgen_MGRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3))); put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); - - return "mgrk"; } -static const HChar * +static void s390_irgen_MH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -8900,11 +7529,9 @@ s390_irgen_MH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2)) )); put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "mh"; } -static const HChar * +static void s390_irgen_MHY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -8916,11 +7543,9 @@ s390_irgen_MHY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2)) )); put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "mhy"; } -static const HChar * +static void s390_irgen_MHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I32); @@ -8932,11 +7557,9 @@ s390_irgen_MHI(UChar r1, UShort i2) assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkU16((UShort)op2)))); put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "mhi"; } -static const HChar * +static void s390_irgen_MGHI(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I64); @@ -8948,14 +7571,12 @@ s390_irgen_MGHI(UChar r1, UShort i2) assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkU16((UShort)op2)))); put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "mghi"; } -static const HChar * +static void s390_irgen_MLR(UChar r1, UChar r2) { - s390_insn_assert("mlr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -8966,14 +7587,12 @@ s390_irgen_MLR(UChar r1, UChar r2) assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "mlr"; } -static const HChar * +static void s390_irgen_MLGR(UChar r1, UChar r2) { - s390_insn_assert("mlgr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I64); IRTemp op2 = newTemp(Ity_I64); @@ -8984,14 +7603,12 @@ s390_irgen_MLGR(UChar r1, UChar r2) assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2))); put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); - - return "mlgr"; } -static const HChar * +static void s390_irgen_ML(UChar r1, IRTemp op2addr) { - s390_insn_assert("ml", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); @@ -9002,14 +7619,12 @@ s390_irgen_ML(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "ml"; } -static const HChar * +static void s390_irgen_MLG(UChar r1, IRTemp op2addr) { - s390_insn_assert("mlg", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op1 = newTemp(Ity_I64); IRTemp op2 = newTemp(Ity_I64); @@ -9020,213 +7635,117 @@ s390_irgen_MLG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2))); put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); - - return "mlg"; } -static const HChar * +static void s390_irgen_MSR(UChar r1, UChar r2) { - IRTemp op1 = newTemp(Ity_I32); - IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I64); - - assign(op1, get_gpr_w1(r1)); - assign(op2, get_gpr_w1(r2)); - assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "msr"; + put_gpr_w1(r1, binop(Iop_Mul32, get_gpr_w1(r1), get_gpr_w1(r2))); } -static const HChar * +static void s390_irgen_MSGR(UChar r1, UChar r2) { - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_I64); - IRTemp result = newTemp(Ity_I128); - - assign(op1, get_gpr_dw0(r1)); - assign(op2, get_gpr_dw0(r2)); - assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgr"; + put_gpr_dw0(r1, binop(Iop_Mul64, get_gpr_dw0(r1), get_gpr_dw0(r2))); } -static const HChar * +static void s390_irgen_MSGFR(UChar r1, UChar r2) { - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I128); - - assign(op1, get_gpr_dw0(r1)); - assign(op2, get_gpr_w1(r2)); - assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2)) - )); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgfr"; + put_gpr_dw0( + r1, binop(Iop_Mul64, get_gpr_dw0(r1), unop(Iop_32Sto64, get_gpr_w1(r2)))); } -static const HChar * +static void s390_irgen_MS(UChar r1, IRTemp op2addr) { - IRTemp op1 = newTemp(Ity_I32); - IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I64); - - assign(op1, get_gpr_w1(r1)); - assign(op2, load(Ity_I32, mkexpr(op2addr))); - assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "ms"; + put_gpr_w1(r1, + binop(Iop_Mul32, get_gpr_w1(r1), load(Ity_I32, mkexpr(op2addr)))); } -static const HChar * +static void s390_irgen_MSC(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I64); assign(op1, get_gpr_w1(r1)); assign(op2, load(Ity_I32, mkexpr(op2addr))); - assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op1, op2); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "msc"; + put_gpr_w1(r1, binop(Iop_Mul32, mkexpr(op1), mkexpr(op2))); } -static const HChar * +static void s390_irgen_MSRKC(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); IRTemp op3 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I64); assign(op2, get_gpr_w1(r2)); assign(op3, get_gpr_w1(r3)); - assign(result, binop(Iop_MullS32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op2, op3); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "msrkc"; + put_gpr_w1(r1, binop(Iop_Mul32, mkexpr(op2), mkexpr(op3))); } -static const HChar * +static void s390_irgen_MSY(UChar r1, IRTemp op2addr) { - IRTemp op1 = newTemp(Ity_I32); - IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I64); - - assign(op1, get_gpr_w1(r1)); - assign(op2, load(Ity_I32, mkexpr(op2addr))); - assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "msy"; + put_gpr_w1(r1, + binop(Iop_Mul32, get_gpr_w1(r1), load(Ity_I32, mkexpr(op2addr)))); } -static const HChar * +static void s390_irgen_MSG(UChar r1, IRTemp op2addr) { - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_I64); - IRTemp result = newTemp(Ity_I128); - - assign(op1, get_gpr_dw0(r1)); - assign(op2, load(Ity_I64, mkexpr(op2addr))); - assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msg"; + put_gpr_dw0(r1, + binop(Iop_Mul64, get_gpr_dw0(r1), load(Ity_I64, mkexpr(op2addr)))); } -static const HChar * +static void s390_irgen_MSGC(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); IRTemp op2 = newTemp(Ity_I64); - IRTemp result = newTemp(Ity_I128); assign(op1, get_gpr_dw0(r1)); assign(op2, load(Ity_I64, mkexpr(op2addr))); - assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op1, op2); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgc"; + put_gpr_dw0(r1, binop(Iop_Mul64, mkexpr(op1), mkexpr(op2))); } -static const HChar * +static void s390_irgen_MSGF(UChar r1, IRTemp op2addr) { - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_I32); - IRTemp result = newTemp(Ity_I128); - - assign(op1, get_gpr_dw0(r1)); - assign(op2, load(Ity_I32, mkexpr(op2addr))); - assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2)) - )); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgf"; + put_gpr_dw0(r1, binop(Iop_Mul64, get_gpr_dw0(r1), + unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))))); } -static const HChar * +static void s390_irgen_MSFI(UChar r1, UInt i2) { - IRTemp op1 = newTemp(Ity_I32); - Int op2; - IRTemp result = newTemp(Ity_I64); - - assign(op1, get_gpr_w1(r1)); - op2 = (Int)i2; - assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2))); - put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); - - return "msfi"; + put_gpr_w1(r1, binop(Iop_Mul32, get_gpr_w1(r1), mkU32(i2))); } -static const HChar * +static void s390_irgen_MSGFI(UChar r1, UInt i2) { - IRTemp op1 = newTemp(Ity_I64); - Int op2; - IRTemp result = newTemp(Ity_I128); - - assign(op1, get_gpr_dw0(r1)); - op2 = (Int)i2; - assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt) - op2)))); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgfi"; + ULong op2 = (ULong)i2 - (((ULong)i2 & (1 << 31)) << 1); + put_gpr_dw0(r1, binop(Iop_Mul64, get_gpr_dw0(r1), mkU64(op2))); } -static const HChar * +static void s390_irgen_MSGRKC(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); IRTemp op3 = newTemp(Ity_I64); - IRTemp result = newTemp(Ity_I128); assign(op2, get_gpr_dw0(r2)); assign(op3, get_gpr_dw0(r3)); - assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op2, op3); - put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); - - return "msgrkc"; + put_gpr_dw0(r1, binop(Iop_Mul64, mkexpr(op2), mkexpr(op3))); } -static const HChar * +static void s390_irgen_OR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -9238,11 +7757,9 @@ s390_irgen_OR(UChar r1, UChar r2) assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "or"; } -static const HChar * +static void s390_irgen_OGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -9254,47 +7771,45 @@ s390_irgen_OGR(UChar r1, UChar r2) assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "ogr"; } -static const HChar * +static void s390_irgen_ORK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "ork", Iop_Or32, False, False); + s390_irgen_logicalK32(r3, r1, r2, Iop_Or32, False, False); } -static const HChar * +static void s390_irgen_OGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "ogrk", Iop_Or64, False, False); + s390_irgen_logicalK64(r3, r1, r2, Iop_Or64, False, False); } -static const HChar * +static void s390_irgen_OCRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "ocrk", Iop_Or32, True, False); + s390_irgen_logicalK32(r3, r1, r2, Iop_Or32, True, False); } -static const HChar * +static void s390_irgen_OCGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "ocgrk", Iop_Or64, True, False); + s390_irgen_logicalK64(r3, r1, r2, Iop_Or64, True, False); } -static const HChar * +static void s390_irgen_NORK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK32(r3, r1, r2, "nork", Iop_Or32, False, True); + s390_irgen_logicalK32(r3, r1, r2, Iop_Or32, False, True); } -static const HChar * +static void s390_irgen_NOGRK(UChar r3, UChar r1, UChar r2) { - return s390_irgen_logicalK64(r3, r1, r2, "nogrk", Iop_Or64, False, True); + s390_irgen_logicalK64(r3, r1, r2, Iop_Or64, False, True); } -static const HChar * +static void s390_irgen_O(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -9306,11 +7821,9 @@ s390_irgen_O(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "o"; } -static const HChar * +static void s390_irgen_OY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -9322,11 +7835,9 @@ s390_irgen_OY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "oy"; } -static const HChar * +static void s390_irgen_OG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -9338,11 +7849,9 @@ s390_irgen_OG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_dw0(r1, mkexpr(result)); - - return "og"; } -static const HChar * +static void s390_irgen_OI(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -9354,11 +7863,9 @@ s390_irgen_OI(UChar i2, IRTemp op1addr) assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "oi"; } -static const HChar * +static void s390_irgen_OIY(UChar i2, IRTemp op1addr) { IRTemp op1 = newTemp(Ity_I8); @@ -9370,11 +7877,9 @@ s390_irgen_OIY(UChar i2, IRTemp op1addr) assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); store(mkexpr(op1addr), mkexpr(result)); - - return "oiy"; } -static const HChar * +static void s390_irgen_OIHF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -9386,11 +7891,9 @@ s390_irgen_OIHF(UChar r1, UInt i2) assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w0(r1, mkexpr(result)); - - return "oihf"; } -static const HChar * +static void s390_irgen_OIHH(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -9402,11 +7905,9 @@ s390_irgen_OIHH(UChar r1, UShort i2) assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw0(r1, mkexpr(result)); - - return "oihh"; } -static const HChar * +static void s390_irgen_OIHL(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -9418,11 +7919,9 @@ s390_irgen_OIHL(UChar r1, UShort i2) assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw1(r1, mkexpr(result)); - - return "oihl"; } -static const HChar * +static void s390_irgen_OILF(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -9434,11 +7933,9 @@ s390_irgen_OILF(UChar r1, UInt i2) assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_w1(r1, mkexpr(result)); - - return "oilf"; } -static const HChar * +static void s390_irgen_OILH(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -9450,11 +7947,9 @@ s390_irgen_OILH(UChar r1, UShort i2) assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw2(r1, mkexpr(result)); - - return "oilh"; } -static const HChar * +static void s390_irgen_OILL(UChar r1, UShort i2) { IRTemp op1 = newTemp(Ity_I16); @@ -9466,22 +7961,18 @@ s390_irgen_OILL(UChar r1, UShort i2) assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2))); s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); put_gpr_hw3(r1, mkexpr(result)); - - return "oill"; } -static const HChar * +static void s390_irgen_PFD(void) { - - return "pfd"; + /* Treat as a no-op */ } -static const HChar * +static void s390_irgen_PFDRL(void) { - - return "pfdrl"; + /* Treat as a no-op */ } static IRExpr * @@ -9539,14 +8030,9 @@ s390_call_pfpo_helper(IRExpr *gr0) return call; } -static const HChar * +static void s390_irgen_PFPO(void) { - if (! s390_host_has_pfpo) { - emulation_failure(EmFail_S390X_pfpo); - return "pfpo"; - } - IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */ IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */ IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */ @@ -9765,11 +8251,9 @@ s390_irgen_PFPO(void) put_gpr_w1(1, mkU32(0x0)); s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0); next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128))); - - return "pfpo"; } -static const HChar * +static void s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr) { IRTemp amount = newTemp(Ity_I64); @@ -9780,11 +8264,9 @@ s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr) put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8, mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_Sub64, mkU64(32), mkexpr(amount)))))); - - return "rll"; } -static const HChar * +static void s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp amount = newTemp(Ity_I64); @@ -9795,11 +8277,9 @@ s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr) put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8, mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_Sub64, mkU64(64), mkexpr(amount)))))); - - return "rllg"; } -static const HChar * +static void s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { UChar from; @@ -9834,11 +8314,9 @@ s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) mkU64(maskc)), mkexpr(result))); } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); - - return "rnsbg"; } -static const HChar * +static void s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { UChar from; @@ -9873,11 +8351,9 @@ s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) mkU64(maskc)), mkexpr(result))); } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); - - return "rxsbg"; } -static const HChar * +static void s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { UChar from; @@ -9912,11 +8388,9 @@ s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) mkU64(maskc)), mkexpr(result))); } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); - - return "rosbg"; } -static const HChar * +static void s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5, Bool set_cc) { @@ -9954,22 +8428,19 @@ s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5, assign(result, get_gpr_dw0(r1)); if (set_cc) { s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result); - return "risbg"; - } - - return "risbgn"; + } } -static const HChar * +static void s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { - return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True); + s390_irgen_RISBGx(r1, r2, i3, i4, i5, True); } -static const HChar * +static void s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { - return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False); + s390_irgen_RISBGx(r1, r2, i3, i4, i5, False); } static IRExpr * @@ -10017,34 +8488,28 @@ s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5, binop(Iop_And32, mkexpr(op2), mkU32(mask))); } -static const HChar * +static void s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True)); - return "risbhg"; } -static const HChar * +static void s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) { put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False)); - return "risblg"; } -static const HChar * +static void s390_irgen_SAR(UChar r1, UChar r2) { put_ar_w0(r1, get_gpr_w1(r2)); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM("sar"), AR(r1), GPR(r2)); - - return "sar"; } -static const HChar * +static void s390_irgen_SLDA(UChar r1, IRTemp op2addr) { - s390_insn_assert("slda", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp p1 = newTemp(Ity_I64); IRTemp p2 = newTemp(Ity_I64); @@ -10065,14 +8530,12 @@ s390_irgen_SLDA(UChar r1, IRTemp op2addr) put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount); - - return "slda"; } -static const HChar * +static void s390_irgen_SLDL(UChar r1, IRTemp op2addr) { - s390_insn_assert("sldl", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp p1 = newTemp(Ity_I64); IRTemp p2 = newTemp(Ity_I64); @@ -10085,11 +8548,9 @@ s390_irgen_SLDL(UChar r1, IRTemp op2addr) mkexpr(op2addr), mkU64(63))))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "sldl"; } -static const HChar * +static void s390_irgen_SLA(UChar r1, IRTemp op2addr) { IRTemp uop = newTemp(Ity_I32); @@ -10107,11 +8568,9 @@ s390_irgen_SLA(UChar r1, IRTemp op2addr) binop(Iop_And32, mkexpr(uop), mkU32(sign_mask)))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount); - - return "sla"; } -static const HChar * +static void s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr) { IRTemp uop = newTemp(Ity_I32); @@ -10129,11 +8588,9 @@ s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr) binop(Iop_And32, mkexpr(uop), mkU32(sign_mask)))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount); - - return "slak"; } -static const HChar * +static void s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp uop = newTemp(Ity_I64); @@ -10151,41 +8608,33 @@ s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr) binop(Iop_And64, mkexpr(uop), mkU64(sign_mask)))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount); - - return "slag"; } -static const HChar * +static void s390_irgen_SLL(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "sll"; } -static const HChar * +static void s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr) { put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "sllk"; } -static const HChar * +static void s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr) { put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "sllg"; } -static const HChar * +static void s390_irgen_SRDA(UChar r1, IRTemp op2addr) { - s390_insn_assert("srda", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp p1 = newTemp(Ity_I64); IRTemp p2 = newTemp(Ity_I64); @@ -10199,14 +8648,12 @@ s390_irgen_SRDA(UChar r1, IRTemp op2addr) put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result); - - return "srda"; } -static const HChar * +static void s390_irgen_SRDL(UChar r1, IRTemp op2addr) { - s390_insn_assert("srdl", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp p1 = newTemp(Ity_I64); IRTemp p2 = newTemp(Ity_I64); @@ -10219,11 +8666,9 @@ s390_irgen_SRDL(UChar r1, IRTemp op2addr) mkexpr(op2addr), mkU64(63))))); put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); - - return "srdl"; } -static const HChar * +static void s390_irgen_SRA(UChar r1, IRTemp op2addr) { IRTemp result = newTemp(Ity_I32); @@ -10234,11 +8679,9 @@ s390_irgen_SRA(UChar r1, IRTemp op2addr) mkexpr(op2addr), mkU64(63))))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result); - - return "sra"; } -static const HChar * +static void s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr) { IRTemp result = newTemp(Ity_I32); @@ -10249,11 +8692,9 @@ s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr) mkexpr(op2addr), mkU64(63))))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result); - - return "srak"; } -static const HChar * +static void s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp result = newTemp(Ity_I64); @@ -10264,11 +8705,9 @@ s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr) mkexpr(op2addr), mkU64(63))))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result); - - return "srag"; } -static const HChar * +static void s390_irgen_SRL(UChar r1, IRTemp op2addr) { IRTemp op = newTemp(Ity_I32); @@ -10276,11 +8715,9 @@ s390_irgen_SRL(UChar r1, IRTemp op2addr) assign(op, get_gpr_w1(r1)); put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "srl"; } -static const HChar * +static void s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr) { IRTemp op = newTemp(Ity_I32); @@ -10288,11 +8725,9 @@ s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr) assign(op, get_gpr_w1(r3)); put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "srlk"; } -static const HChar * +static void s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr) { IRTemp op = newTemp(Ity_I64); @@ -10300,75 +8735,57 @@ s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr) assign(op, get_gpr_dw0(r3)); put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(63))))); - - return "srlg"; } -static const HChar * +static void s390_irgen_ST(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_w1(r1)); - - return "st"; } -static const HChar * +static void s390_irgen_STY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_w1(r1)); - - return "sty"; } -static const HChar * +static void s390_irgen_STG(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_dw0(r1)); - - return "stg"; } -static const HChar * +static void s390_irgen_STRL(UChar r1, UInt i2) { store(mkU64(addr_rel_long(i2)), get_gpr_w1(r1)); - - return "strl"; } -static const HChar * +static void s390_irgen_STGRL(UChar r1, UInt i2) { store(mkU64(addr_rel_long(i2)), get_gpr_dw0(r1)); - - return "stgrl"; } -static const HChar * +static void s390_irgen_STC(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b7(r1)); - - return "stc"; } -static const HChar * +static void s390_irgen_STCY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b7(r1)); - - return "stcy"; } -static const HChar * +static void s390_irgen_STCH(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b3(r1)); - - return "stch"; } -static const HChar * +static void s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr) { UChar mask; @@ -10391,17 +8808,15 @@ s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr) if ((mask & 1) != 0) { store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1)); } - - return "stcm"; } -static const HChar * -s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_STCMY(UChar r1, UChar m3, IRTemp op2addr) { UChar mask; UChar n; - mask = (UChar)r3; + mask = (UChar)m3; n = 0; if ((mask & 8) != 0) { store(mkexpr(op2addr), get_gpr_b4(r1)); @@ -10418,17 +8833,15 @@ s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr) if ((mask & 1) != 0) { store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1)); } - - return "stcmy"; } -static const HChar * -s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr) +static void +s390_irgen_STCMH(UChar r1, UChar m3, IRTemp op2addr) { UChar mask; UChar n; - mask = (UChar)r3; + mask = (UChar)m3; n = 0; if ((mask & 8) != 0) { store(mkexpr(op2addr), get_gpr_b0(r1)); @@ -10445,100 +8858,78 @@ s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr) if ((mask & 1) != 0) { store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1)); } - - return "stcmh"; } -static const HChar * +static void s390_irgen_STH(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_hw3(r1)); - - return "sth"; } -static const HChar * +static void s390_irgen_STHY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_hw3(r1)); - - return "sthy"; } -static const HChar * +static void s390_irgen_STHRL(UChar r1, UInt i2) { store(mkU64(addr_rel_long(i2)), get_gpr_hw3(r1)); - - return "sthrl"; } -static const HChar * +static void s390_irgen_STHH(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_hw1(r1)); - - return "sthh"; } -static const HChar * +static void s390_irgen_STFH(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_w0(r1)); - - return "stfh"; } -static const HChar * +static void s390_irgen_STOC(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ store(mkexpr(op2addr), get_gpr_w1(r1)); - - return "stoc"; } -static const HChar * +static void s390_irgen_STOCG(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ store(mkexpr(op2addr), get_gpr_dw0(r1)); - - return "stocg"; } -static const HChar * +static void s390_irgen_STPQ(UChar r1, IRTemp op2addr) { - s390_insn_assert("stpq", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); store(mkexpr(op2addr), get_gpr_dw0(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1)); - - return "stpq"; } -static const HChar * +static void s390_irgen_STRVH(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b7(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1)); - - return "strvh"; } -static const HChar * +static void s390_irgen_STRV(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b7(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1)); - - return "strv"; } -static const HChar * +static void s390_irgen_STRVG(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_gpr_b7(r1)); @@ -10549,11 +8940,9 @@ s390_irgen_STRVG(UChar r1, IRTemp op2addr) store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1)); store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1)); - - return "strvg"; } -static const HChar * +static void s390_irgen_SR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -10565,11 +8954,9 @@ s390_irgen_SR(UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "sr"; } -static const HChar * +static void s390_irgen_SGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -10581,11 +8968,9 @@ s390_irgen_SGR(UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "sgr"; } -static const HChar * +static void s390_irgen_SGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -10597,11 +8982,9 @@ s390_irgen_SGFR(UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "sgfr"; } -static const HChar * +static void s390_irgen_SRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10613,11 +8996,9 @@ s390_irgen_SRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3); put_gpr_w1(r1, mkexpr(result)); - - return "srk"; } -static const HChar * +static void s390_irgen_SGRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -10629,11 +9010,9 @@ s390_irgen_SGRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3); put_gpr_dw0(r1, mkexpr(result)); - - return "sgrk"; } -static const HChar * +static void s390_irgen_S(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10645,11 +9024,9 @@ s390_irgen_S(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "s"; } -static const HChar * +static void s390_irgen_SY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10661,11 +9038,9 @@ s390_irgen_SY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "sy"; } -static const HChar * +static void s390_irgen_SG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -10677,11 +9052,9 @@ s390_irgen_SG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "sg"; } -static const HChar * +static void s390_irgen_SGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -10693,11 +9066,9 @@ s390_irgen_SGF(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "sgf"; } -static const HChar * +static void s390_irgen_SGH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -10709,11 +9080,9 @@ s390_irgen_SGH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "sgh"; } -static const HChar * +static void s390_irgen_SH(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10725,11 +9094,9 @@ s390_irgen_SH(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "sh"; } -static const HChar * +static void s390_irgen_SHY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10741,11 +9108,9 @@ s390_irgen_SHY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "shy"; } -static const HChar * +static void s390_irgen_SHHHR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10757,11 +9122,9 @@ s390_irgen_SHHHR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "shhhr"; } -static const HChar * +static void s390_irgen_SHHLR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10773,11 +9136,9 @@ s390_irgen_SHHLR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "shhlr"; } -static const HChar * +static void s390_irgen_SLR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -10789,11 +9150,9 @@ s390_irgen_SLR(UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "slr"; } -static const HChar * +static void s390_irgen_SLGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -10805,11 +9164,9 @@ s390_irgen_SLGR(UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "slgr"; } -static const HChar * +static void s390_irgen_SLGFR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -10821,11 +9178,9 @@ s390_irgen_SLGFR(UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "slgfr"; } -static const HChar * +static void s390_irgen_SLRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10837,11 +9192,9 @@ s390_irgen_SLRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3); put_gpr_w1(r1, mkexpr(result)); - - return "slrk"; } -static const HChar * +static void s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I64); @@ -10853,11 +9206,9 @@ s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3); put_gpr_dw0(r1, mkexpr(result)); - - return "slgrk"; } -static const HChar * +static void s390_irgen_SL(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10869,11 +9220,9 @@ s390_irgen_SL(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "sl"; } -static const HChar * +static void s390_irgen_SLY(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -10885,11 +9234,9 @@ s390_irgen_SLY(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2); put_gpr_w1(r1, mkexpr(result)); - - return "sly"; } -static const HChar * +static void s390_irgen_SLG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -10901,11 +9248,9 @@ s390_irgen_SLG(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "slg"; } -static const HChar * +static void s390_irgen_SLGF(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -10917,11 +9262,9 @@ s390_irgen_SLGF(UChar r1, IRTemp op2addr) assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2); put_gpr_dw0(r1, mkexpr(result)); - - return "slgf"; } -static const HChar * +static void s390_irgen_SLFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I32); @@ -10934,11 +9277,9 @@ s390_irgen_SLFI(UChar r1, UInt i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32, mkU32(op2))); put_gpr_w1(r1, mkexpr(result)); - - return "slfi"; } -static const HChar * +static void s390_irgen_SLGFI(UChar r1, UInt i2) { IRTemp op1 = newTemp(Ity_I64); @@ -10951,11 +9292,9 @@ s390_irgen_SLGFI(UChar r1, UInt i2) s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64, mkU64(op2))); put_gpr_dw0(r1, mkexpr(result)); - - return "slgfi"; } -static const HChar * +static void s390_irgen_SLHHHR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10967,11 +9306,9 @@ s390_irgen_SLHHHR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "slhhhr"; } -static const HChar * +static void s390_irgen_SLHHLR(UChar r3, UChar r1, UChar r2) { IRTemp op2 = newTemp(Ity_I32); @@ -10983,11 +9320,9 @@ s390_irgen_SLHHLR(UChar r3, UChar r1, UChar r2) assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3))); s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3); put_gpr_w0(r1, mkexpr(result)); - - return "slhhlr"; } -static const HChar * +static void s390_irgen_SLBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I32); @@ -11003,11 +9338,9 @@ s390_irgen_SLBR(UChar r1, UChar r2) mkexpr(borrow_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in); put_gpr_w1(r1, mkexpr(result)); - - return "slbr"; } -static const HChar * +static void s390_irgen_SLBGR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_I64); @@ -11023,11 +9356,9 @@ s390_irgen_SLBGR(UChar r1, UChar r2) mkexpr(borrow_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in); put_gpr_dw0(r1, mkexpr(result)); - - return "slbgr"; } -static const HChar * +static void s390_irgen_SLB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I32); @@ -11043,11 +9374,9 @@ s390_irgen_SLB(UChar r1, IRTemp op2addr) mkexpr(borrow_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in); put_gpr_w1(r1, mkexpr(result)); - - return "slb"; } -static const HChar * +static void s390_irgen_SLBG(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_I64); @@ -11063,11 +9392,9 @@ s390_irgen_SLBG(UChar r1, IRTemp op2addr) mkexpr(borrow_in))); s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in); put_gpr_dw0(r1, mkexpr(result)); - - return "slbg"; } -static const HChar * +static void s390_irgen_SVC(UChar i) { IRTemp sysno = newTemp(Ity_I64); @@ -11078,39 +9405,36 @@ s390_irgen_SVC(UChar i) assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1))); } system_call(mkexpr(sysno)); - - return "svc"; } -static const HChar * -s390_irgen_TMx(const HChar *mnem, UChar mask, IRTemp op1addr) +static void +s390_irgen_TMx(UChar mask, IRTemp op1addr) { IRTemp masked = newTemp(Ity_I8); assign(masked, binop(Iop_And8, load(Ity_I8, mkexpr(op1addr)), mkU8(mask))); s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, masked, mktemp(Ity_I8, mkU8(mask))); - return mnem; } -static const HChar * +static void s390_irgen_TM(UChar i2, IRTemp op1addr) { - return s390_irgen_TMx("tm", i2, op1addr); + s390_irgen_TMx(i2, op1addr); } -static const HChar * +static void s390_irgen_TMY(UChar i2, IRTemp op1addr) { - return s390_irgen_TMx("tmy", i2, op1addr); + s390_irgen_TMx( i2, op1addr); } -static const HChar * -s390_irgen_TMxx(const HChar *mnem, UChar r1, UShort mask, UChar offs) +static void +s390_irgen_TMxx(UChar r1, UShort mask, UChar offs) { if (mask == 0) { s390_cc_set_val(0); - return mnem; + return; } IRExpr* masked; @@ -11127,180 +9451,146 @@ s390_irgen_TMxx(const HChar *mnem, UChar r1, UShort mask, UChar offs) mktemp(Ity_I64, masked), mktemp(Ity_I64, mkU64(mask))); } - return mnem; } -static const HChar * +static void s390_irgen_TMHH(UChar r1, UShort i2) { - return s390_irgen_TMxx("tmhh", r1, i2, 48); + s390_irgen_TMxx( r1, i2, 48); } -static const HChar * +static void s390_irgen_TMHL(UChar r1, UShort i2) { - return s390_irgen_TMxx("tmhl", r1, i2, 32); + s390_irgen_TMxx(r1, i2, 32); } -static const HChar * +static void s390_irgen_TMLH(UChar r1, UShort i2) { - return s390_irgen_TMxx("tmlh", r1, i2, 16); + s390_irgen_TMxx(r1, i2, 16); } -static const HChar * +static void s390_irgen_TMLL(UChar r1, UShort i2) { - return s390_irgen_TMxx("tmll", r1, i2, 0); + s390_irgen_TMxx(r1, i2, 0); } -static const HChar * +static void s390_irgen_EFPC(UChar r1) { put_gpr_w1(r1, get_fpc_w0()); - - return "efpc"; } -static const HChar * +static void s390_irgen_LER(UChar r1, UChar r2) { put_fpr_w0(r1, get_fpr_w0(r2)); - - return "ler"; } -static const HChar * +static void s390_irgen_LDR(UChar r1, UChar r2) { put_fpr_dw0(r1, get_fpr_dw0(r2)); - - return "ldr"; } -static const HChar * +static void s390_irgen_LDER(UChar r1, UChar r2) { put_fpr_dw0(r1, mkF64i(0x0)); put_fpr_w0(r1, get_fpr_w0(r2)); - - return "lder"; } -static const HChar * +static void s390_irgen_LXR(UChar r1, UChar r2) { - s390_insn_assert("lxr", is_valid_fpr_pair(r1)); - s390_insn_assert("lxr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); put_fpr_dw0(r1, get_fpr_dw0(r2)); put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2)); - - return "lxr"; } -static const HChar * +static void s390_irgen_LE(UChar r1, IRTemp op2addr) { put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr))); - - return "le"; } -static const HChar * +static void s390_irgen_LD(UChar r1, IRTemp op2addr) { put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr))); - - return "ld"; } -static const HChar * +static void s390_irgen_LDE(UChar r1, IRTemp op2addr) { put_fpr_dw0(r1, mkF64i(0x0)); put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr))); - - return "lde"; } -static const HChar * +static void s390_irgen_LEY(UChar r1, IRTemp op2addr) { put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr))); - - return "ley"; } -static const HChar * +static void s390_irgen_LDY(UChar r1, IRTemp op2addr) { put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr))); - - return "ldy"; } -static const HChar * +static void s390_irgen_LFPC(IRTemp op2addr) { put_fpc_w0(load(Ity_I32, mkexpr(op2addr))); - - return "lfpc"; } -static const HChar * +static void s390_irgen_LZER(UChar r1) { put_fpr_w0(r1, mkF32i(0x0)); - - return "lzer"; } -static const HChar * +static void s390_irgen_LZDR(UChar r1) { put_fpr_dw0(r1, mkF64i(0x0)); - - return "lzdr"; } -static const HChar * +static void s390_irgen_LZXR(UChar r1) { - s390_insn_assert("lzxr", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); put_fpr_dw0(r1, mkF64i(0x0)); put_fpr_dw0(r1 + 2, mkF64i(0x0)); - - return "lzxr"; } -static const HChar * +static void s390_irgen_SRNM(IRTemp op2addr) { UInt input_mask, fpc_mask; input_mask = 3; - fpc_mask = s390_host_has_fpext ? 7 : 3; + fpc_mask = 7; put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)), binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(input_mask)))); - return "srnm"; } -static const HChar * +static void s390_irgen_SRNMB(UChar b2, UShort d2) { /* Can only check at IR generation time when b2 == 0 */ if (b2 == 0) { - s390_insn_assert("srnmb", d2 <= 3 || d2 == 7); // valid rounding mode - /* d2 == 7 requires fpext */ - if (d2 == 7 && ! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - return "srnmb"; - } + d2 &= 0xff; // d2[0:55] is ignored + s390_insn_assert(d2 <= 3 || d2 == 7); // valid rounding mode } IRTemp op2addr = newTemp(Ity_I64); @@ -11314,12 +9604,11 @@ s390_irgen_SRNMB(UChar b2, UShort d2) binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)), binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(input_mask)))); - return "srnmb"; } /* All 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */ -static const HChar * +static void s390_irgen_SRNMT(IRTemp op2addr) { UInt input_mask, fpc_mask; @@ -11333,59 +9622,46 @@ s390_irgen_SRNMT(IRTemp op2addr) binop(Iop_Shl32, binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(input_mask)), mkU8(4)))); - return "srnmt"; } -static const HChar * +static void s390_irgen_SFPC(UChar r1) { put_fpc_w0(get_gpr_w1(r1)); - - return "sfpc"; } -static const HChar * +static void s390_irgen_STE(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_fpr_w0(r1)); - - return "ste"; } -static const HChar * +static void s390_irgen_STD(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_fpr_dw0(r1)); - - return "std"; } -static const HChar * +static void s390_irgen_STEY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_fpr_w0(r1)); - - return "stey"; } -static const HChar * +static void s390_irgen_STDY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), get_fpr_dw0(r1)); - - return "stdy"; } -static const HChar * +static void s390_irgen_STFPC(IRTemp op2addr) { store(mkexpr(op2addr), get_fpc_w0()); - - return "stfpc"; } -static const HChar * +static void s390_irgen_AEBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F32); @@ -11399,11 +9675,9 @@ s390_irgen_AEBR(UChar r1, UChar r2) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); put_fpr_w0(r1, mkexpr(result)); - - return "aebr"; } -static const HChar * +static void s390_irgen_ADBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F64); @@ -11417,11 +9691,9 @@ s390_irgen_ADBR(UChar r1, UChar r2) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); put_fpr_dw0(r1, mkexpr(result)); - - return "adbr"; } -static const HChar * +static void s390_irgen_AEB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F32); @@ -11435,11 +9707,9 @@ s390_irgen_AEB(UChar r1, IRTemp op2addr) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); put_fpr_w0(r1, mkexpr(result)); - - return "aeb"; } -static const HChar * +static void s390_irgen_ADB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F64); @@ -11453,258 +9723,193 @@ s390_irgen_ADB(UChar r1, IRTemp op2addr) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); put_fpr_dw0(r1, mkexpr(result)); - - return "adb"; } -static const HChar * +static void s390_irgen_CEFBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("cefbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp op2 = newTemp(Ity_I32); assign(op2, get_gpr_w1(r2)); put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)), mkexpr(op2))); - - return "cefbra"; } -static const HChar * +static void s390_irgen_CDFBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cdfbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op2 = newTemp(Ity_I32); assign(op2, get_gpr_w1(r2)); put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2))); - - return "cdfbra"; } -static const HChar * +static void s390_irgen_CEGBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("cegbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp op2 = newTemp(Ity_I64); assign(op2, get_gpr_dw0(r2)); put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)), mkexpr(op2))); - - return "cegbra"; } -static const HChar * +static void s390_irgen_CDGBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("cdgbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp op2 = newTemp(Ity_I64); assign(op2, get_gpr_dw0(r2)); put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)), mkexpr(op2))); - - return "cdgbra"; } -static const HChar * +static void s390_irgen_CELFBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("celfbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)), - mkexpr(op2))); - } - return "celfbr"; + assign(op2, get_gpr_w1(r2)); + put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)), + mkexpr(op2))); } -static const HChar * +static void s390_irgen_CDLFBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cdlfbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2))); - } - return "cdlfbr"; + assign(op2, get_gpr_w1(r2)); + put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CELGBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("celgbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)), - mkexpr(op2))); - } - return "celgbr"; + assign(op2, get_gpr_dw0(r2)); + put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)), + mkexpr(op2))); } -static const HChar * +static void s390_irgen_CDLGBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cdlgbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_fpr_dw0(r1, binop(Iop_I64UtoF64, - mkexpr(encode_bfp_rounding_mode(m3)), - mkexpr(op2))); - } - return "cdlgbr"; + assign(op2, get_gpr_dw0(r2)); + put_fpr_dw0(r1, binop(Iop_I64UtoF64, + mkexpr(encode_bfp_rounding_mode(m3)), + mkexpr(op2))); } -static const HChar * +static void s390_irgen_CLFEBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clfebr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F32); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F32); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_w0(r2)); - assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode); - } - return "clfebr"; + assign(op, get_fpr_w0(r2)); + assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLFDBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clfdbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F64); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F64); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_dw0(r2)); - assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode); - } - return "clfdbr"; + assign(op, get_fpr_dw0(r2)); + assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLGEBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clgebr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F32); - IRTemp result = newTemp(Ity_I64); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F32); + IRTemp result = newTemp(Ity_I64); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_w0(r2)); - assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode); - } - return "clgebr"; + assign(op, get_fpr_w0(r2)); + assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLGDBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clgdbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F64); - IRTemp result = newTemp(Ity_I64); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F64); + IRTemp result = newTemp(Ity_I64); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_dw0(r2)); - assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode); - } - return "clgdbr"; + assign(op, get_fpr_dw0(r2)); + assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode), + mkexpr(op))); + put_gpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_CFEBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cfebra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F32); @@ -11716,15 +9921,13 @@ s390_irgen_CFEBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode); - - return "cfebra"; } -static const HChar * +static void s390_irgen_CFDBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cfdbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F64); @@ -11736,15 +9939,13 @@ s390_irgen_CFDBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode); - - return "cfdbra"; } -static const HChar * +static void s390_irgen_CGEBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cgebra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F32); @@ -11756,15 +9957,13 @@ s390_irgen_CGEBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode); - - return "cgebra"; } -static const HChar * +static void s390_irgen_CGDBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cgdbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F64); @@ -11776,11 +9975,9 @@ s390_irgen_CGDBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode); - - return "cgdbra"; } -static const HChar * +static void s390_irgen_DEBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F32); @@ -11793,11 +9990,9 @@ s390_irgen_DEBR(UChar r1, UChar r2) assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_w0(r1, mkexpr(result)); - - return "debr"; } -static const HChar * +static void s390_irgen_DDBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F64); @@ -11810,11 +10005,9 @@ s390_irgen_DDBR(UChar r1, UChar r2) assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_dw0(r1, mkexpr(result)); - - return "ddbr"; } -static const HChar * +static void s390_irgen_DEB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F32); @@ -11827,11 +10020,9 @@ s390_irgen_DEB(UChar r1, IRTemp op2addr) assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_w0(r1, mkexpr(result)); - - return "deb"; } -static const HChar * +static void s390_irgen_DDB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F64); @@ -11844,11 +10035,9 @@ s390_irgen_DDB(UChar r1, IRTemp op2addr) assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_dw0(r1, mkexpr(result)); - - return "ddb"; } -static const HChar * +static void s390_irgen_LTEBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F32); @@ -11856,11 +10045,9 @@ s390_irgen_LTEBR(UChar r1, UChar r2) assign(result, get_fpr_w0(r2)); put_fpr_w0(r1, mkexpr(result)); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); - - return "ltebr"; } -static const HChar * +static void s390_irgen_LTDBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); @@ -11868,11 +10055,9 @@ s390_irgen_LTDBR(UChar r1, UChar r2) assign(result, get_fpr_dw0(r2)); put_fpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); - - return "ltdbr"; } -static const HChar * +static void s390_irgen_LCEBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F32); @@ -11880,11 +10065,9 @@ s390_irgen_LCEBR(UChar r1, UChar r2) assign(result, unop(Iop_NegF32, get_fpr_w0(r2))); put_fpr_w0(r1, mkexpr(result)); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); - - return "lcebr"; } -static const HChar * +static void s390_irgen_LCDBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); @@ -11892,53 +10075,41 @@ s390_irgen_LCDBR(UChar r1, UChar r2) assign(result, unop(Iop_NegF64, get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); - - return "lcdbr"; } -static const HChar * +static void s390_irgen_LDEBR(UChar r1, UChar r2) { IRTemp op = newTemp(Ity_F32); assign(op, get_fpr_w0(r2)); put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op))); - - return "ldebr"; } -static const HChar * +static void s390_irgen_LDEB(UChar r1, IRTemp op2addr) { IRTemp op = newTemp(Ity_F32); assign(op, load(Ity_F32, mkexpr(op2addr))); put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op))); - - return "ldeb"; } -static const HChar * +static void s390_irgen_LEDBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("ledbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp op = newTemp(Ity_F64); assign(op, get_fpr_dw0(r2)); put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)), mkexpr(op))); - - return "ledbra"; } -static const HChar * +static void s390_irgen_MEEBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F32); @@ -11952,11 +10123,9 @@ s390_irgen_MEEBR(UChar r1, UChar r2) assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_w0(r1, mkexpr(result)); - - return "meebr"; } -static const HChar * +static void s390_irgen_MDBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F64); @@ -11969,11 +10138,9 @@ s390_irgen_MDBR(UChar r1, UChar r2) assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_dw0(r1, mkexpr(result)); - - return "mdbr"; } -static const HChar * +static void s390_irgen_MEEB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F32); @@ -11986,11 +10153,9 @@ s390_irgen_MEEB(UChar r1, IRTemp op2addr) assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_w0(r1, mkexpr(result)); - - return "meeb"; } -static const HChar * +static void s390_irgen_MDB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F64); @@ -12003,11 +10168,9 @@ s390_irgen_MDB(UChar r1, IRTemp op2addr) assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_dw0(r1, mkexpr(result)); - - return "mdb"; } -static const HChar * +static void s390_irgen_SEBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F32); @@ -12021,11 +10184,9 @@ s390_irgen_SEBR(UChar r1, UChar r2) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); put_fpr_w0(r1, mkexpr(result)); - - return "sebr"; } -static const HChar * +static void s390_irgen_SDBR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_F64); @@ -12039,11 +10200,9 @@ s390_irgen_SDBR(UChar r1, UChar r2) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); put_fpr_dw0(r1, mkexpr(result)); - - return "sdbr"; } -static const HChar * +static void s390_irgen_SEB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F32); @@ -12057,11 +10216,9 @@ s390_irgen_SEB(UChar r1, IRTemp op2addr) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result); put_fpr_w0(r1, mkexpr(result)); - - return "seb"; } -static const HChar * +static void s390_irgen_SDB(UChar r1, IRTemp op2addr) { IRTemp op1 = newTemp(Ity_F64); @@ -12075,70 +10232,48 @@ s390_irgen_SDB(UChar r1, IRTemp op2addr) mkexpr(op2))); s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result); put_fpr_dw0(r1, mkexpr(result)); - - return "sdb"; } -static const HChar * +static void s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); - put_dpr_dw0(r1, mkexpr(result)); - } - return "adtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("axtra", is_valid_fpr_pair(r1)); - s390_insn_assert("axtra", is_valid_fpr_pair(r2)); - s390_insn_assert("axtra", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_pair(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; - s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); - } - return "axtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_pair(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); + + s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); } -static const HChar * +static void s390_irgen_CDTR(UChar r1, UChar r2) { IRTemp op1 = newTemp(Ity_D64); @@ -12152,15 +10287,13 @@ s390_irgen_CDTR(UChar r1, UChar r2) assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - - return "cdtr"; } -static const HChar * +static void s390_irgen_CXTR(UChar r1, UChar r2) { - s390_insn_assert("cxtr", is_valid_fpr_pair(r1)); - s390_insn_assert("cxtr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp op1 = newTemp(Ity_D128); IRTemp op2 = newTemp(Ity_D128); @@ -12173,1091 +10306,703 @@ s390_irgen_CXTR(UChar r1, UChar r2) assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - - return "cxtr"; } -static const HChar * +static void s390_irgen_CDFTR(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2))); - } - return "cdftr"; + assign(op2, get_gpr_w1(r2)); + put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CXFTR(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("cxftr", is_valid_fpr_pair(r1)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2))); - } - return "cxftr"; + assign(op2, get_gpr_w1(r2)); + put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CDGTRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op2 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); - if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_DFP_ROUND_PER_FPC_0; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - assign(op2, get_gpr_dw0(r2)); - put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)), - mkexpr(op2))); - } - return "cdgtra"; + assign(op2, get_gpr_dw0(r2)); + put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)), + mkexpr(op2))); } -static const HChar * +static void s390_irgen_CXGTRA(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("cxgtra", is_valid_fpr_pair(r1)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - - IRTemp op2 = newTemp(Ity_I64); + s390_insn_assert(is_valid_fpr_pair(r1)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - /* No emulation warning here about an non-zero m3 on hosts without - floating point extension facility. No rounding is performed */ + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2))); - } - return "cxgtra"; + assign(op2, get_gpr_dw0(r2)); + put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CDLFTR(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2))); - } - } - return "cdlftr"; + assign(op2, get_gpr_w1(r2)); + put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CXLFTR(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cxlftr", is_valid_fpr_pair(r1)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2))); - } - } - return "cxlftr"; + assign(op2, get_gpr_w1(r2)); + put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CDLGTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I64); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_dpr_dw0(r1, binop(Iop_I64UtoD64, - mkexpr(encode_dfp_rounding_mode(m3)), - mkexpr(op2))); - } - } - return "cdlgtr"; + assign(op2, get_gpr_dw0(r2)); + put_dpr_dw0(r1, binop(Iop_I64UtoD64, + mkexpr(encode_dfp_rounding_mode(m3)), mkexpr(op2))); } -static const HChar * +static void s390_irgen_CXLGTR(UChar m3 __attribute__((unused)), UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cxlgtr", is_valid_fpr_pair(r1)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2))); - } - } - return "cxlgtr"; + assign(op2, get_gpr_dw0(r2)); + put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CFDTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_dw0(r2)); - assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode); - } - } - return "cfdtr"; + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_dw0(r2)); + assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CFXTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cfxtr", is_valid_fpr_pair(r2)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - - IRTemp op = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_pair(r2)); - assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, - rounding_mode); - } - } - return "cfxtr"; + s390_insn_assert(is_valid_fpr_pair(r2)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + + IRTemp op = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_pair(r2)); + assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CGDTRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D64); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_dw0(r2)); - put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op))); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode); - } - } - return "cgdtra"; + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op = newTemp(Ity_D64); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_dw0(r2)); + put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op))); + s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_CGXTRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cgxtra", is_valid_fpr_pair(r2)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r2)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D128); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_D128); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - assign(op, get_dpr_pair(r2)); - put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op))); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode); - } - } - return "cgxtra"; + assign(op, get_dpr_pair(r2)); + put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op))); + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_CEDTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp cc_vex = newTemp(Ity_I32); - IRTemp cc_s390 = newTemp(Ity_I32); + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp cc_vex = newTemp(Ity_I32); + IRTemp cc_s390 = newTemp(Ity_I32); - assign(op1, get_dpr_dw0(r1)); - assign(op2, get_dpr_dw0(r2)); - assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2))); + assign(op1, get_dpr_dw0(r1)); + assign(op2, get_dpr_dw0(r2)); + assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); - s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - } - return "cedtr"; + assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); + s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); } -static const HChar * +static void s390_irgen_CEXTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("cextr", is_valid_fpr_pair(r1)); - s390_insn_assert("cextr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp cc_vex = newTemp(Ity_I32); - IRTemp cc_s390 = newTemp(Ity_I32); + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp cc_vex = newTemp(Ity_I32); + IRTemp cc_s390 = newTemp(Ity_I32); - assign(op1, get_dpr_pair(r1)); - assign(op2, get_dpr_pair(r2)); - assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2))); + assign(op1, get_dpr_pair(r1)); + assign(op2, get_dpr_pair(r2)); + assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); - s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - } - return "cextr"; + assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); + s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); } -static const HChar * +static void s390_irgen_CLFDTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_dw0(r2)); - assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode); - } - } - return "clfdtr"; + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_dw0(r2)); + assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLFXTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clfxtr", is_valid_fpr_pair(r2)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - - IRTemp op = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_pair(r2)); - assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, - rounding_mode); - } - } - return "clfxtr"; + s390_insn_assert(is_valid_fpr_pair(r2)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + + IRTemp op = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_pair(r2)); + assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLGDTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_I64); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_dw0(r2)); - assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode); - } - } - return "clgdtr"; + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_I64); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_dw0(r2)); + assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_CLGXTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clgxtr", is_valid_fpr_pair(r2)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - - IRTemp op = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_I64); - IRTemp rounding_mode = encode_dfp_rounding_mode(m3); - - assign(op, get_dpr_pair(r2)); - assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op, - rounding_mode); - } - } - return "clgxtr"; + s390_insn_assert(is_valid_fpr_pair(r2)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + + IRTemp op = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_I64); + IRTemp rounding_mode = encode_dfp_rounding_mode(m3); + + assign(op, get_dpr_pair(r2)); + assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode), mkexpr(op))); + put_gpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op, rounding_mode); } -static const HChar * +static void s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "ddtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("dxtra", is_valid_fpr_pair(r1)); - s390_insn_assert("dxtra", is_valid_fpr_pair(r2)); - s390_insn_assert("dxtra", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_pair(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); - } - return "dxtra"; + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; + + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_pair(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_EEDTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2))); - } - return "eedtr"; + put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2))); } -static const HChar * +static void s390_irgen_EEXTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("eextr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r2)); - put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2))); - } - return "eextr"; + put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2))); } -static const HChar * +static void s390_irgen_ESDTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2))); - } - return "esdtr"; + put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2))); } -static const HChar * +static void s390_irgen_ESXTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("esxtr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r2)); - put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2))); - } - return "esxtr"; + put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2))); } -static const HChar * +static void s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); - assign(op1, get_gpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "iedtr"; + assign(op1, get_gpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("iextr", is_valid_fpr_pair(r1)); - s390_insn_assert("iextr", is_valid_fpr_pair(r3)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r3)); - IRTemp op1 = newTemp(Ity_I64); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); - assign(op1, get_gpr_dw0(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); - } - return "iextr"; + assign(op1, get_gpr_dw0(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_LDETR(UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if ((m4 & 0x8) != 0) - emulation_warning(EmWarn_S390X_XiC_not_zero); - IRTemp op = newTemp(Ity_D32); + if ((m4 & 0x8) != 0) + emulation_warning(EmWarn_S390X_XiC_not_zero); + IRTemp op = newTemp(Ity_D32); - assign(op, get_dpr_w0(r2)); - put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op))); - } - return "ldetr"; + assign(op, get_dpr_w0(r2)); + put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op))); } -static const HChar * +static void s390_irgen_LXDTR(UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - if ((m4 & 0x8) != 0) - emulation_warning(EmWarn_S390X_XiC_not_zero); - s390_insn_assert("lxdtr", is_valid_fpr_pair(r1)); + if ((m4 & 0x8) != 0) + emulation_warning(EmWarn_S390X_XiC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); - IRTemp op = newTemp(Ity_D64); + IRTemp op = newTemp(Ity_D64); - assign(op, get_dpr_dw0(r2)); - put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op))); - } - return "lxdtr"; + assign(op, get_dpr_dw0(r2)); + put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op))); } -static const HChar * +static void s390_irgen_LDXTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("ldxtr", is_valid_fpr_pair(r1)); - s390_insn_assert("ldxtr", is_valid_fpr_pair(r2)); - - /* If fpext is not installed and m3 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m3 > 0 && m3 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_DFP_ROUND_PER_FPC_0; - } - if ((m4 & 0x8) != 0) - emulation_warning(EmWarn_S390X_XiC_not_zero); - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp result = newTemp(Ity_D64); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); - assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)), - get_dpr_pair(r2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "ldxtr"; + if ((m4 & 0x8) != 0) + emulation_warning(EmWarn_S390X_XiC_not_zero); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp result = newTemp(Ity_D64); + + assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)), + get_dpr_pair(r2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_LEDTR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - /* If fpext is not installed and m3 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m3 > 0 && m3 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_DFP_ROUND_PER_FPC_0; - } - if ((m4 & 0x8) != 0) - emulation_warning(EmWarn_S390X_XiC_not_zero); - if (s390_host_has_fpext && (m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_D64); + if ((m4 & 0x8) != 0) + emulation_warning(EmWarn_S390X_XiC_not_zero); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); + IRTemp op = newTemp(Ity_D64); - assign(op, get_dpr_dw0(r2)); - put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)), - mkexpr(op))); - } - return "ledtr"; + assign(op, get_dpr_dw0(r2)); + put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)), + mkexpr(op))); } -static const HChar * +static void s390_irgen_LTDTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp result = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); - assign(result, get_dpr_dw0(r2)); - put_dpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); - } - return "ltdtr"; + assign(result, get_dpr_dw0(r2)); + put_dpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); } -static const HChar * +static void s390_irgen_LTXTR(UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("ltxtr", is_valid_fpr_pair(r1)); - s390_insn_assert("ltxtr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); - IRTemp result = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); - assign(result, get_dpr_pair(r2)); - put_dpr_pair(r1, mkexpr(result)); - s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); - } - return "ltxtr"; + assign(result, get_dpr_pair(r2)); + put_dpr_pair(r1, mkexpr(result)); + s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); } -static const HChar * +static void s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "mdtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("mxtra", is_valid_fpr_pair(r1)); - s390_insn_assert("mxtra", is_valid_fpr_pair(r2)); - s390_insn_assert("mxtra", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_pair(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); - } - return "mxtra"; + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; + + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_pair(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - /* If fpext is not installed and m4 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m4 > 0 && m4 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "qadtr"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("qaxtr", is_valid_fpr_pair(r1)); - s390_insn_assert("qaxtr", is_valid_fpr_pair(r2)); - s390_insn_assert("qaxtr", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - /* If fpext is not installed and m4 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m4 > 0 && m4 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_pair(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); - } - return "qaxtr"; + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; + + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_pair(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_I8); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - /* If fpext is not installed and m4 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m4 > 0 && m4 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_I8); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_gpr_b7(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode), - mkexpr(op1), mkexpr(op2))); - put_dpr_dw0(r1, mkexpr(result)); - } - return "rrdtr"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_gpr_b7(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode), + mkexpr(op1), mkexpr(op2))); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("rrxtr", is_valid_fpr_pair(r1)); - s390_insn_assert("rrxtr", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_I8); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - /* If fpext is not installed and m4 is in 1:7, - rounding mode performed is unpredictable */ - if (! s390_host_has_fpext && m4 > 0 && m4 < 8) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_gpr_b7(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode), - mkexpr(op1), mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); - } - return "rrxtr"; + IRTemp op1 = newTemp(Ity_I8); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; + + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_gpr_b7(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode), + mkexpr(op1), mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op1 = newTemp(Ity_D64); - IRTemp op2 = newTemp(Ity_D64); - IRTemp result = newTemp(Ity_D64); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + IRTemp op1 = newTemp(Ity_D64); + IRTemp op2 = newTemp(Ity_D64); + IRTemp result = newTemp(Ity_D64); + IRTemp rounding_mode; - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_dw0(r2)); - assign(op2, get_dpr_dw0(r3)); - assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); - put_dpr_dw0(r1, mkexpr(result)); - } - return "sdtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_dw0(r2)); + assign(op2, get_dpr_dw0(r3)); + assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result); + put_dpr_dw0(r1, mkexpr(result)); } -static const HChar * +static void s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("sxtra", is_valid_fpr_pair(r1)); - s390_insn_assert("sxtra", is_valid_fpr_pair(r2)); - s390_insn_assert("sxtra", is_valid_fpr_pair(r3)); - - IRTemp op1 = newTemp(Ity_D128); - IRTemp op2 = newTemp(Ity_D128); - IRTemp result = newTemp(Ity_D128); - IRTemp rounding_mode; - - if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m4 = S390_DFP_ROUND_PER_FPC_0; - } + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r3)); - rounding_mode = encode_dfp_rounding_mode(m4); - assign(op1, get_dpr_pair(r2)); - assign(op2, get_dpr_pair(r3)); - assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1), - mkexpr(op2))); - put_dpr_pair(r1, mkexpr(result)); + IRTemp op1 = newTemp(Ity_D128); + IRTemp op2 = newTemp(Ity_D128); + IRTemp result = newTemp(Ity_D128); + IRTemp rounding_mode; - s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); - } - return "sxtra"; + rounding_mode = encode_dfp_rounding_mode(m4); + assign(op1, get_dpr_pair(r2)); + assign(op2, get_dpr_pair(r3)); + assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1), + mkexpr(op2))); + put_dpr_pair(r1, mkexpr(result)); + s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result); } -static const HChar * +static void s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op = newTemp(Ity_D64); + IRTemp op = newTemp(Ity_D64); - assign(op, get_dpr_dw0(r3)); - put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), - unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), - mkU64(63))))); - } - return "sldt"; + assign(op, get_dpr_dw0(r3)); + put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), + unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), + mkU64(63))))); } -static const HChar * +static void s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("slxt", is_valid_fpr_pair(r1)); - s390_insn_assert("slxt", is_valid_fpr_pair(r3)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r3)); - IRTemp op = newTemp(Ity_D128); + IRTemp op = newTemp(Ity_D128); - assign(op, get_dpr_pair(r3)); - put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), - unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), - mkU64(63))))); - } - return "slxt"; + assign(op, get_dpr_pair(r3)); + put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), + unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), + mkU64(63))))); } -static const HChar * +static void s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp op = newTemp(Ity_D64); + IRTemp op = newTemp(Ity_D64); - assign(op, get_dpr_dw0(r3)); - put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), - unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), - mkU64(63))))); - } - return "srdt"; + assign(op, get_dpr_dw0(r3)); + put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), + unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), + mkU64(63))))); } -static const HChar * +static void s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("srxt", is_valid_fpr_pair(r1)); - s390_insn_assert("srxt", is_valid_fpr_pair(r3)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r3)); - IRTemp op = newTemp(Ity_D128); + IRTemp op = newTemp(Ity_D128); - assign(op, get_dpr_pair(r3)); - put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), - unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), - mkU64(63))))); - } - return "srxt"; + assign(op, get_dpr_pair(r3)); + put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), + unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), + mkU64(63))))); } -static const HChar * +static void s390_irgen_TDCET(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp value = newTemp(Ity_D32); + IRTemp value = newTemp(Ity_D32); - assign(value, get_dpr_w0(r1)); + assign(value, get_dpr_w0(r1)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr); - } - return "tdcet"; + s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr); } -static const HChar * +static void s390_irgen_TDCDT(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp value = newTemp(Ity_D64); + IRTemp value = newTemp(Ity_D64); - assign(value, get_dpr_dw0(r1)); + assign(value, get_dpr_dw0(r1)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr); - } - return "tdcdt"; + s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr); } -static const HChar * +static void s390_irgen_TDCXT(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("tdcxt", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); - IRTemp value = newTemp(Ity_D128); + IRTemp value = newTemp(Ity_D128); - assign(value, get_dpr_pair(r1)); + assign(value, get_dpr_pair(r1)); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr); - } - return "tdcxt"; + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr); } -static const HChar * +static void s390_irgen_TDGET(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp value = newTemp(Ity_D32); + IRTemp value = newTemp(Ity_D32); - assign(value, get_dpr_w0(r1)); + assign(value, get_dpr_w0(r1)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr); - } - return "tdget"; + s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr); } -static const HChar * +static void s390_irgen_TDGDT(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - IRTemp value = newTemp(Ity_D64); + IRTemp value = newTemp(Ity_D64); - assign(value, get_dpr_dw0(r1)); + assign(value, get_dpr_dw0(r1)); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr); - } - return "tdgdt"; + s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr); } -static const HChar * +static void s390_irgen_TDGXT(UChar r1, IRTemp op2addr) { - if (! s390_host_has_dfp) { - emulation_failure(EmFail_S390X_DFP_insn); - } else { - s390_insn_assert("tdgxt", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); - IRTemp value = newTemp(Ity_D128); + IRTemp value = newTemp(Ity_D128); - assign(value, get_dpr_pair(r1)); + assign(value, get_dpr_pair(r1)); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr); - } - return "tdgxt"; + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr); } -static const HChar * +static void s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2) { IRType ty; @@ -13282,14 +11027,13 @@ s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2) assign(len, mkU64(length)); s390_irgen_CLC_EX(len, start1, start2); } - return "clc"; } -static const HChar * +static void s390_irgen_CLCL(UChar r1, UChar r2) { - s390_insn_assert("clcl", is_valid_gpr_pair(r1)); - s390_insn_assert("clcl", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -13364,15 +11108,13 @@ s390_irgen_CLCL(UChar r1, UChar r2) binop(Iop_Sub32, mkexpr(r2p1), mkU32(1)))); iterate(); - - return "clcl"; } -static const HChar * +static void s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2) { - s390_insn_assert("clcle", is_valid_gpr_pair(r1)); - s390_insn_assert("clcle", is_valid_gpr_pair(r3)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r3)); IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3; @@ -13441,8 +11183,6 @@ s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2) mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1)))); iterate(); - - return "clcle"; } @@ -13580,18 +11320,18 @@ s390_irgen_EX_SS(UChar r, IRTemp addr2, IRTemp torun, restart_if(mkexpr(cond)); ovl = last_execute_target; - assign(start1, binop(Iop_Add64, mkU64(SS_d1(ovl)), - SS_b1(ovl) != 0 ? get_gpr_dw0(SS_b1(ovl)) : mkU64(0))); - assign(start2, binop(Iop_Add64, mkU64(SS_d2(ovl)), - SS_b2(ovl) != 0 ? get_gpr_dw0(SS_b2(ovl)) : mkU64(0))); + assign(start1, binop(Iop_Add64, mkU64(SSa_d1(ovl)), + SSa_b1(ovl) != 0 ? get_gpr_dw0(SSa_b1(ovl)) : mkU64(0))); + assign(start2, binop(Iop_Add64, mkU64(SSa_d2(ovl)), + SSa_b2(ovl) != 0 ? get_gpr_dw0(SSa_b2(ovl)) : mkU64(0))); assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8, - r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(SS_l(ovl))))); + r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(SSa_l(ovl))))); irgen(len, start1, start2); last_execute_target = Invalid_execute_target; } -static const HChar * +static void s390_irgen_EX(UChar r1, IRTemp addr2) { IRTemp insn0, unmodified_insn; @@ -13630,44 +11370,44 @@ s390_irgen_EX(UChar r1, IRTemp addr2) put_IA(mkaddr_expr(guest_IA_next_instr)); dis_res->whatNext = Dis_StopHere; dis_res->jk_StopHere = Ijk_InvalICache; - return "ex"; + return; } switch (last_execute_target & 0xff00000000000000ULL) { case 0xd200000000000000ULL: /* special case MVC */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_MVC_EX, 64); - return "ex@mvc"; + return; case 0xd500000000000000ULL: /* special case CLC */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_CLC_EX, 64); - return "ex@clc"; + return; case 0xd700000000000000ULL: /* special case XC */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_XC_EX, 32); - return "ex@xc"; + return; case 0xd600000000000000ULL: /* special case OC */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_OC_EX, 32); - return "ex@oc"; + return; case 0xd400000000000000ULL: /* special case NC */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_NC_EX, 32); - return "ex@nc"; + return; case 0xdc00000000000000ULL: /* special case TR */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_TR_EX, 64); - return "ex@tr"; + return; case 0xe800000000000000ULL: /* special case MVCIN */ s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_MVCIN_EX, 64); - return "ex@mvcin"; + return; default: { @@ -13713,16 +11453,13 @@ s390_irgen_EX(UChar r1, IRTemp addr2) bytes = (UChar *) &last_execute_target; s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1, dis_res); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - vex_printf(" which was executed by\n"); /* dont make useless translations in the next execute */ last_execute_target = Invalid_execute_target; } } - return "ex"; } -static const HChar * +static void s390_irgen_EXRL(UChar r1, UInt offset) { IRTemp addr = newTemp(Ity_I64); @@ -13742,21 +11479,18 @@ s390_irgen_EXRL(UChar r1, UInt offset) bytes_addr = guest_IA_rel_base; assign(addr, mkU64(bytes_addr)); s390_irgen_EX(r1, addr); - return "exrl"; } -static const HChar * +static void s390_irgen_IPM(UChar r1) { // As long as we dont support SPM, lets just assume 0 as program mask put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */), binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4))))); - - return "ipm"; } -static const HChar * +static void s390_irgen_SRST(UChar r1, UChar r2) { IRTemp address = newTemp(Ity_I64); @@ -13790,11 +11524,9 @@ s390_irgen_SRST(UChar r1, UChar r2) put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1))); iterate(); - - return "srst"; } -static const HChar * +static void s390_irgen_CLST(UChar r1, UChar r2) { IRTemp address1 = newTemp(Ity_I64); @@ -13848,8 +11580,6 @@ s390_irgen_CLST(UChar r1, UChar r2) put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1))); iterate(); - - return "clst"; } static void @@ -13871,23 +11601,19 @@ s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr) } while (reg != (r3 + 1)); } -static const HChar * +static void s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_multiple_32bit(r1, r3, op2addr); - - return "lm"; } -static const HChar * +static void s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_multiple_32bit(r1, r3, op2addr); - - return "lmy"; } -static const HChar * +static void s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr) { UChar reg; @@ -13904,11 +11630,9 @@ s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr) assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4))); reg++; } while (reg != (r3 + 1)); - - return "lmh"; } -static const HChar * +static void s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr) { UChar reg; @@ -13925,8 +11649,6 @@ s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr) assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8))); reg++; } while (reg != (r3 + 1)); - - return "lmg"; } static void @@ -13948,23 +11670,19 @@ s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr) } while( reg != (r3 + 1)); } -static const HChar * +static void s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_store_multiple_32bit(r1, r3, op2addr); - - return "stm"; } -static const HChar * +static void s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_store_multiple_32bit(r1, r3, op2addr); - - return "stmy"; } -static const HChar * +static void s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr) { UChar reg; @@ -13981,11 +11699,9 @@ s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr) assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4))); reg++; } while( reg != (r3 + 1)); - - return "stmh"; } -static const HChar * +static void s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr) { UChar reg; @@ -14002,8 +11718,6 @@ s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr) assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8))); reg++; } while( reg != (r3 + 1)); - - return "stmg"; } static void @@ -14043,15 +11757,13 @@ s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2) put_counter_dw0(mkU64(0)); } -static const HChar * +static void s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I32); assign(len, mkU32(length)); s390_irgen_xonc(Iop_Xor8, len, start1, start2); - - return "xc"; } static void @@ -14087,57 +11799,46 @@ s390_irgen_XC_sameloc(UChar length, UChar b, UShort d) } s390_cc_set_val(0); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM("xc"), UDLB(d, length, b), UDXB(d, 0, b)); } -static const HChar * +static void s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I32); assign(len, mkU32(length)); s390_irgen_xonc(Iop_And8, len, start1, start2); - - return "nc"; } -static const HChar * +static void s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I32); assign(len, mkU32(length)); s390_irgen_xonc(Iop_Or8, len, start1, start2); - - return "oc"; } -static const HChar * +static void s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I64); assign(len, mkU64(length)); s390_irgen_MVC_EX(len, start1, start2); - - return "mvc"; } -static const HChar * +static void s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I64); assign(len, mkU64(length)); s390_irgen_MVCIN_EX(len, start1, start2); - - return "mvcin"; } -static const HChar * +static void s390_irgen_MVCRL(IRTemp op1addr, IRTemp op2addr) { IRTemp counter = newTemp(Ity_I64); @@ -14158,15 +11859,13 @@ s390_irgen_MVCRL(IRTemp op1addr, IRTemp op2addr) put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1))); iterate_if(binop(Iop_CmpNE64, mkexpr(offset), mkU64(0))); put_counter_dw0(mkU64(0)); - - return "mvcrl"; } -static const HChar * +static void s390_irgen_MVCL(UChar r1, UChar r2) { - s390_insn_assert("mvcl", is_valid_gpr_pair(r1)); - s390_insn_assert("mvcl", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -14243,16 +11942,14 @@ s390_irgen_MVCL(UChar r1, UChar r2) s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False); iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1))); - - return "mvcl"; } -static const HChar * +static void s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2) { - s390_insn_assert("mvcle", is_valid_gpr_pair(r1)); - s390_insn_assert("mvcle", is_valid_gpr_pair(r3)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r3)); IRTemp addr1, addr3, addr3_load, len1, len3, single; @@ -14300,11 +11997,9 @@ s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2) s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False); iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1))); - - return "mvcle"; } -static const HChar * +static void s390_irgen_MVST(UChar r1, UChar r2) { IRTemp addr1 = newTemp(Ity_I64); @@ -14328,8 +12023,6 @@ s390_irgen_MVST(UChar r1, UChar r2) s390_cc_set_val(1); put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter))); put_counter_dw0(mkU64(0)); - - return "mvst"; } static void @@ -14372,144 +12065,124 @@ s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2) put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient } -static const HChar * +static void s390_irgen_DR(UChar r1, UChar r2) { - s390_insn_assert("dr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I32); assign(op2, get_gpr_w1(r2)); s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2); - - return "dr"; } -static const HChar * +static void s390_irgen_D(UChar r1, IRTemp op2addr) { - s390_insn_assert("d", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I32); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2); - - return "d"; } -static const HChar * +static void s390_irgen_DLR(UChar r1, UChar r2) { - s390_insn_assert("dlr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I32); assign(op2, get_gpr_w1(r2)); s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2); - - return "dlr"; } -static const HChar * +static void s390_irgen_DL(UChar r1, IRTemp op2addr) { - s390_insn_assert("dl", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I32); assign(op2, load(Ity_I32, mkexpr(op2addr))); s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2); - - return "dl"; } -static const HChar * +static void s390_irgen_DLG(UChar r1, IRTemp op2addr) { - s390_insn_assert("dlg", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, load(Ity_I64, mkexpr(op2addr))); s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2); - - return "dlg"; } -static const HChar * +static void s390_irgen_DLGR(UChar r1, UChar r2) { - s390_insn_assert("dlgr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, get_gpr_dw0(r2)); s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2); - - return "dlgr"; } -static const HChar * +static void s390_irgen_DSGR(UChar r1, UChar r2) { - s390_insn_assert("dsgr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, get_gpr_dw0(r2)); s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2); - - return "dsgr"; } -static const HChar * +static void s390_irgen_DSG(UChar r1, IRTemp op2addr) { - s390_insn_assert("dsg", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, load(Ity_I64, mkexpr(op2addr))); s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2); - - return "dsg"; } -static const HChar * +static void s390_irgen_DSGFR(UChar r1, UChar r2) { - s390_insn_assert("dsgfr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2); - - return "dsgfr"; } -static const HChar * +static void s390_irgen_DSGF(UChar r1, IRTemp op2addr) { - s390_insn_assert("dsgf", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp op2 = newTemp(Ity_I64); assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2); - - return "dsgf"; } static void @@ -14531,20 +12204,16 @@ s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr) } while (reg != (r3 + 1)); } -static const HChar * +static void s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_ar_multiple(r1, r3, op2addr); - - return "lam"; } -static const HChar * +static void s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_load_ar_multiple(r1, r3, op2addr); - - return "lamy"; } static void @@ -14566,20 +12235,16 @@ s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr) } while (reg != (r3 + 1)); } -static const HChar * +static void s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_store_ar_multiple(r1, r3, op2addr); - - return "stam"; } -static const HChar * +static void s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_store_ar_multiple(r1, r3, op2addr); - - return "stamy"; } @@ -14614,23 +12279,19 @@ s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr) yield_if(mkexpr(nequal)); } -static const HChar * +static void s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_cas_32(r1, r3, op2addr); - - return "cs"; } -static const HChar * +static void s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr) { s390_irgen_cas_32(r1, r3, op2addr); - - return "csy"; } -static const HChar * +static void s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr) { IRCAS *cas; @@ -14658,8 +12319,6 @@ s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr) Otherwise, store the old_value from memory in r1 and yield. */ put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1))); yield_if(mkexpr(nequal)); - - return "csg"; } /* Implementation for 32-bit compare-double-and-swap */ @@ -14705,31 +12364,27 @@ s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr) yield_if(mkexpr(nequal)); } -static const HChar * +static void s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr) { - s390_insn_assert("cds", is_valid_gpr_pair(r1)); - s390_insn_assert("cds", is_valid_gpr_pair(r3)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r3)); s390_irgen_cdas_32(r1, r3, op2addr); - - return "cds"; } -static const HChar * +static void s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr) { - s390_insn_assert("cdsy", is_valid_gpr_pair(r1)); - s390_insn_assert("cdsy", is_valid_gpr_pair(r3)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r3)); s390_irgen_cdas_32(r1, r3, op2addr); - - return "cdsy"; } -static const HChar * +static void s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr) { - s390_insn_assert("cdsg", is_valid_gpr_pair(r1)); - s390_insn_assert("cdsg", is_valid_gpr_pair(r3)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r3)); IRCAS *cas; IRTemp op1_high = newTemp(Ity_I64); @@ -14770,18 +12425,16 @@ s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr) put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high))); put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low))); yield_if(mkexpr(nequal)); - - return "cdsg"; } /* Binary floating point */ -static const HChar * +static void s390_irgen_AXBR(UChar r1, UChar r2) { - s390_insn_assert("axbr", is_valid_fpr_pair(r1)); - s390_insn_assert("axbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp op1 = newTemp(Ity_F128); IRTemp op2 = newTemp(Ity_F128); @@ -14795,14 +12448,12 @@ s390_irgen_AXBR(UChar r1, UChar r2) put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "axbr"; } /* Helper for "compare" insns CEBR, CDBR, CXBR, and their signalling counterparts. */ -static const HChar * -s390_irgen_CxBR(const HChar *mnem, UChar r1, UChar r2, IRType type, IROp cmp_op) +static void +s390_irgen_CxBR(UChar r1, UChar r2, IRType type, IROp cmp_op) { IRTemp op1 = newTemp(type); IRTemp op2 = newTemp(type); @@ -14815,54 +12466,53 @@ s390_irgen_CxBR(const HChar *mnem, UChar r1, UChar r2, IRType type, IROp cmp_op) assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - return mnem; } -static const HChar * +static void s390_irgen_CEBR(UChar r1, UChar r2) { - return s390_irgen_CxBR("cebr", r1, r2, Ity_F32, Iop_CmpF32); + s390_irgen_CxBR(r1, r2, Ity_F32, Iop_CmpF32); } -static const HChar * +static void s390_irgen_KEBR(UChar r1, UChar r2) { - return s390_irgen_CxBR("kebr", r1, r2, Ity_F32, Iop_CmpF32); + s390_irgen_CxBR(r1, r2, Ity_F32, Iop_CmpF32); } -static const HChar * +static void s390_irgen_CDBR(UChar r1, UChar r2) { - return s390_irgen_CxBR("cdbr", r1, r2, Ity_F64, Iop_CmpF64); + s390_irgen_CxBR(r1, r2, Ity_F64, Iop_CmpF64); } -static const HChar * +static void s390_irgen_KDBR(UChar r1, UChar r2) { - return s390_irgen_CxBR("kdbr", r1, r2, Ity_F64, Iop_CmpF64); + s390_irgen_CxBR(r1, r2, Ity_F64, Iop_CmpF64); } -static const HChar * +static void s390_irgen_CXBR(UChar r1, UChar r2) { - s390_insn_assert("cxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("cxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); - return s390_irgen_CxBR("cxbr", r1, r2, Ity_F128, Iop_CmpF128); + s390_irgen_CxBR(r1, r2, Ity_F128, Iop_CmpF128); } -static const HChar * +static void s390_irgen_KXBR(UChar r1, UChar r2) { - s390_insn_assert("kxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("kxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); - return s390_irgen_CxBR("kxbr", r1, r2, Ity_F128, Iop_CmpF128); + s390_irgen_CxBR(r1, r2, Ity_F128, Iop_CmpF128); } /* Helper for "compare" insns CEB, CDB, and their signalling counterparts. */ -static const HChar * -s390_irgen_CxB(const HChar *mnem, UChar r1, IRTemp op2addr, IRType type, +static void +s390_irgen_CxB(UChar r1, IRTemp op2addr, IRType type, IROp cmp_op) { IRTemp op1 = newTemp(type); @@ -14876,110 +12526,95 @@ s390_irgen_CxB(const HChar *mnem, UChar r1, IRTemp op2addr, IRType type, assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - return mnem; } -static const HChar * +static void s390_irgen_CEB(UChar r1, IRTemp op2addr) { - return s390_irgen_CxB("ceb", r1, op2addr, Ity_F32, Iop_CmpF32); + s390_irgen_CxB(r1, op2addr, Ity_F32, Iop_CmpF32); } -static const HChar * +static void s390_irgen_KEB(UChar r1, IRTemp op2addr) { - return s390_irgen_CxB("keb", r1, op2addr, Ity_F32, Iop_CmpF32); + s390_irgen_CxB(r1, op2addr, Ity_F32, Iop_CmpF32); } -static const HChar * +static void s390_irgen_CDB(UChar r1, IRTemp op2addr) { - return s390_irgen_CxB("cdb", r1, op2addr, Ity_F64, Iop_CmpF64); + s390_irgen_CxB(r1, op2addr, Ity_F64, Iop_CmpF64); } -static const HChar * +static void s390_irgen_KDB(UChar r1, IRTemp op2addr) { - return s390_irgen_CxB("kdb", r1, op2addr, Ity_F64, Iop_CmpF64); + s390_irgen_CxB(r1, op2addr, Ity_F64, Iop_CmpF64); } -static const HChar * +static void s390_irgen_CXFBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cxfbra", is_valid_fpr_pair(r1)); - s390_insn_assert("cxfbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op2 = newTemp(Ity_I32); assign(op2, get_gpr_w1(r2)); put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2))); - - return "cxfbra"; } -static const HChar * +static void s390_irgen_CXLFBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cxlfbr", is_valid_fpr_pair(r1)); - s390_insn_assert("cxlfbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); - assign(op2, get_gpr_w1(r2)); - put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2))); - } - return "cxlfbr"; + assign(op2, get_gpr_w1(r2)); + put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CXGBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cxgbra", is_valid_fpr_pair(r1)); - s390_insn_assert("cxgbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op2 = newTemp(Ity_I64); assign(op2, get_gpr_dw0(r2)); put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2))); - - return "cxgbra"; } -static const HChar * +static void s390_irgen_CXLGBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("cxlgbr", is_valid_fpr_pair(r1)); - s390_insn_assert("cxlgbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op2 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2))); - } - return "cxlgbr"; + assign(op2, get_gpr_dw0(r2)); + put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2))); } -static const HChar * +static void s390_irgen_CFXBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cfxbra", is_valid_fpr_pair(r2)); - s390_insn_assert("cfxbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F128); @@ -14991,41 +12626,34 @@ s390_irgen_CFXBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_w1(r1, mkexpr(result)); s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode); - - return "cfxbra"; } -static const HChar * +static void s390_irgen_CLFXBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clfxbr", is_valid_fpr_pair(r2)); - s390_insn_assert("clfxbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F128); - IRTemp result = newTemp(Ity_I32); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F128); + IRTemp result = newTemp(Ity_I32); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_pair(r2)); - assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_w1(r1, mkexpr(result)); - s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode); - } - return "clfxbr"; + assign(op, get_fpr_pair(r2)); + assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode), + mkexpr(op))); + put_gpr_w1(r1, mkexpr(result)); + s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode); } -static const HChar * +static void s390_irgen_CGXBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("cgxbra", is_valid_fpr_pair(r2)); - s390_insn_assert("cgxbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp op = newTemp(Ity_F128); @@ -15037,40 +12665,33 @@ s390_irgen_CGXBRA(UChar m3, UChar m4, UChar r1, UChar r2) mkexpr(op))); put_gpr_dw0(r1, mkexpr(result)); s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode); - - return "cgxbra"; } -static const HChar * +static void s390_irgen_CLGXBR(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext) { - emulation_failure(EmFail_S390X_fpext); - } else { - s390_insn_assert("clgxbr", is_valid_fpr_pair(r2)); - s390_insn_assert("clgxbr", is_valid_rounding_mode(m3)); - if ((m4 & 0x4) != 0) - emulation_warning(EmWarn_S390X_XxC_not_zero); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) + emulation_warning(EmWarn_S390X_XxC_not_zero); - IRTemp op = newTemp(Ity_F128); - IRTemp result = newTemp(Ity_I64); - IRTemp rounding_mode = encode_bfp_rounding_mode(m3); + IRTemp op = newTemp(Ity_F128); + IRTemp result = newTemp(Ity_I64); + IRTemp rounding_mode = encode_bfp_rounding_mode(m3); - assign(op, get_fpr_pair(r2)); - assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode), - mkexpr(op))); - put_gpr_dw0(r1, mkexpr(result)); - s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op, - rounding_mode); - } - return "clgxbr"; + assign(op, get_fpr_pair(r2)); + assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode), + mkexpr(op))); + put_gpr_dw0(r1, mkexpr(result)); + s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op, + rounding_mode); } -static const HChar * +static void s390_irgen_DXBR(UChar r1, UChar r2) { - s390_insn_assert("dxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("dxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp op1 = newTemp(Ity_F128); IRTemp op2 = newTemp(Ity_F128); @@ -15082,97 +12703,83 @@ s390_irgen_DXBR(UChar r1, UChar r2) assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_pair(r1, mkexpr(result)); - - return "dxbr"; } -static const HChar * +static void s390_irgen_LTXBR(UChar r1, UChar r2) { - s390_insn_assert("ltxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("ltxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp result = newTemp(Ity_F128); assign(result, get_fpr_pair(r2)); put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "ltxbr"; } -static const HChar * +static void s390_irgen_LCXBR(UChar r1, UChar r2) { - s390_insn_assert("lcxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("lcxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp result = newTemp(Ity_F128); assign(result, unop(Iop_NegF128, get_fpr_pair(r2))); put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "lcxbr"; } -static const HChar * +static void s390_irgen_LXDBR(UChar r1, UChar r2) { - s390_insn_assert("lxdbr", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); IRTemp op = newTemp(Ity_F64); assign(op, get_fpr_dw0(r2)); put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op))); - - return "lxdbr"; } -static const HChar * +static void s390_irgen_LXEBR(UChar r1, UChar r2) { - s390_insn_assert("lxebr", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); IRTemp op = newTemp(Ity_F32); assign(op, get_fpr_w0(r2)); put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op))); - - return "lxebr"; } -static const HChar * +static void s390_irgen_LXDB(UChar r1, IRTemp op2addr) { - s390_insn_assert("lxdb", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); IRTemp op = newTemp(Ity_F64); assign(op, load(Ity_F64, mkexpr(op2addr))); put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op))); - - return "lxdb"; } -static const HChar * +static void s390_irgen_LXEB(UChar r1, IRTemp op2addr) { - s390_insn_assert("lxeb", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); IRTemp op = newTemp(Ity_F32); assign(op, load(Ity_F32, mkexpr(op2addr))); put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op))); - - return "lxeb"; } -static const HChar * +static void s390_irgen_FIEBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("fiebra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp result = newTemp(Ity_F32); @@ -15180,15 +12787,13 @@ s390_irgen_FIEBRA(UChar m3, UChar m4, UChar r1, UChar r2) assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)), get_fpr_w0(r2))); put_fpr_w0(r1, mkexpr(result)); - - return "fiebra"; } -static const HChar * +static void s390_irgen_FIDBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("fidbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp result = newTemp(Ity_F64); @@ -15196,17 +12801,15 @@ s390_irgen_FIDBRA(UChar m3, UChar m4, UChar r1, UChar r2) assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)), get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); - - return "fidbra"; } -static const HChar * +static void s390_irgen_FIXBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - s390_insn_assert("fixbra", is_valid_fpr_pair(r1)); - s390_insn_assert("fixbra", is_valid_fpr_pair(r2)); - s390_insn_assert("fixbra", is_valid_rounding_mode(m3)); - if (s390_host_has_fpext && (m4 & 0x4) != 0) + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); IRTemp result = newTemp(Ity_F128); @@ -15214,11 +12817,9 @@ s390_irgen_FIXBRA(UChar m3, UChar m4, UChar r1, UChar r2) assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)), get_fpr_pair(r2))); put_fpr_pair(r1, mkexpr(result)); - - return "fixbra"; } -static const HChar * +static void s390_irgen_LNEBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F32); @@ -15226,11 +12827,9 @@ s390_irgen_LNEBR(UChar r1, UChar r2) assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2)))); put_fpr_w0(r1, mkexpr(result)); s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result); - - return "lnebr"; } -static const HChar * +static void s390_irgen_LNDBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); @@ -15238,26 +12837,22 @@ s390_irgen_LNDBR(UChar r1, UChar r2) assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2)))); put_fpr_dw0(r1, mkexpr(result)); s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result); - - return "lndbr"; } -static const HChar * +static void s390_irgen_LNXBR(UChar r1, UChar r2) { - s390_insn_assert("lnxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("lnxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp result = newTemp(Ity_F128); assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2)))); put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "lnxbr"; } -static const HChar * +static void s390_irgen_LPEBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F32); @@ -15265,11 +12860,9 @@ s390_irgen_LPEBR(UChar r1, UChar r2) assign(result, unop(Iop_AbsF32, get_fpr_w0(r2))); put_fpr_w0(r1, mkexpr(result)); s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result); - - return "lpebr"; } -static const HChar * +static void s390_irgen_LPDBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); @@ -15277,74 +12870,58 @@ s390_irgen_LPDBR(UChar r1, UChar r2) assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result); - - return "lpdbr"; } -static const HChar * +static void s390_irgen_LPXBR(UChar r1, UChar r2) { - s390_insn_assert("lpxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("lpxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp result = newTemp(Ity_F128); assign(result, unop(Iop_AbsF128, get_fpr_pair(r2))); put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "lpxbr"; } -static const HChar * +static void s390_irgen_LDXBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("ldxbra", is_valid_fpr_pair(r1)); - s390_insn_assert("ldxbra", is_valid_fpr_pair(r2)); - s390_insn_assert("ldxbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp result = newTemp(Ity_F64); assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)), get_fpr_pair(r2))); put_fpr_dw0(r1, mkexpr(result)); - - return "ldxbra"; } -static const HChar * +static void s390_irgen_LEXBRA(UChar m3, UChar m4, UChar r1, UChar r2) { - if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m3 = S390_BFP_ROUND_PER_FPC; - } - if (s390_host_has_fpext && (m4 & 0x4) != 0) + if ((m4 & 0x4) != 0) emulation_warning(EmWarn_S390X_XxC_not_zero); - s390_insn_assert("lexbra", is_valid_fpr_pair(r1)); - s390_insn_assert("lexbra", is_valid_fpr_pair(r2)); - s390_insn_assert("lexbra", is_valid_rounding_mode(m3)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_rounding_mode(m3)); IRTemp result = newTemp(Ity_F32); assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)), get_fpr_pair(r2))); put_fpr_w0(r1, mkexpr(result)); - - return "lexbra"; } -static const HChar * +static void s390_irgen_MXBR(UChar r1, UChar r2) { - s390_insn_assert("mxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("mxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp op1 = newTemp(Ity_F128); IRTemp op2 = newTemp(Ity_F128); @@ -15356,33 +12933,27 @@ s390_irgen_MXBR(UChar r1, UChar r2) assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1), mkexpr(op2))); put_fpr_pair(r1, mkexpr(result)); - - return "mxbr"; } -static const HChar * +static void s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2) { IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC); put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode), get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1))); - - return "maebr"; } -static const HChar * +static void s390_irgen_MADBR(UChar r1, UChar r3, UChar r2) { IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC); put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode), get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1))); - - return "madbr"; } -static const HChar * +static void s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1) { IRExpr *op2 = load(Ity_F32, mkexpr(op2addr)); @@ -15390,11 +12961,9 @@ s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1) put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode), get_fpr_w0(r3), op2, get_fpr_w0(r1))); - - return "maeb"; } -static const HChar * +static void s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1) { IRExpr *op2 = load(Ity_F64, mkexpr(op2addr)); @@ -15402,33 +12971,27 @@ s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1) put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode), get_fpr_dw0(r3), op2, get_fpr_dw0(r1))); - - return "madb"; } -static const HChar * +static void s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2) { IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC); put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode), get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1))); - - return "msebr"; } -static const HChar * +static void s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2) { IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC); put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode), get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1))); - - return "msdbr"; } -static const HChar * +static void s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1) { IRExpr *op2 = load(Ity_F32, mkexpr(op2addr)); @@ -15436,11 +12999,9 @@ s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1) put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode), get_fpr_w0(r3), op2, get_fpr_w0(r1))); - - return "mseb"; } -static const HChar * +static void s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1) { IRExpr *op2 = load(Ity_F64, mkexpr(op2addr)); @@ -15448,11 +13009,9 @@ s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1) put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode), get_fpr_dw0(r3), op2, get_fpr_dw0(r1))); - - return "msdb"; } -static const HChar * +static void s390_irgen_SQEBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F32); @@ -15460,11 +13019,9 @@ s390_irgen_SQEBR(UChar r1, UChar r2) assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2))); put_fpr_w0(r1, mkexpr(result)); - - return "sqebr"; } -static const HChar * +static void s390_irgen_SQDBR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); @@ -15472,15 +13029,13 @@ s390_irgen_SQDBR(UChar r1, UChar r2) assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); - - return "sqdbr"; } -static const HChar * +static void s390_irgen_SQXBR(UChar r1, UChar r2) { - s390_insn_assert("sqxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("sqxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp result = newTemp(Ity_F128); IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC); @@ -15488,11 +13043,9 @@ s390_irgen_SQXBR(UChar r1, UChar r2) assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode), get_fpr_pair(r2))); put_fpr_pair(r1, mkexpr(result)); - - return "sqxbr"; } -static const HChar * +static void s390_irgen_SQEB(UChar r1, IRTemp op2addr) { IRTemp op = newTemp(Ity_F32); @@ -15500,11 +13053,9 @@ s390_irgen_SQEB(UChar r1, IRTemp op2addr) assign(op, load(Ity_F32, mkexpr(op2addr))); put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op))); - - return "sqeb"; } -static const HChar * +static void s390_irgen_SQDB(UChar r1, IRTemp op2addr) { IRTemp op = newTemp(Ity_F64); @@ -15512,15 +13063,13 @@ s390_irgen_SQDB(UChar r1, IRTemp op2addr) assign(op, load(Ity_F64, mkexpr(op2addr))); put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op))); - - return "sqdb"; } -static const HChar * +static void s390_irgen_SXBR(UChar r1, UChar r2) { - s390_insn_assert("sxbr", is_valid_fpr_pair(r1)); - s390_insn_assert("sxbr", is_valid_fpr_pair(r2)); + s390_insn_assert(is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r2)); IRTemp op1 = newTemp(Ity_F128); IRTemp op2 = newTemp(Ity_F128); @@ -15533,11 +13082,9 @@ s390_irgen_SXBR(UChar r1, UChar r2) mkexpr(op2))); put_fpr_pair(r1, mkexpr(result)); s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result); - - return "sxbr"; } -static const HChar * +static void s390_irgen_TCEB(UChar r1, IRTemp op2addr) { IRTemp value = newTemp(Ity_F32); @@ -15545,11 +13092,9 @@ s390_irgen_TCEB(UChar r1, IRTemp op2addr) assign(value, get_fpr_w0(r1)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr); - - return "tceb"; } -static const HChar * +static void s390_irgen_TCDB(UChar r1, IRTemp op2addr) { IRTemp value = newTemp(Ity_F64); @@ -15557,75 +13102,61 @@ s390_irgen_TCDB(UChar r1, IRTemp op2addr) assign(value, get_fpr_dw0(r1)); s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr); - - return "tcdb"; } -static const HChar * +static void s390_irgen_TCXB(UChar r1, IRTemp op2addr) { - s390_insn_assert("tcxb", is_valid_fpr_pair(r1)); + s390_insn_assert(is_valid_fpr_pair(r1)); IRTemp value = newTemp(Ity_F128); assign(value, get_fpr_pair(r1)); s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr); - - return "tcxb"; } -static const HChar * +static void s390_irgen_LCDFR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); assign(result, unop(Iop_NegF64, get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); - - return "lcdfr"; } -static const HChar * +static void s390_irgen_LNDFR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2)))); put_fpr_dw0(r1, mkexpr(result)); - - return "lndfr"; } -static const HChar * +static void s390_irgen_LPDFR(UChar r1, UChar r2) { IRTemp result = newTemp(Ity_F64); assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2))); put_fpr_dw0(r1, mkexpr(result)); - - return "lpdfr"; } -static const HChar * +static void s390_irgen_LDGR(UChar r1, UChar r2) { put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2))); - - return "ldgr"; } -static const HChar * +static void s390_irgen_LGDR(UChar r1, UChar r2) { put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2))); - - return "lgdr"; } -static const HChar * +static void s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2) { IRTemp sign = newTemp(Ity_I64); @@ -15637,8 +13168,6 @@ s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2) mkU64((1ULL << 63) - 1))); put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value), mkexpr(sign)))); - - return "cpsdr"; } @@ -15657,20 +13186,16 @@ s390_call_cvb(IRExpr *in) return call; } -static const HChar * +static void s390_irgen_CVB(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr)))); - - return "cvb"; } -static const HChar * +static void s390_irgen_CVBY(UChar r1, IRTemp op2addr) { put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr)))); - - return "cvby"; } @@ -15689,26 +13214,22 @@ s390_call_cvd(IRExpr *in) return call; } -static const HChar * +static void s390_irgen_CVD(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1)))); - - return "cvd"; } -static const HChar * +static void s390_irgen_CVDY(UChar r1, IRTemp op2addr) { store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1))); - - return "cvdy"; } -static const HChar * +static void s390_irgen_FLOGR(UChar r1, UChar r2) { - s390_insn_assert("flogr", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp input = newTemp(Ity_I64); IRTemp num = newTemp(Ity_I64); @@ -15746,14 +13267,19 @@ s390_irgen_FLOGR(UChar r1, UChar r2) /* Compare the original value as an unsigned integer with 0. */ s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input, mktemp(Ity_I64, mkU64(0)), False); - - return "flogr"; } -static const HChar * +static void s390_irgen_POPCNT(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("popcnt", (m3 & 7) == 0); + if (s390_host_has_mi3 && m3 == 8) { + IRTemp val = newTemp(Ity_I64); + + assign(val, unop(Iop_PopCount64, get_gpr_dw0(r2))); + s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val); + put_gpr_dw0(r1, mkexpr(val)); + return; + } static const ULong masks[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, @@ -15781,10 +13307,9 @@ s390_irgen_POPCNT(UChar m3, UChar r1, UChar r2) } s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val); put_gpr_dw0(r1, mkexpr(val)); - return "popcnt"; } -static const HChar * +static void s390_irgen_STCK(IRTemp op2addr) { IRDirty *d; @@ -15798,30 +13323,24 @@ s390_irgen_STCK(IRTemp op2addr) d->mSize = 8; stmt(IRStmt_Dirty(d)); s390_cc_set(cc); - return "stck"; } -static const HChar * +static void s390_irgen_STCKF(IRTemp op2addr) { - if (! s390_host_has_stckf) { - emulation_failure(EmFail_S390X_stckf); - } else { - IRTemp cc = newTemp(Ity_I64); + IRTemp cc = newTemp(Ity_I64); - IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF", - &s390x_dirtyhelper_STCKF, - mkIRExprVec_1(mkexpr(op2addr))); - d->mFx = Ifx_Write; - d->mAddr = mkexpr(op2addr); - d->mSize = 8; - stmt(IRStmt_Dirty(d)); - s390_cc_set(cc); - } - return "stckf"; + IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF", + &s390x_dirtyhelper_STCKF, + mkIRExprVec_1(mkexpr(op2addr))); + d->mFx = Ifx_Write; + d->mAddr = mkexpr(op2addr); + d->mSize = 8; + stmt(IRStmt_Dirty(d)); + s390_cc_set(cc); } -static const HChar * +static void s390_irgen_STCKE(IRTemp op2addr) { IRDirty *d; @@ -15835,24 +13354,18 @@ s390_irgen_STCKE(IRTemp op2addr) d->mSize = 16; stmt(IRStmt_Dirty(d)); s390_cc_set(cc); - return "stcke"; } -static const HChar * +static void s390_irgen_STFLE(UChar b2, UShort d2) { - if (! s390_host_has_stfle) { - emulation_failure(EmFail_S390X_stfle); - return "stfle"; - } extension(S390_EXT_STFLE, b2 | (d2 << 8)); - return "stfle"; } -static const HChar * +static void s390_irgen_CKSM(UChar r1,UChar r2) { - s390_insn_assert("cksm", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr = newTemp(Ity_I64); IRTemp op = newTemp(Ity_I32); @@ -15911,14 +13424,12 @@ s390_irgen_CKSM(UChar r1,UChar r2) put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc))); iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0))); - - return "cksm"; } -static const HChar * +static void s390_irgen_TROO(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("troo", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp src_addr, des_addr, tab_addr, src_len, test_byte; src_addr = newTemp(Ity_I64); @@ -15949,7 +13460,7 @@ s390_irgen_TROO(UChar m3, UChar r1, UChar r2) mkexpr(tab_addr))); assign(op1, load(Ity_I8, mkexpr(result))); - if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { + if ((m3 & 0x1) == 0) { s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte))); } @@ -15960,14 +13471,12 @@ s390_irgen_TROO(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1))); iterate(); - - return "troo"; } -static const HChar * +static void s390_irgen_TRTO(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("trto", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp src_addr, des_addr, tab_addr, src_len, test_byte; src_addr = newTemp(Ity_I64); @@ -15999,7 +13508,7 @@ s390_irgen_TRTO(UChar m3, UChar r1, UChar r2) assign(op1, load(Ity_I8, mkexpr(result))); - if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { + if ((m3 & 0x1) == 0) { s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte))); } @@ -16010,14 +13519,12 @@ s390_irgen_TRTO(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2))); iterate(); - - return "trto"; } -static const HChar * +static void s390_irgen_TROT(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("trot", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp src_addr, des_addr, tab_addr, src_len, test_byte; src_addr = newTemp(Ity_I64); @@ -16048,7 +13555,7 @@ s390_irgen_TROT(UChar m3, UChar r1, UChar r2) mkexpr(tab_addr))); assign(op1, load(Ity_I16, mkexpr(result))); - if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { + if ((m3 & 0x1) == 0) { s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte))); } @@ -16059,14 +13566,12 @@ s390_irgen_TROT(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1))); iterate(); - - return "trot"; } -static const HChar * +static void s390_irgen_TRTT(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("trtt", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp src_addr, des_addr, tab_addr, src_len, test_byte; src_addr = newTemp(Ity_I64); @@ -16097,7 +13602,7 @@ s390_irgen_TRTT(UChar m3, UChar r1, UChar r2) mkexpr(tab_addr))); assign(op1, load(Ity_I16, mkexpr(result))); - if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { + if ((m3 & 0x1) == 0) { s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte))); } @@ -16109,25 +13614,21 @@ s390_irgen_TRTT(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2))); iterate(); - - return "trtt"; } -static const HChar * +static void s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2) { IRTemp len = newTemp(Ity_I64); assign(len, mkU64(length)); s390_irgen_TR_EX(len, start1, start2); - - return "tr"; } -static const HChar * +static void s390_irgen_TRE(UChar r1,UChar r2) { - s390_insn_assert("tre", is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r1)); IRTemp src_addr, tab_addr, src_len, test_byte; src_addr = newTemp(Ity_I64); @@ -16164,8 +13665,6 @@ s390_irgen_TRE(UChar r1,UChar r2) put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1))); iterate(); - - return "tre"; } static IRExpr * @@ -16182,11 +13681,11 @@ s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate) return call; } -static const HChar * +static void s390_irgen_CU21(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("cu21", is_valid_gpr_pair(r1)); - s390_insn_assert("cu21", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -16243,7 +13742,7 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) /* Before we can test whether the 1st operand is exhausted we need to test for an invalid low surrogate. Because cc=2 outranks cc=1. */ - if (s390_host_has_etf3 && (m3 & 0x1) == 1) { + if ((m3 & 0x1) == 1) { IRExpr *invalid_low_surrogate = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); @@ -16294,8 +13793,6 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes))); iterate(); - - return "cu21"; } static IRExpr * @@ -16312,11 +13809,11 @@ s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate) return call; } -static const HChar * +static void s390_irgen_CU24(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("cu24", is_valid_gpr_pair(r1)); - s390_insn_assert("cu24", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -16374,7 +13871,7 @@ s390_irgen_CU24(UChar m3, UChar r1, UChar r2) /* Before we can test whether the 1st operand is exhausted we need to test for an invalid low surrogate. Because cc=2 outranks cc=1. */ - if (s390_host_has_etf3 && (m3 & 0x1) == 1) { + if ((m3 & 0x1) == 1) { IRExpr *invalid_low_surrogate = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); @@ -16404,8 +13901,6 @@ s390_irgen_CU24(UChar m3, UChar r1, UChar r2) put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4))); iterate(); - - return "cu24"; } static IRExpr * @@ -16422,11 +13917,11 @@ s390_call_cu42(IRExpr *srcval) return call; } -static const HChar * +static void s390_irgen_CU42(UChar r1, UChar r2) { - s390_insn_assert("cu42", is_valid_gpr_pair(r1)); - s390_insn_assert("cu42", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -16501,8 +13996,6 @@ s390_irgen_CU42(UChar r1, UChar r2) put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes))); iterate(); - - return "cu42"; } static IRExpr * @@ -16519,11 +14012,11 @@ s390_call_cu41(IRExpr *srcval) return call; } -static const HChar * +static void s390_irgen_CU41(UChar r1, UChar r2) { - s390_insn_assert("cu41", is_valid_gpr_pair(r1)); - s390_insn_assert("cu41", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); IRTemp addr1 = newTemp(Ity_I64); IRTemp addr2 = newTemp(Ity_I64); @@ -16595,8 +14088,6 @@ s390_irgen_CU41(UChar r1, UChar r2) put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes))); iterate(); - - return "cu41"; } static IRExpr * @@ -16656,7 +14147,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) assign(len1, get_gpr_dw0(r1 + 1)); assign(len2, get_gpr_dw0(r2 + 1)); - UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1; + UInt extended_checking = (m3 & 0x1) == 1; /* We're processing the 2nd operand 1 byte at a time. Therefore, if there is less than 1 byte left, then the 2nd operand is exhausted @@ -16769,26 +14260,22 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) iterate(); } -static const HChar * +static void s390_irgen_CU12(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("cu12", is_valid_gpr_pair(r1)); - s390_insn_assert("cu12", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1); - - return "cu12"; } -static const HChar * +static void s390_irgen_CU14(UChar m3, UChar r1, UChar r2) { - s390_insn_assert("cu14", is_valid_gpr_pair(r1)); - s390_insn_assert("cu14", is_valid_gpr_pair(r2)); + s390_insn_assert(is_valid_gpr_pair(r1)); + s390_insn_assert(is_valid_gpr_pair(r2)); s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0); - - return "cu14"; } static IRExpr * @@ -16806,143 +14293,116 @@ s390_call_ecag(IRExpr *op2addr) return call; } -static const HChar * +static void s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr) { - if (! s390_host_has_gie) { - emulation_failure(EmFail_S390X_ecag); - } else { - put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr))); - } - - return "ecag"; + put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr))); } -static const HChar * -s390_irgen_VL(UChar v1, IRTemp op2addr) +static void +s390_irgen_VL(UChar v1, IRTemp op2addr, + UChar m3 __attribute__((unused))) /* alignment hint */ { put_vr_qw(v1, load(Ity_V128, mkexpr(op2addr))); - - return "vl"; } -static const HChar * +static void s390_irgen_VLR(UChar v1, UChar v2) { put_vr_qw(v1, get_vr_qw(v2)); - - return "vlr"; } -static const HChar * -s390_irgen_VST(UChar v1, IRTemp op2addr) +static void +s390_irgen_VST(UChar v1, IRTemp op2addr, + UChar m3 __attribute__((unused))) /* alignment hint */ { store(mkexpr(op2addr), get_vr_qw(v1)); - - return "vst"; } -static const HChar * +static void s390_irgen_VLREP(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vlrep", m3 <= 3); + s390_insn_assert(m3 <= 3); IRType o2type = s390_vr_get_type(m3); IRExpr* o2 = load(o2type, mkexpr(op2addr)); - s390_vr_fill(v1, o2); - return "vlrep"; + put_vr_qw(v1, s390_V128_fill(o2)); } -static const HChar * +static void s390_irgen_VLEB(UChar v1, IRTemp op2addr, UChar m3) { /* Specification exception cannot occur. */ IRExpr* o2 = load(Ity_I8, mkexpr(op2addr)); put_vr(v1, Ity_I8, m3, o2); - - return "vleb"; } -static const HChar * +static void s390_irgen_VLEH(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vleh", m3 < 8); + s390_insn_assert(m3 < 8); IRExpr* o2 = load(Ity_I16, mkexpr(op2addr)); put_vr(v1, Ity_I16, m3, o2); - - return "vleh"; } -static const HChar * +static void s390_irgen_VLEF(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vlef", m3 < 4); + s390_insn_assert(m3 < 4); IRExpr* o2 = load(Ity_I32, mkexpr(op2addr)); put_vr(v1, Ity_I32, m3, o2); - - return "vlef"; } -static const HChar * +static void s390_irgen_VLEG(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vleg", m3 < 2); + s390_insn_assert(m3 < 2); IRExpr* o2 = load(Ity_I64, mkexpr(op2addr)); put_vr(v1, Ity_I64, m3, o2); - - return "vleg"; } -static const HChar * +static void s390_irgen_VLEIB(UChar v1, UShort i2, UChar m3) { /* Specification exception cannot occur. */ IRExpr* o2 = unop(Iop_16to8, mkU16(i2)); put_vr(v1, Ity_I8, m3, o2); - - return "vleib"; } -static const HChar * +static void s390_irgen_VLEIH(UChar v1, UShort i2, UChar m3) { - s390_insn_assert("vleih", m3 < 8); + s390_insn_assert(m3 < 8); IRExpr* o2 = mkU16(i2); put_vr(v1, Ity_I16, m3, o2); - - return "vleih"; } -static const HChar * +static void s390_irgen_VLEIF(UChar v1, UShort i2, UChar m3) { - s390_insn_assert("vleif", m3 < 4); + s390_insn_assert(m3 < 4); IRExpr* o2 = unop(Iop_16Sto32, mkU16(i2)); put_vr(v1, Ity_I32, m3, o2); - - return "vleif"; } -static const HChar * +static void s390_irgen_VLEIG(UChar v1, UShort i2, UChar m3) { - s390_insn_assert("vleig", m3 < 2); + s390_insn_assert(m3 < 2); IRExpr* o2 = unop(Iop_16Sto64, mkU16(i2)); put_vr(v1, Ity_I64, m3, o2); - - return "vleig"; } -static const HChar * +static void s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4) { - s390_insn_assert("vlgv", m4 <= 3); + s390_insn_assert(m4 <= 3); IRType o2type = s390_vr_get_type(m4); IRExpr* index = unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(0xf))); @@ -16970,21 +14430,18 @@ s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4) } put_gpr_dw0(r1, result); - return "vlgv"; } -static const HChar * +static void s390_irgen_VGBM(UChar v1, UShort i2) { put_vr_qw(v1, mkV128(i2)); - - return "vgbm"; } -static const HChar * +static void s390_irgen_VGM(UChar v1, UChar i2, UChar i3, UChar m4) { - s390_insn_assert("vgm", m4 <= 3); + s390_insn_assert(m4 <= 3); UChar max_idx = (8 << m4) - 1; UChar from = max_idx & i2; @@ -17017,14 +14474,13 @@ s390_irgen_VGM(UChar v1, UChar i2, UChar i3, UChar m4) vpanic("s390_irgen_VGM: unknown element size"); } - s390_vr_fill(v1, fillValue); - return "vgm"; + put_vr_qw(v1, s390_V128_fill(fillValue)); } -static const HChar * +static void s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vllez", m3 <= 3 || m3 == 6); + s390_insn_assert(m3 <= 3 || m3 == 6); IRType type = s390_vr_get_type(m3 & 3); IRExpr* op2 = load(type, mkexpr(op2addr)); @@ -17054,32 +14510,30 @@ s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3) put_vr_dw0(v1, op2as64bit); } put_vr_dw1(v1, mkU64(0)); - return "vllez"; } -static const HChar * +static void s390_irgen_VGEF(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vgef", m3 < 4); + s390_insn_assert(m3 < 4); put_vr(v1, Ity_I32, m3, load(Ity_I32, mkexpr(op2addr))); - return "vgef"; } -static const HChar * +static void s390_irgen_VGEG(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vgeg", m3 < 2); + s390_insn_assert(m3 < 2); put_vr(v1, Ity_I64, m3, load(Ity_I64, mkexpr(op2addr))); - return "vgeg"; } -static const HChar * -s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3) +static void +s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3, + UChar m4 __attribute__((unused))) /* alignment hint */ { - s390_insn_assert("vlm", v3 >= v1); - s390_insn_assert("vlm", v3 - v1 <= 16); + s390_insn_assert(v3 >= v1); + s390_insn_assert(v3 - v1 <= 16); IRExpr* current = mkexpr(op2addr); @@ -17088,22 +14542,18 @@ s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3) put_vr_qw(vr, load(Ity_V128, current)); current = next; } - - return "vlm"; } -static const HChar * +static void s390_irgen_VLVGP(UChar v1, UChar r2, UChar r3) { put_vr_qw(v1, binop(Iop_64HLtoV128, get_gpr_dw0(r2), get_gpr_dw0(r3))); - - return "vlvgp"; } -static const HChar * +static void s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4) { - s390_insn_assert("vlvg", m4 <= 3); + s390_insn_assert(m4 <= 3); IRType type = s390_vr_get_type(m4); IRExpr* index = unop(Iop_64to8, mkexpr(op2addr)); @@ -17129,85 +14579,73 @@ s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4) default: vpanic("s390_irgen_VLVG: unknown type"); } - - return "vlvg"; } -static const HChar * +static void s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmrh", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_InterleaveHI8x16, Iop_InterleaveHI16x8, Iop_InterleaveHI32x4, Iop_InterleaveHI64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vmrh"; } -static const HChar * +static void s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmrl", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vmrl"; } -static const HChar * +static void s390_irgen_VPK(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vpk", m4 >= 1 && m4 <= 3); + s390_insn_assert(m4 >= 1 && m4 <= 3); const IROp ops[] = { Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8, Iop_NarrowBin64to32x4 }; Char index = m4 - 1; put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3))); - return "vpk"; } -static const HChar * +static void s390_irgen_VPERM(UChar v1, UChar v2, UChar v3, UChar v4) { put_vr_qw(v1, triop(Iop_Perm8x16x2, get_vr_qw(v2), get_vr_qw(v3), get_vr_qw(v4))); - - return "vperm"; } -static const HChar * +static void s390_irgen_VSCEF(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vscef", m3 < 4); + s390_insn_assert(m3 < 4); store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3)); - return "vscef"; } -static const HChar * +static void s390_irgen_VSCEG(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vsceg", m3 < 2); + s390_insn_assert(m3 < 2); store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3)); - return "vsceg"; } -static const HChar * +static void s390_irgen_VPDI(UChar v1, UChar v2, UChar v3, UChar m4) { put_vr_qw(v1, binop(Iop_64HLtoV128, m4 & 4 ? get_vr_dw1(v2) : get_vr_dw0(v2), m4 & 1 ? get_vr_dw1(v3) : get_vr_dw0(v3))); - return "vpdi"; } -static const HChar * +static void s390_irgen_VSEG(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vseg", m3 <= 2); + s390_insn_assert(m3 <= 2); IRType type = s390_vr_get_type(m3); switch(type) { @@ -17227,54 +14665,45 @@ s390_irgen_VSEG(UChar v1, UChar v2, UChar m3) ppIRType(type); vpanic("s390_irgen_VSEG: unknown type"); } - - return "vseg"; } -static const HChar * +static void s390_irgen_VSTEB(UChar v1, IRTemp op2addr, UChar m3) { /* Specification exception cannot occur. */ store(mkexpr(op2addr), get_vr(v1, Ity_I8, m3)); - - return "vsteb"; } -static const HChar * +static void s390_irgen_VSTEH(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vsteh", m3 < 8); + s390_insn_assert(m3 < 8); store(mkexpr(op2addr), get_vr(v1, Ity_I16, m3)); - - return "vsteh"; } -static const HChar * +static void s390_irgen_VSTEF(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vstef", m3 < 8); + s390_insn_assert(m3 < 4); store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3)); - - return "vstef"; } -static const HChar * +static void s390_irgen_VSTEG(UChar v1, IRTemp op2addr, UChar m3) { - s390_insn_assert("vsteg", m3 < 2); + s390_insn_assert(m3 < 2); store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3)); - - return "vsteg"; } -static const HChar * -s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3) +static void +s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3, + UChar m4 __attribute__((unused))) /* alignment hint */ { - s390_insn_assert("vstm", v3 >= v1); - s390_insn_assert("vstm", v3 - v1 <= 16); + s390_insn_assert(v3 >= v1); + s390_insn_assert(v3 - v1 <= 16); IRExpr* current = mkexpr(op2addr); @@ -17283,100 +14712,62 @@ s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3) store(current, get_vr_qw(vr)); current = next; } +} - return "vstm"; +static void +s390_irgen_VUPx(UChar v1, UChar m3, Bool is_signed, IRExpr* val) +{ + s390_insn_assert(m3 <= 3); + put_vr_qw(v1, s390_V128_unpack(val, m3, is_signed)); } -static const HChar * +static void s390_irgen_VUPH(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vuph", m3 <= 2); - - const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2))); - - return "vuph"; + s390_irgen_VUPx(v1, m3, True, get_vr_dw0(v2)); } -static const HChar * +static void s390_irgen_VUPLH(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vuplh", m3 <= 2); - - const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2))); - return "vuplh"; + s390_irgen_VUPx(v1, m3, False, get_vr_dw0(v2)); } -static const HChar * +static void s390_irgen_VUPL(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vupl", m3 <= 2); - - const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2))); - - return "vupl"; + s390_irgen_VUPx(v1, m3, True, get_vr_dw1(v2)); } -static const HChar * +static void s390_irgen_VUPLL(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vupll", m3 <= 2); - - const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2))); - - return "vupll"; + s390_irgen_VUPx(v1, m3, False, get_vr_dw1(v2)); } -static const HChar * +static void s390_irgen_VREP(UChar v1, UChar v3, UShort i2, UChar m4) { - s390_insn_assert("vrep", m4 <= 3); - s390_insn_assert("vrep", (m4 == 0 && i2 < 16) || (m4 == 1 && i2 < 8) || + s390_insn_assert(m4 <= 3); + s390_insn_assert((m4 == 0 && i2 < 16) || (m4 == 1 && i2 < 8) || (m4 == 2 && i2 < 4) || (m4 == 3 && i2 < 2)); IRType type = s390_vr_get_type(m4); IRExpr* arg = get_vr(v3, type, i2); - s390_vr_fill(v1, arg); - - return "vrep"; + put_vr_qw(v1, s390_V128_fill(arg)); } -static const HChar * +static void s390_irgen_VREPI(UChar v1, UShort i2, UChar m3) { - s390_insn_assert("vrepi", m3 <= 3); - - IRType type = s390_vr_get_type(m3); - IRExpr *value; - switch (type) { - case Ity_I8: - value = mkU8((UChar)i2); - break; - case Ity_I16: - value = mkU16(i2); - break; - case Ity_I32: - value = unop(Iop_16Sto32, mkU16(i2)); - break; - case Ity_I64: - value = unop(Iop_16Sto64, mkU16(i2)); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VREPI: unknown type"); - } - s390_vr_fill(v1, value); - - return "vrepi"; + s390_insn_assert(m3 <= 3); + put_vr_qw(v1, s390_V128_fillnum((Short)i2, m3)); } -static const HChar * +static void s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vpks", m4 >= 1 && m4 <= 3); + s390_insn_assert(m4 >= 1 && m4 <= 3); if (!s390_vr_is_cs_set(m5)) { const IROp ops[] = { Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8, @@ -17416,14 +14807,12 @@ s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) stmt(IRStmt_Dirty(d)); s390_cc_set(cc); } - - return "vpks"; } -static const HChar * +static void s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vpkls", m4 >= 1 && m4 <= 3); + s390_insn_assert(m4 >= 1 && m4 <= 3); if (!s390_vr_is_cs_set(m5)) { const IROp ops[] = { Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8, @@ -17463,11 +14852,9 @@ s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) stmt(IRStmt_Dirty(d)); s390_cc_set(cc); } - - return "vpkls"; } -static const HChar * +static void s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4) { IRExpr* vIfTrue = get_vr_qw(v2); @@ -17475,190 +14862,160 @@ s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4) IRExpr* vCond = get_vr_qw(v4); put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse)); - return "vsel"; } -static const HChar * +static void s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3) { - s390_insn_assert("vlbb", m3 <= 6); + s390_insn_assert(m3 <= 6); IRExpr* maxIndex = binop(Iop_Sub32, s390_getCountToBlockBoundary(addr, m3), mkU32(1)); s390_vr_loadWithLength(v1, addr, maxIndex, False); - - return "vlbb"; } -static const HChar * +static void s390_irgen_VLL(UChar v1, IRTemp addr, UChar r3) { s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), False); - - return "vll"; } -static const HChar * +static void s390_irgen_VLRL(UChar v1, IRTemp addr, UChar i3) { if (! s390_host_has_vxd) { emulation_failure(EmFail_S390X_vxd); - return "vlrl"; + return; } - s390_insn_assert("vlrl", (i3 & 0xf0) == 0); + s390_insn_assert((i3 & 0xf0) == 0); s390_vr_loadWithLength(v1, addr, mkU32((UInt) i3), True); - - return "vlrl"; } -static const HChar * +static void s390_irgen_VLRLR(UChar v1, UChar r3, IRTemp addr) { if (! s390_host_has_vxd) { emulation_failure(EmFail_S390X_vxd); - return "vlrlr"; + return; } s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), True); - - return "vlrlr"; } -static const HChar * +static void s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3) { s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), False); - return "vstl"; } -static const HChar * +static void s390_irgen_VSTRL(UChar v1, IRTemp addr, UChar i3) { if (! s390_host_has_vxd) { emulation_failure(EmFail_S390X_vxd); - return "vstrl"; + return; } - s390_insn_assert("vstrl", (i3 & 0xf0) == 0); + s390_insn_assert((i3 & 0xf0) == 0); s390_vr_storeWithLength(v1, addr, mkU32((UInt) i3), True); - return "vstrl"; } -static const HChar * +static void s390_irgen_VSTRLR(UChar v1, UChar r3, IRTemp addr) { if (! s390_host_has_vxd) { emulation_failure(EmFail_S390X_vxd); - return "vstrlr"; + return; } s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), True); - return "vstrlr"; } -static const HChar * +static void s390_irgen_VX(UChar v1, UChar v2, UChar v3) { put_vr_qw(v1, binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3))); - - return "vx"; } -static const HChar * +static void s390_irgen_VN(UChar v1, UChar v2, UChar v3) { put_vr_qw(v1, binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3))); - - return "vn"; } -static const HChar * +static void s390_irgen_VO(UChar v1, UChar v2, UChar v3) { put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3))); - - return "vo"; } -static const HChar * +static void s390_irgen_VOC(UChar v1, UChar v2, UChar v3) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "voc"; + return; } put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), unop(Iop_NotV128, get_vr_qw(v3)))); - - return "voc"; } -static const HChar * +static void s390_irgen_VNN(UChar v1, UChar v2, UChar v3) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vnn"; + return; } put_vr_qw(v1, unop(Iop_NotV128, binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3)))); - - return "vnn"; } -static const HChar * +static void s390_irgen_VNO(UChar v1, UChar v2, UChar v3) { put_vr_qw(v1, unop(Iop_NotV128, binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3)))); - - return "vno"; } -static const HChar * +static void s390_irgen_VNX(UChar v1, UChar v2, UChar v3) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vnx"; + return; } put_vr_qw(v1, unop(Iop_NotV128, binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3)))); - - return "vnx"; } -static const HChar * +static void s390_irgen_LZRF(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I32); assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00))); put_gpr_w1(r1, mkexpr(op2)); - - return "lzrf"; } -static const HChar * +static void s390_irgen_LZRG(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I64); assign(op2, binop(Iop_And64, load(Ity_I64, mkexpr(op2addr)), mkU64(0xffffffffffffff00UL))); put_gpr_dw0(r1, mkexpr(op2)); - - return "lzrg"; } -static const HChar * +static void s390_irgen_LLZRGF(UChar r1, IRTemp op2addr) { IRTemp op2 = newTemp(Ity_I32); @@ -17666,68 +15023,54 @@ s390_irgen_LLZRGF(UChar r1, IRTemp op2addr) assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00))); put_gpr_w1(r1, mkexpr(op2)); put_gpr_w0(r1, mkU32(0)); - - return "llzrgf"; } -static const HChar * +static void s390_irgen_LOCFH(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr))); - - return "locfh"; } -static const HChar * +static void s390_irgen_LOCFHR(UChar m3, UChar r1, UChar r2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_w0(r1, get_gpr_w0(r2)); - - return "locfhr"; } -static const HChar * +static void s390_irgen_LOCHHI(UChar r1, UChar m3, UShort i2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_w0(r1, mkU32((UInt)(Int)(Short)i2)); - - return "lochhi"; } -static const HChar * +static void s390_irgen_LOCHI(UChar r1, UChar m3, UShort i2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2)); - - return "lochi"; } -static const HChar * +static void s390_irgen_LOCGHI(UChar r1, UChar m3, UShort i2) { next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2)); - - return "locghi"; } -static const HChar * +static void s390_irgen_STOCFH(UChar r1, IRTemp op2addr) { /* condition is checked in format handler */ store(mkexpr(op2addr), get_gpr_w1(r1)); - - return "stocfh"; } -static const HChar * +static void s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3) { - s390_insn_assert("lcbb", m3 <= 6); + s390_insn_assert(m3 <= 6); IRTemp op2 = newTemp(Ity_I32); assign(op2, s390_getCountToBlockBoundary(op2addr, m3)); @@ -17735,39 +15078,35 @@ s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3) IRExpr* cc = mkite(binop(Iop_CmpEQ32, mkexpr(op2), mkU32(16)), mkU64(0), mkU64(3)); s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), cc, mkU64(0), mkU64(0)); - - return "lcbb"; } -static const HChar * +static void s390_irgen_PRNO(UChar r1, UChar r2) { if (!s390_host_has_msa5) { emulation_failure(EmFail_S390X_prno); - return "prno"; + return; } /* Check for obvious specification exceptions */ - s390_insn_assert("prno", r1 % 2 == 0 && r2 % 2 == 0 && r1 != 0 && r2 != 0); + s390_insn_assert(r1 % 2 == 0 && r2 % 2 == 0 && r1 != 0 && r2 != 0); extension(S390_EXT_PRNO, r1 | (r2 << 4)); - return "prno"; } -static const HChar * +static void s390_irgen_DFLTCC(UChar r3, UChar r1, UChar r2) { if (!s390_host_has_dflt) { emulation_failure(EmFail_S390X_dflt); - return "dfltcc"; + return; } /* Check for obvious specification exceptions */ - s390_insn_assert("dfltcc", r1 % 2 == 0 && r1 != 0 && + s390_insn_assert(r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 && r3 >= 2); extension(S390_EXT_DFLT, r1 | (r2 << 4) | (r3 << 8)); - return "dfltcc"; } enum s390_VStrX { @@ -17777,7 +15116,7 @@ enum s390_VStrX { }; #define S390_VEC_OP3(m, op0, op1, op2) \ - (m) == 0 ? op0 : (m) == 1 ? op1 : (m) == 2 ? op2 : Iop_INVALID; + ((m) == 0 ? op0 : (m) == 1 ? op1 : (m) == 2 ? op2 : Iop_INVALID) /* Helper function for transforming VSTRC, VFAE, or VFEE. These instructions share much of the same logic. */ @@ -17956,26 +15295,24 @@ s390_irgen_VStrX(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, dis_res->hint = Dis_HintVerbose; } -static const HChar * +static void s390_irgen_VFAE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vfae", m4 <= 2); + s390_insn_assert(m4 <= 2); s390_irgen_VStrX(v1, v2, v3, 255, m4, m5, s390_VStrX_VFAE); - return "vfae"; } -static const HChar * +static void s390_irgen_VFEE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vfee", m4 < 3 && m5 == (m5 & 3)); + s390_insn_assert(m4 < 3 && m5 == (m5 & 3)); s390_irgen_VStrX(v1, v2, v3, 255, m4, m5, s390_VStrX_VFEE); - return "vfee"; } -static const HChar * +static void s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vfene", m4 < 3 && m5 == (m5 & 3)); + s390_insn_assert(m4 < 3 && m5 == (m5 & 3)); static const IROp compare_op[3] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4 @@ -18055,13 +15392,13 @@ s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) s390_cc_set(cc); } dis_res->hint = Dis_HintVerbose; - return "vfene"; } -static const HChar * -s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5) +static void +s390_irgen_VISTR( + UChar v1, UChar v2, UChar m3, UChar m4 __attribute__((unused)), UChar m5) { - s390_insn_assert("vistr", m3 < 3 && m5 == (m5 & 1)); + s390_insn_assert(m3 < 3 && m5 == (m5 & 1)); static const IROp compare_op[3] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4 @@ -18089,26 +15426,24 @@ s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5) s390_cc_set(cc); } dis_res->hint = Dis_HintVerbose; - return "vistr"; } -static const HChar * +static void s390_irgen_VSTRC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { - s390_insn_assert("vstrc", m5 <= 2); + s390_insn_assert(m5 <= 2); s390_irgen_VStrX(v1, v2, v3, v4, m5, m6, s390_VStrX_VSTRC); - return "vstrc"; } -static const HChar * +static void s390_irgen_VSTRS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vstrs"; + return; } - s390_insn_assert("vstrs", m5 <= 2 && m6 == (m6 & 2)); + s390_insn_assert(m5 <= 2 && m6 == (m6 & 2)); IRTemp op2 = newTemp(Ity_V128); IRTemp op3 = newTemp(Ity_V128); @@ -18201,248 +15536,276 @@ s390_irgen_VSTRS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) s390_cc_set(cc); dis_res->hint = Dis_HintVerbose; - return "vstrs"; } -static const HChar * +static void s390_irgen_VNC(UChar v1, UChar v2, UChar v3) { put_vr_qw(v1, binop(Iop_AndV128, get_vr_qw(v2), unop(Iop_NotV128, get_vr_qw(v3))) ); - - return "vnc"; } -static const HChar * +static void s390_irgen_VA(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("va", m4 <= 4); - - const IROp ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4, - Iop_Add64x2, Iop_Add128x1 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "va"; + s390_insn_assert(m4 <= 4); + put_vr_qw(v1, s390_V128_add(get_vr_qw(v2), get_vr_qw(v3), m4)); } -static const HChar * +static void s390_irgen_VS(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vs", m4 <= 4); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4, - Iop_Sub64x2, Iop_Sub128x1 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vs"; + put_vr_qw(v1, s390_V128_sub(get_vr_qw(v2), get_vr_qw(v3), m4)); } -static const HChar * +static void s390_irgen_VMX(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmx", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2}; + IRExpr* max; - return "vmx"; + if (m4 < 4) { + max = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + max = s390_V128_bitwiseITE(s390_V128_CmpGTS(mkexpr(a), mkexpr(b), m4), + mkexpr(a), mkexpr(b)); + } + put_vr_qw(v1, max); } -static const HChar * +static void s390_irgen_VMXL(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmxl", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2}; + IRExpr* max; - return "vmxl"; + if (m4 < 4) { + max = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + max = s390_V128_bitwiseITE(s390_V128_CmpGTU(mkexpr(a), mkexpr(b), m4), + mkexpr(a), mkexpr(b)); + } + put_vr_qw(v1, max); } -static const HChar * +static void s390_irgen_VMN(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmn", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2}; + IRExpr* min; - return "vmn"; + if (m4 < 4) { + min = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + IRTemp diff = newTemp(Ity_V128); + assign(diff, binop(Iop_Sub128x1, mkexpr(a), mkexpr(b))); + min = s390_V128_bitwiseITE(s390_V128_CmpGTS(mkexpr(a), mkexpr(b), m4), + mkexpr(b), mkexpr(a)); + } + put_vr_qw(v1, min); } -static const HChar * +static void s390_irgen_VMNL(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmnl", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2}; + IRExpr* min; - return "vmnl"; + if (m4 < 4) { + min = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + IRTemp diff = newTemp(Ity_V128); + assign(diff, binop(Iop_Sub128x1, mkexpr(a), mkexpr(b))); + min = s390_V128_bitwiseITE(s390_V128_CmpGTU(mkexpr(a), mkexpr(b), m4), + mkexpr(b), mkexpr(a)); + } + put_vr_qw(v1, min); } -static const HChar * +static void s390_irgen_VAVG(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vavg", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2}; + IRExpr* avg; - return "vavg"; + if (m4 < 4) { + avg = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + // a/2 + b/2 + ((a | b) & 1) + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + avg = binop(Iop_Add128x1, + binop(Iop_Add128x1, binop(Iop_SarV128, mkexpr(a), mkU8(1)), + binop(Iop_SarV128, mkexpr(b), mkU8(1))), + binop(Iop_AndV128, s390_V128_fillnum(1, m4), + binop(Iop_OrV128, mkexpr(a), mkexpr(b)))); + } + put_vr_qw(v1, avg); } -static const HChar * +static void s390_irgen_VAVGL(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vavgl", m4 <= 3); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + const IROp ops[] = {Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2}; + IRExpr* avg; - return "vavgl"; + if (m4 < 4) { + avg = binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)); + } else { + // a/2 + b/2 + ((a | b) & 1) + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + avg = binop(Iop_Add128x1, + binop(Iop_Add128x1, binop(Iop_ShrV128, mkexpr(a), mkU8(1)), + binop(Iop_ShrV128, mkexpr(b), mkU8(1))), + binop(Iop_AndV128, s390_V128_fillnum(1, m4), + binop(Iop_OrV128, mkexpr(a), mkexpr(b)))); + } + put_vr_qw(v1, avg); } -static const HChar * +static void s390_irgen_VLC(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vlc", m3 < 4); - - IRType type = s390_vr_get_type(m3); - put_vr_qw(v1, s390_V128_get_complement(get_vr_qw(v2), type)); - return "vlc"; + s390_insn_assert(m3 <= 4); + put_vr_qw(v1, s390_V128_get_complement(get_vr_qw(v2), m3)); } -static const HChar * +static void s390_irgen_VLP(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vlp", m3 <= 3); + s390_insn_assert(m3 <= 4); - const IROp ops[] = { Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); - - return "vlp"; + if (m3 < 4) { + const IROp ops[] = {Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2}; + put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); + } else { + IRTemp op = newTemp(Ity_V128); + assign(op, get_vr_qw(v2)); + put_vr_qw(v1, + s390_V128_bitwiseITE( + s390_V128_high_set(mkexpr(op), m3), + s390_V128_get_complement(mkexpr(op), m3), mkexpr(op))); + } } -static const HChar * -s390_irgen_VCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +static void +s390_irgen_VCEQ(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vch", m4 <= 3); - - if (!s390_vr_is_cs_set(m5)) { - const IROp ops[] = { Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4, - Iop_CmpGT64Sx2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - } else { - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); - - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCH; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.m4 = m4; - details.m5 = m5; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); + s390_insn_assert(m4 <= 4); - d->nFxState = 3; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Write; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[2].size = sizeof(V128); + IRTemp res = newTemp(Ity_V128); + assign(res, s390_V128_CmpEQ(get_vr_qw(v2), get_vr_qw(v3), m4)); + put_vr_qw(v1, mkexpr(res)); + if (s390_vr_is_cs_set(m5)) + s390_V128_setcc_for_cmp(res, m4); +} - stmt(IRStmt_Dirty(d)); - s390_cc_set(cc); - } +static void +s390_irgen_VCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +{ + s390_insn_assert(m4 <= 4); - return "vch"; + IRTemp res = newTemp(Ity_V128); + assign(res, s390_V128_CmpGTS(get_vr_qw(v2), get_vr_qw(v3), m4)); + put_vr_qw(v1, mkexpr(res)); + if (s390_vr_is_cs_set(m5)) + s390_V128_setcc_for_cmp(res, m4); } -static const HChar * +static void s390_irgen_VCHL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert("vchl", m4 <= 3); - - if (!s390_vr_is_cs_set(m5)) { - const IROp ops[] = { Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4, - Iop_CmpGT64Ux2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - } else { - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); + s390_insn_assert(m4 <= 4); - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCHL; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.m4 = m4; - details.m5 = m5; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - - d->nFxState = 3; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Write; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[2].size = sizeof(V128); - - stmt(IRStmt_Dirty(d)); - s390_cc_set(cc); - } - - return "vchl"; + IRTemp res = newTemp(Ity_V128); + assign(res, s390_V128_CmpGTU(get_vr_qw(v2), get_vr_qw(v3), m4)); + put_vr_qw(v1, mkexpr(res)); + if (s390_vr_is_cs_set(m5)) + s390_V128_setcc_for_cmp(res, m4); } -static const HChar * +static void s390_irgen_VCLZ(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vclz", m3 <= 3); - - const IROp ops[] = { Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4, Iop_Clz64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); + s390_insn_assert(m3 <= 4); - return "vclz"; + if (m3 < 4) { + const IROp ops[] = {Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4, Iop_Clz64x2}; + put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); + } else { + IRTemp cnt = newTemp(Ity_V128); + IRTemp cnt_h = newTemp(Ity_I64); + assign(cnt, unop(Iop_Clz64x2, get_vr_qw(v2))); + assign(cnt_h, unop(Iop_V128HIto64, mkexpr(cnt))); + put_vr_qw(v1, + binop(Iop_64HLtoV128, mkU64(0), + binop(Iop_Add64, mkexpr(cnt_h), + mkite(binop(Iop_CmpEQ64, mkexpr(cnt_h), mkU64(64)), + unop(Iop_V128to64, mkexpr(cnt)), mkU64(0))))); + } } -static const HChar * +static void s390_irgen_VCTZ(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vctz", m3 <= 3); + s390_insn_assert(m3 <= 4); - const IROp ops[] = { Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2 }; - put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); - - return "vctz"; + if (m3 < 4) { + const IROp ops[] = {Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2}; + put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2))); + } else { + IRTemp cnt = newTemp(Ity_V128); + IRTemp cnt_l = newTemp(Ity_I64); + assign(cnt, unop(Iop_Ctz64x2, get_vr_qw(v2))); + assign(cnt_l, unop(Iop_V128to64, mkexpr(cnt))); + put_vr_qw( + v1, binop(Iop_64HLtoV128, mkU64(0), + binop(Iop_Add64, mkexpr(cnt_l), + mkite(binop(Iop_CmpEQ64, mkexpr(cnt_l), mkU64(64)), + unop(Iop_V128HIto64, mkexpr(cnt)), mkU64(0))))); + } } -static const HChar * +static void s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vpopct", m3 <= 3); + s390_insn_assert(m3 <= 3); IRExpr* cnt = unop(Iop_Cnt8x16, get_vr_qw(v2)); @@ -18455,149 +15818,124 @@ s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3) } } put_vr_qw(v1, cnt); - - return "vpopct"; } -static const HChar * +static void s390_irgen_VML(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vml", m4 <= 2); + s390_insn_assert(m4 <= 4); - const IROp ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vml"; + put_vr_qw(v1, s390_V128_mul(get_vr_qw(v2), get_vr_qw(v3), m4)); } -static const HChar * +static void s390_irgen_VMLH(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmlh", m4 <= 2); - - const IROp ops[] = { Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + s390_insn_assert(m4 <= 4); - return "vmlh"; + put_vr_qw(v1, s390_V128_mula_high(get_vr_qw(v2), get_vr_qw(v3), + NULL, m4, False)); } -static const HChar * +static void s390_irgen_VMH(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmh", m4 <= 2); - - const IROp ops[] = { Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + s390_insn_assert(m4 <= 4); - return "vmh"; + put_vr_qw(v1, s390_V128_mula_high(get_vr_qw(v2), get_vr_qw(v3), + NULL, m4, True)); } -static const HChar * +static void s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmo", m4 <= 2); - - const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); + s390_insn_assert(m4 <= 3); - return "vmo"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_mul_widen(a, b, m4, True, False)); } -static const HChar * +static void s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmlo", m4 <= 2); + s390_insn_assert(m4 <= 3); - const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vmlo"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_mul_widen(a, b, m4, False, False)); } -static const HChar * +static void s390_irgen_VESLV(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vselv", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2}; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "veslv"; } -static const HChar * +static void s390_irgen_VESL(UChar v1, IRTemp op2addr, UChar v3, UChar m4) { - s390_insn_assert("vesl", m4 <= 3); + s390_insn_assert(m4 <= 3); IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr)); const IROp ops[] = { Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount)); - - return "vesl"; } -static const HChar * +static void s390_irgen_VESRAV(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vesrav", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vesrav"; } -static const HChar * +static void s390_irgen_VESRA(UChar v1, IRTemp op2addr, UChar v3, UChar m4) { - s390_insn_assert("vesra", m4 <= 3); + s390_insn_assert(m4 <= 3); IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr)); const IROp ops[] = { Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount)); - - return "vesra"; } -static const HChar * +static void s390_irgen_VESRLV(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vesrlv", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "vesrlv"; } -static const HChar * +static void s390_irgen_VESRL(UChar v1, IRTemp op2addr, UChar v3, UChar m4) { - s390_insn_assert("vesrl", m4 <= 3); + s390_insn_assert(m4 <= 3); IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr)); const IROp ops[] = { Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount)); - - return "vesrl"; } -static const HChar * +static void s390_irgen_VERLLV(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("verllv", m4 <= 3); + s390_insn_assert(m4 <= 3); const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - - return "verllv"; } -static const HChar * +static void s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4) { - s390_insn_assert("verll", m4 <= 3); + s390_insn_assert(m4 <= 3); /* There is no Iop_RolN?x?? operations so we have to use VECTOR x VECTOR variant. @@ -18605,11 +15943,9 @@ s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4) IRExpr* shift_vector = unop(Iop_Dup8x16, unop(Iop_64to8, mkexpr(op2addr))); const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_vector)); - - return "verll"; } -static const HChar * +static void s390_irgen_VSL(UChar v1, UChar v2, UChar v3) { IRTemp a = newTemp(Ity_V128); @@ -18626,10 +15962,9 @@ s390_irgen_VSL(UChar v1, UChar v2, UChar v3) binop(Iop_ShlV128, mkexpr(a), mkU8(8)), unop(Iop_NotV128, mkexpr(b))), unop(Iop_Dup8x16, mkU8(1))))); - return "vsl"; } -static const HChar * +static void s390_irgen_VSRL(UChar v1, UChar v2, UChar v3) { IRTemp a = newTemp(Ity_V128); @@ -18646,10 +15981,9 @@ s390_irgen_VSRL(UChar v1, UChar v2, UChar v3) binop(Iop_ShrV128, mkexpr(a), mkU8(8)), unop(Iop_NotV128, mkexpr(b))), unop(Iop_Dup8x16, mkU8(1))))); - return "vsrl"; } -static const HChar * +static void s390_irgen_VSRA(UChar v1, UChar v2, UChar v3) { IRTemp a = newTemp(Ity_V128); @@ -18672,13 +16006,12 @@ s390_irgen_VSRA(UChar v1, UChar v2, UChar v3) binop(Iop_ShrV128, mkexpr(a), mkU8(8)), unop(Iop_NotV128, mkexpr(b))), unop(Iop_Dup8x16, mkU8(1))))); - return "vsra"; } -static const HChar * +static void s390_irgen_VERIM(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5) { - s390_insn_assert("verim", m5 <= 3); + s390_insn_assert(m5 <= 3); /* There is no Iop_RolN?x?? operations so we have to use VECTOR x VECTOR variant. @@ -18691,157 +16024,142 @@ s390_irgen_VERIM(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5) IRExpr* mask = get_vr_qw(v3); IRExpr* result = get_vr_qw(v1); put_vr_qw(v1, s390_V128_bitwiseITE(mask, rotated_vector, result)); - - return "verim"; } -static const HChar * +static void s390_irgen_VEC(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vec", m3 <= 3); - - IRType type = s390_vr_get_type(m3); - IRTemp op1 = newTemp(type); - IRTemp op2 = newTemp(type); + s390_insn_assert(m3 <= 4); - switch(type) { - case Ity_I8: - assign(op1, get_vr_b7(v1)); - assign(op2, get_vr_b7(v2)); - break; - case Ity_I16: - assign(op1, get_vr_hw3(v1)); - assign(op2, get_vr_hw3(v2)); - break; - case Ity_I32: - assign(op1, get_vr_w1(v1)); - assign(op2, get_vr_w1(v2)); - break; - case Ity_I64: - assign(op1, get_vr_dw0(v1)); - assign(op2, get_vr_dw0(v2)); - break; - default: - vpanic("s390_irgen_VEC: unknown type"); - } - - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); + IRTemp op1, op2; - return "vec"; -} + if (m3 == 4) { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); -static const HChar * -s390_irgen_VECL(UChar v1, UChar v2, UChar m3) -{ - s390_insn_assert("vecl", m3 <= 3); + op1 = newTemp(Ity_I64); + op2 = newTemp(Ity_I64); + assign(a, get_vr_qw(v1)); + assign(b, get_vr_qw(v2)); + assign(op1, unop(Iop_V128to64, + s390_V128_CmpGT128x1(mkexpr(a), mkexpr(b), True, True))); + assign(op2, unop(Iop_V128to64, + s390_V128_CmpGT128x1(mkexpr(b), mkexpr(a), True, True))); + } else { + IRType type = s390_vr_get_type(m3); - IRType type = s390_vr_get_type(m3); - IRTemp op1 = newTemp(type); - IRTemp op2 = newTemp(type); + op1 = newTemp(type); + op2 = newTemp(type); - switch(type) { - case Ity_I8: - assign(op1, get_vr_b7(v1)); - assign(op2, get_vr_b7(v2)); - break; - case Ity_I16: - assign(op1, get_vr_hw3(v1)); - assign(op2, get_vr_hw3(v2)); - break; - case Ity_I32: - assign(op1, get_vr_w1(v1)); - assign(op2, get_vr_w1(v2)); - break; - case Ity_I64: - assign(op1, get_vr_dw0(v1)); - assign(op2, get_vr_dw0(v2)); - break; - default: - vpanic("s390_irgen_VECL: unknown type"); + switch (type) { + case Ity_I8: + assign(op1, get_vr_b7(v1)); + assign(op2, get_vr_b7(v2)); + break; + case Ity_I16: + assign(op1, get_vr_hw3(v1)); + assign(op2, get_vr_hw3(v2)); + break; + case Ity_I32: + assign(op1, get_vr_w1(v1)); + assign(op2, get_vr_w1(v2)); + break; + case Ity_I64: + assign(op1, get_vr_dw0(v1)); + assign(op2, get_vr_dw0(v2)); + break; + default: + vpanic("s390_irgen_VEC: unknown type"); + } } - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "vecl"; + s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); } -static const HChar * -s390_irgen_VCEQ(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +static void +s390_irgen_VECL(UChar v1, UChar v2, UChar m3) { - s390_insn_assert("vceq", m4 <= 3); - - if (!s390_vr_is_cs_set(m5)) { - const IROp ops[] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4, - Iop_CmpEQ64x2 }; - put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - + s390_insn_assert(m3 <= 4); + + IRTemp op1, op2; + + if (m3 == 4) { + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + IRTemp a_hi = newTemp(Ity_I64); + IRTemp b_hi = newTemp(Ity_I64); + IRTemp use_hi = newTemp(Ity_I1); + op1 = newTemp(Ity_I64); + op2 = newTemp(Ity_I64); + assign(a, get_vr_qw(v1)); + assign(b, get_vr_qw(v2)); + assign(a_hi, unop(Iop_V128HIto64, mkexpr(a))); + assign(b_hi, unop(Iop_V128HIto64, mkexpr(b))); + assign(use_hi, binop(Iop_CmpNE64, mkexpr(a_hi), mkexpr(b_hi))); + assign(op1, mkite(mkexpr(use_hi), mkexpr(a_hi), + unop(Iop_V128to64, mkexpr(a)))); + assign(op2, mkite(mkexpr(use_hi), mkexpr(b_hi), + unop(Iop_V128to64, mkexpr(b)))); } else { - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); - - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCEQ; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.m4 = m4; - details.m5 = m5; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); + IRType type = s390_vr_get_type(m3); - d->nFxState = 3; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Write; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[2].size = sizeof(V128); + op1 = newTemp(type); + op2 = newTemp(type); - stmt(IRStmt_Dirty(d)); - s390_cc_set(cc); + switch (type) { + case Ity_I8: + assign(op1, get_vr_b7(v1)); + assign(op2, get_vr_b7(v2)); + break; + case Ity_I16: + assign(op1, get_vr_hw3(v1)); + assign(op2, get_vr_hw3(v2)); + break; + case Ity_I32: + assign(op1, get_vr_w1(v1)); + assign(op2, get_vr_w1(v2)); + break; + case Ity_I64: + assign(op1, get_vr_dw0(v1)); + assign(op2, get_vr_dw0(v2)); + break; + default: + vpanic("s390_irgen_VECL: unknown type"); + } } - return "vceq"; + s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); } -static const HChar * + +static void s390_irgen_VSLB(UChar v1, UChar v2, UChar v3) { IRTemp shift_amount = newTemp(Ity_I8); assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000))); put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount))); - return "vslb"; } -static const HChar * +static void s390_irgen_VSRLB(UChar v1, UChar v2, UChar v3) { IRTemp shift_amount = newTemp(Ity_I8); assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000))); put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount))); - return "vsrlb"; } -static const HChar * +static void s390_irgen_VSRAB(UChar v1, UChar v2, UChar v3) { IRTemp shift_amount = newTemp(Ity_I8); assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000))); put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount))); - return "vsrab"; } -static const HChar * +static void s390_irgen_VSLDB(UChar v1, UChar v2, UChar v3, UChar i4) { UChar imm = i4 & 0b00001111; @@ -18858,19 +16176,17 @@ s390_irgen_VSLDB(UChar v1, UChar v2, UChar v3, UChar i4) ) ); } - - return "vsldb"; } -static const HChar * +static void s390_irgen_VSLD(UChar v1, UChar v2, UChar v3, UChar i4) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vsld"; + return; } - s390_insn_assert("vsld", i4 <= 7); + s390_insn_assert(i4 <= 7); if (i4 == 0) { /* Just copy v2. */ @@ -18884,19 +16200,17 @@ s390_irgen_VSLD(UChar v1, UChar v2, UChar v3, UChar i4) ) ); } - - return "vsld"; } -static const HChar * +static void s390_irgen_VSRD(UChar v1, UChar v2, UChar v3, UChar i4) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vsrd"; + return; } - s390_insn_assert("vsrd", i4 <= 7); + s390_insn_assert(i4 <= 7); if (i4 == 0) { /* Just copy v3. */ @@ -18910,138 +16224,85 @@ s390_irgen_VSRD(UChar v1, UChar v2, UChar v3, UChar i4) ) ); } - - return "vsrd"; } -static const HChar * +static void s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vme", m4 <= 2); + s390_insn_assert(m4 <= 3); - const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, - Iop_MullEven32Sx4 }; - UChar shifts[] = { 8, 16, 32 }; - IRExpr* result = binop(ops[m4], - binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m4])), - binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m4])) - ); - put_vr_qw(v1, result); - - return "vme"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_mul_widen(a, b, m4, True, True)); } -static const HChar * +static void s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmle", m4 <= 2); - - const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, - Iop_MullEven32Ux4 }; - UChar shifts[] = { 8, 16, 32 }; - IRExpr* result = binop(ops[m4], - binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m4])), - binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m4])) - ); - put_vr_qw(v1, result); + s390_insn_assert(m4 <= 3); - return "vmle"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_mul_widen(a, b, m4, False, True)); } -static const HChar * +static void s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmao", m5 <= 2); - - const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, - Iop_MullEven32Sx4 }; - const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2}; - - IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3)); - IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); - put_vr_qw(v1, result); + s390_insn_assert(m5 <= 3); - return "vmao"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_add(s390_V128_mul_widen(a, b, m5, True, False), + get_vr_qw(v4), m5 + 1)); } -static const HChar * +static void s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmalo", m5 <= 2); - - const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, - Iop_MullEven32Ux4 }; - const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 }; - - IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3)); - IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); - put_vr_qw(v1, result); + s390_insn_assert(m5 <= 3); - return "vmalo"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_add(s390_V128_mul_widen(a, b, m5, False, False), + get_vr_qw(v4), m5 + 1)); } -static const HChar * +static void s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmae", m5 <= 2); - - const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, - Iop_MullEven32Sx4 }; - const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 }; - UChar shifts[] = { 8, 16, 32 }; - - IRExpr* mul_result = - binop(mul_ops[m5], - binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m5])), - binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m5]))); - IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); - put_vr_qw(v1, result); + s390_insn_assert(m5 <= 3); - return "vmae"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_add(s390_V128_mul_widen(a, b, m5, True, True), + get_vr_qw(v4), m5 + 1)); } -static const HChar * +static void s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmale", m5 <= 2); - - const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, - Iop_MullEven32Ux4 }; - const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 }; - UChar shifts[] = { 8, 16, 32 }; - - IRExpr* mul_result = binop(mul_ops[m5], - binop(Iop_ShrV128, - get_vr_qw(v2), mkU8(shifts[m5])), - binop(Iop_ShrV128, - get_vr_qw(v3), mkU8(shifts[m5])) - ); + s390_insn_assert(m5 <= 3); - IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); - put_vr_qw(v1, result); - - return "vmale"; + IRExpr* a = get_vr_qw(v2); + IRExpr* b = get_vr_qw(v3); + put_vr_qw(v1, s390_V128_add(s390_V128_mul_widen(a, b, m5, False, True), + get_vr_qw(v4), m5 + 1)); } -static const HChar * +static void s390_irgen_VMAL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmal", m5 <= 2); - - const IROp mul_ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 }; - const IROp add_ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4 }; + s390_insn_assert(m5 <= 4); - IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3)); - IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); - put_vr_qw(v1, result); - - return "vmal"; + put_vr_qw(v1, s390_V128_add(s390_V128_mul(get_vr_qw(v2), get_vr_qw(v3), m5), + get_vr_qw(v4), m5)); } -static const HChar * +static void s390_irgen_VSUM(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vsum", m4 <= 1); + s390_insn_assert(m4 <= 1); IRType type = s390_vr_get_type(m4); IRExpr* mask; @@ -19061,14 +16322,12 @@ s390_irgen_VSUM(UChar v1, UChar v2, UChar v3, UChar m4) IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask); put_vr_qw(v1, binop(Iop_Add32x4, sum, addition)); - - return "vsum"; } -static const HChar * +static void s390_irgen_VSUMG(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vsumg", m4 == 1 || m4 == 2); + s390_insn_assert(m4 == 1 || m4 == 2); IRType type = s390_vr_get_type(m4); IRExpr* mask; @@ -19088,14 +16347,12 @@ s390_irgen_VSUMG(UChar v1, UChar v2, UChar v3, UChar m4) IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask); put_vr_qw(v1, binop(Iop_Add64x2, sum, addition)); - - return "vsumg"; } -static const HChar * +static void s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vsumq", m4 == 2 || m4 == 3); + s390_insn_assert(m4 == 2 || m4 == 3); IRType type = s390_vr_get_type(m4); IRExpr* mask; @@ -19115,11 +16372,9 @@ s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4) IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask); put_vr_qw(v1, binop(Iop_Add128x1, sum, addition)); - - return "vsumq"; } -static const HChar * +static void s390_irgen_VTM(UChar v1, UChar v2) { IRTemp op1 = newTemp(Ity_V128); @@ -19145,13 +16400,12 @@ s390_irgen_VTM(UChar v1, UChar v2) assign(cc, mkite(masked_is_zero, mkU64(0), mkite(diff_is_zero, mkU64(3), mkU64(1)))); s390_cc_set(cc); - return "vtm"; } -static const HChar * +static void s390_irgen_VAC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vac", m5 == 4); + s390_insn_assert(m5 == 4); IRTemp sum = newTemp(Ity_V128); assign(sum, binop(Iop_Add128x1, get_vr_qw(v2), get_vr_qw(v3))); @@ -19159,27 +16413,25 @@ s390_irgen_VAC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1)); IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask); put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in)); - - return "vac"; } -static const HChar * +static void s390_irgen_VACC(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vacc", m4 <= 4); + s390_insn_assert(m4 <= 4); - IRType type = s390_vr_get_type(m4); - IRExpr* arg1 = get_vr_qw(v2); - IRExpr* arg2 = get_vr_qw(v3); + IRTemp arg1 = newTemp(Ity_V128); + assign(arg1, get_vr_qw(v2)); + IRExpr* sum = s390_V128_add(mkexpr(arg1), get_vr_qw(v3), m4); - put_vr_qw(v1, s390_V128_calculate_carry_out(arg1, arg2, type, False)); - return "vacc"; + put_vr_qw(v1, binop(Iop_AndV128, s390_V128_CmpGTU(mkexpr(arg1), sum, m4), + s390_V128_fillnum(1, m4))); } -static const HChar * +static void s390_irgen_VACCC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vaccc", m5 == 4); + s390_insn_assert(m5 == 4); IRExpr* result = s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2), @@ -19188,10 +16440,9 @@ s390_irgen_VACCC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) ); put_vr_qw(v1, result); - return "vaccc"; } -static const HChar* +static void s390_irgen_VCKSM(UChar v1, UChar v2, UChar v3) { @@ -19202,14 +16453,12 @@ s390_irgen_VCKSM(UChar v1, UChar v2, UChar v3) put_vr_qw(v1, binop(Iop_64HLtoV128, unop(Iop_32Uto64, mkexpr(result)), mkU64(0ULL))); - - return "vcksm"; } -static const HChar * +static void s390_irgen_VGFM(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vgfm", m4 <= 3); + s390_insn_assert(m4 <= 3); IRDirty* d; IRTemp cc = newTemp(Ity_I64); @@ -19239,13 +16488,12 @@ s390_irgen_VGFM(UChar v1, UChar v2, UChar v3, UChar m4) d->fxState[2].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - return "vgfm"; } -static const HChar * +static void s390_irgen_VGFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vgfma", m5 <= 3); + s390_insn_assert(m5 <= 3); IRDirty* d; IRTemp cc = newTemp(Ity_I64); @@ -19279,13 +16527,12 @@ s390_irgen_VGFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) d->fxState[3].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - return "vgfma"; } -static const HChar * +static void s390_irgen_VSBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vsbi", m5 == 4); + s390_insn_assert(m5 == 4); IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0ULL), mkU64(1ULL)); IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask); @@ -19298,27 +16545,27 @@ s390_irgen_VSBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) ); put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in)); - return "vsbi"; } -static const HChar * +static void s390_irgen_VSCBI(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vscbi", m4 <= 4); + s390_insn_assert(m4 <= 4); - IRType type = s390_vr_get_type(m4); - IRExpr* arg1 = get_vr_qw(v2); - IRExpr* arg2 = s390_V128_get_complement(get_vr_qw(v3), type); - IRExpr* result = s390_V128_calculate_carry_out(arg1, arg2, type, True); + IRTemp arg1 = newTemp(Ity_V128); + assign(arg1, get_vr_qw(v2)); + IRExpr* diff = s390_V128_sub(mkexpr(arg1), get_vr_qw(v3), m4); - put_vr_qw(v1, result); - return "vscbi"; + put_vr_qw(v1, binop(Iop_AndV128, + unop(Iop_NotV128, + s390_V128_CmpGTU(diff, mkexpr(arg1), m4)), + s390_V128_fillnum(1, m4))); } -static const HChar * +static void s390_irgen_VSBCBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vsbcbi", m5 == 4); + s390_insn_assert(m5 == 4); IRExpr* result = s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2), @@ -19326,100 +16573,35 @@ s390_irgen_VSBCBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) get_vr_qw(v4)); put_vr_qw(v1, result); - return "vsbcbi"; } -static const HChar * +static void s390_irgen_VMAH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmah", m5 < 3); - - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); + s390_insn_assert(m5 <= 4); - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VMAH; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.v4 = v4; - details.m4 = m5; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - - d->nFxState = 4; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Read; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128); - d->fxState[2].size = sizeof(V128); - d->fxState[3].fx = Ifx_Write; - d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[3].size = sizeof(V128); - - stmt(IRStmt_Dirty(d)); - - return "vmah"; + put_vr_qw(v1, s390_V128_mula_high(get_vr_qw(v2), get_vr_qw(v3), + get_vr_qw(v4), m5, True)); } -static const HChar * +static void s390_irgen_VMALH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmalh", m5 < 3); - - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); - - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VMALH; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.v4 = v4; - details.m4 = m5; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - - d->nFxState = 4; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Read; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128); - d->fxState[2].size = sizeof(V128); - d->fxState[3].fx = Ifx_Write; - d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[3].size = sizeof(V128); + s390_insn_assert(m5 <= 4); - stmt(IRStmt_Dirty(d)); - - return "vmalh"; + put_vr_qw(v1, s390_V128_mula_high(get_vr_qw(v2), get_vr_qw(v3), + get_vr_qw(v4), m5, False)); } -static const HChar * +static void s390_irgen_VMSL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vmsl"; + return; } - s390_insn_assert("vmsl", m5 == 3 && (m6 & 3) == 0); + s390_insn_assert(m5 == 3); IRDirty* d; IRTemp cc = newTemp(Ity_I64); @@ -19454,8 +16636,6 @@ s390_irgen_VMSL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) d->fxState[3].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - - return "vmsl"; } static void @@ -19486,10 +16666,6 @@ s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, Bool rounding, IRExpr* argument = get_vr(v2, fromType, i * sourceIndexScaleFactor); IRExpr* result; if (rounding) { - if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { - emulation_warning(EmWarn_S390X_fpext_rounding); - m5 = S390_BFP_ROUND_PER_FPC; - } result = binop(op, mkexpr(encode_bfp_rounding_mode(m5)), argument); @@ -19500,69 +16676,64 @@ s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, Bool rounding, } } -static const HChar * +static void s390_irgen_VCDG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vcdg", m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); - s390_insn_assert("vcdg", (m4 & 0x3) == 0); - s390_insn_assert("vcdg", m5 != 2 && m5 <= 7); + s390_insn_assert(m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); s390_vector_fp_convert(m3 == 2 ? Iop_I32StoF32 : Iop_I64StoF64, m3 == 2 ? Ity_I32 : Ity_I64, m3 == 2 ? Ity_F32 : Ity_F64, True, v1, v2, m3, m4, m5); - return "vcdg"; } -static const HChar * +static void s390_irgen_VCDLG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vcdlg", m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); - s390_insn_assert("vcdlg", (m4 & 0x3) == 0); - s390_insn_assert("vcdlg", m5 != 2 && m5 <= 7); + s390_insn_assert(m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); s390_vector_fp_convert(m3 == 2 ? Iop_I32UtoF32 : Iop_I64UtoF64, m3 == 2 ? Ity_I32 : Ity_I64, m3 == 2 ? Ity_F32 : Ity_F64, True, v1, v2, m3, m4, m5); - return "vcdlg"; } -static const HChar * +static void s390_irgen_VCGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vcgd", m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); - s390_insn_assert("vcgd", (m4 & 0x3) == 0); - s390_insn_assert("vcgd", m5 != 2 && m5 <= 7); + s390_insn_assert(m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); s390_vector_fp_convert(m3 == 2 ? Iop_F32toI32S : Iop_F64toI64S, m3 == 2 ? Ity_F32 : Ity_F64, m3 == 2 ? Ity_I32 : Ity_I64, True, v1, v2, m3, m4, m5); - return "vcgd"; } -static const HChar * +static void s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vclgd", m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); - s390_insn_assert("vclgd", (m4 & 0x3) == 0); - s390_insn_assert("vclgd", m5 != 2 && m5 <= 7); + s390_insn_assert(m3 == 3 || (m3 == 2 && s390_host_has_vxe2)); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); s390_vector_fp_convert(m3 == 2 ? Iop_F32toI32U : Iop_F64toI64U, m3 == 2 ? Ity_F32 : Ity_F64, m3 == 2 ? Ity_I32 : Ity_I64, True, v1, v2, m3, m4, m5); - return "vclgd"; } -static const HChar * +static void s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vfi", - (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); - s390_insn_assert("vfi", (m4 & 0x3) == 0); - s390_insn_assert("vfi", m5 != 2 && m5 <= 7); + s390_insn_assert((m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); switch (m3) { case 2: s390_vector_fp_convert(Iop_RoundF32toInt, Ity_F32, Ity_F32, True, @@ -19572,15 +16743,13 @@ s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) case 4: s390_vector_fp_convert(Iop_RoundF128toInt, Ity_F128, Ity_F128, True, v1, v2, m3, m4, m5); break; } - - return "vfi"; } -static const HChar * +static void s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4) { - s390_insn_assert("vfll", m3 == 2 || (s390_host_has_vxe && m3 == 3)); - s390_insn_assert("vfll", (m4 & 0x7) == 0); + s390_insn_assert(m3 == 2 || (s390_host_has_vxe && m3 == 3)); + s390_insn_assert((m4 & 0x7) == 0); if (m3 == 2) s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, False, @@ -19588,16 +16757,14 @@ s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4) else s390_vector_fp_convert(Iop_F64toF128, Ity_F64, Ity_F128, False, v1, v2, m3, m4, /* don't care */ 0); - - return "vfll"; } -static const HChar * +static void s390_irgen_VFLR(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vflr", m3 == 3 || (s390_host_has_vxe && m3 == 4)); - s390_insn_assert("vflr", (m4 & 0x3) == 0); - s390_insn_assert("vflr", m5 != 2 && m5 <= 7); + s390_insn_assert(m3 == 3 || (s390_host_has_vxe && m3 == 4)); + s390_insn_assert((m4 & 0x3) == 0); + s390_insn_assert(m5 != 2 && m5 <= 7); if (m3 == 3) s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, True, @@ -19605,16 +16772,14 @@ s390_irgen_VFLR(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) else s390_vector_fp_convert(Iop_F128toF64, Ity_F128, Ity_F64, True, v1, v2, m3, m4, m5); - - return "vflr"; } -static const HChar * +static void s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - s390_insn_assert("vfpso", m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)); - s390_insn_assert("vfpso", (m4 & 0x7) == 0); - s390_insn_assert("vfpso", m5 <= 2); + s390_insn_assert(m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)); + s390_insn_assert((m4 & 0x7) == 0); + s390_insn_assert(m5 <= 2); Bool single = s390_vr_is_single_element_control_set(m4) || m3 == 4; IRType type = single ? s390_vr_get_ftype(m3) : Ity_V128; @@ -19641,16 +16806,14 @@ s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) const IROp *ops = m5 == 2 ? abs_ops : negate_ops; put_vr(v1, type, 0, unop(ops[idx], get_vr(v2, type, 0))); } - - return "vfpso"; } -static const HChar * -s390x_vec_fp_binary_op(const HChar* mnm, const IROp ops[], +static void +s390x_vec_fp_binary_op(const IROp ops[], UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - s390_insn_assert(mnm, (m5 & 7) == 0 && + s390_insn_assert((m5 & 7) == 0 && (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); int idx = 2 * (m4 - 2); @@ -19664,15 +16827,13 @@ s390x_vec_fp_binary_op(const HChar* mnm, const IROp ops[], put_vr_qw(v1, triop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(), get_vr_qw(v2), get_vr_qw(v3))); } - - return mnm; } -static const HChar * -s390x_vec_fp_unary_op(const HChar* mnm, const IROp ops[], +static void +s390x_vec_fp_unary_op(const IROp ops[], UChar v1, UChar v2, UChar m3, UChar m4) { - s390_insn_assert(mnm, (m4 & 7) == 0 && + s390_insn_assert((m4 & 7) == 0 && (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); int idx = 2 * (m3 - 2); @@ -19687,19 +16848,17 @@ s390x_vec_fp_unary_op(const HChar* mnm, const IROp ops[], put_vr_qw(v1, binop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(), get_vr_qw(v2))); } - - return mnm; } -static const HChar * +static void s390_vector_fp_mulAddOrSub(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6, - const HChar* mnm, const IROp single_ops[], + const IROp single_ops[], Bool negate) { - s390_insn_assert(mnm, (m5 & 0x7) == 0); - s390_insn_assert(mnm, m6 == 3 || (s390_host_has_vxe && m6 >= 2 && m6 <= 4)); + s390_insn_assert((m5 & 0x7) == 0); + s390_insn_assert(m6 == 3 || (s390_host_has_vxe && m6 >= 2 && m6 <= 4)); static const IROp negate_ops[] = { Iop_NegF32, Iop_NegF64, Iop_NegF128 }; IRType type = s390_vr_get_ftype(m6); @@ -19717,10 +16876,9 @@ s390_vector_fp_mulAddOrSub(UChar v1, UChar v2, UChar v3, UChar v4, get_vr(v4, type, idx)); put_vr(v1, type, idx, negate ? unop(negate_ops[m6 - 2], result) : result); } - return mnm; } -static const HChar * +static void s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { static const IROp vfa_ops[] = { @@ -19728,10 +16886,10 @@ s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) Iop_AddF64, Iop_Add64Fx2, Iop_AddF128, }; - return s390x_vec_fp_binary_op("vfa", vfa_ops, v1, v2, v3, m4, m5); + s390x_vec_fp_binary_op(vfa_ops, v1, v2, v3, m4, m5); } -static const HChar * +static void s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { static const IROp vfs_ops[] = { @@ -19739,10 +16897,10 @@ s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) Iop_SubF64, Iop_Sub64Fx2, Iop_SubF128, }; - return s390x_vec_fp_binary_op("vfs", vfs_ops, v1, v2, v3, m4, m5); + s390x_vec_fp_binary_op(vfs_ops, v1, v2, v3, m4, m5); } -static const HChar * +static void s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { static const IROp vfm_ops[] = { @@ -19750,10 +16908,10 @@ s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) Iop_MulF64, Iop_Mul64Fx2, Iop_MulF128, }; - return s390x_vec_fp_binary_op("vfm", vfm_ops, v1, v2, v3, m4, m5); + s390x_vec_fp_binary_op(vfm_ops, v1, v2, v3, m4, m5); } -static const HChar * +static void s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { static const IROp vfd_ops[] = { @@ -19761,10 +16919,10 @@ s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) Iop_DivF64, Iop_Div64Fx2, Iop_DivF128, }; - return s390x_vec_fp_binary_op("vfd", vfd_ops, v1, v2, v3, m4, m5); + s390x_vec_fp_binary_op(vfd_ops, v1, v2, v3, m4, m5); } -static const HChar * +static void s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4) { static const IROp vfsq_ops[] = { @@ -19772,59 +16930,59 @@ s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4) Iop_SqrtF64, Iop_Sqrt64Fx2, Iop_SqrtF128 }; - return s390x_vec_fp_unary_op("vfsq", vfsq_ops, v1, v2, m3, m4); + s390x_vec_fp_unary_op(vfsq_ops, v1, v2, m3, m4); } static const IROp FMA_single_ops[] = { Iop_MAddF32, Iop_MAddF64, Iop_MAddF128 }; -static const HChar * +static void s390_irgen_VFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { - return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, - "vfma", FMA_single_ops, False); + s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, + FMA_single_ops, False); } -static const HChar * +static void s390_irgen_VFNMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vfnma"; + return; } - return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, - "vfnma", FMA_single_ops, True); + s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, + FMA_single_ops, True); } static const IROp FMS_single_ops[] = { Iop_MSubF32, Iop_MSubF64, Iop_MSubF128 }; -static const HChar * +static void s390_irgen_VFMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { - return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, - "vfms", FMS_single_ops, False); + s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, + FMS_single_ops, False); } -static const HChar * +static void s390_irgen_VFNMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vfnms"; + return; } - return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, - "vfnms", FMS_single_ops, True); + s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, + FMS_single_ops, True); } -static const HChar * +static void s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4) { - s390_insn_assert("wfc", m4 == 0 && + s390_insn_assert(m4 == 0 && (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); static const IROp ops[] = { Iop_CmpF32, Iop_CmpF64, Iop_CmpF128 }; @@ -19836,27 +16994,23 @@ s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4) IRTemp cc_s390 = newTemp(Ity_I32); assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); - - return "wfc"; } -static const HChar * +static void s390_irgen_WFK(UChar v1, UChar v2, UChar m3, UChar m4) { - s390_insn_assert("wfk", m4 == 0 && + s390_insn_assert(m4 == 0 && (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); s390_irgen_WFC(v1, v2, m3, m4); - - return "wfk"; } -static const HChar * +static void s390_irgen_VFCx(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6, - const HChar *mnem, IRCmpFResult cmp, Bool equal_ok, + IRCmpFResult cmp, Bool equal_ok, IROp cmp32, IROp cmp64) { - s390_insn_assert(mnem, (m5 & 3) == 0 && (m6 & 14) == 0 && + s390_insn_assert((m5 & 3) == 0 && (m6 & 14) == 0 && (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); Bool single = s390_vr_is_single_element_control_set(m5) || m4 == 4; @@ -19910,39 +17064,36 @@ s390_irgen_VFCx(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6, s390_cc_set(cc); } } - - return mnem; } -static const HChar * +static void s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { - return s390_irgen_VFCx(v1, v2, v3, m4, m5, m6, "vfce", Ircr_EQ, - False, Iop_CmpEQ32Fx4, Iop_CmpEQ64Fx2); + s390_irgen_VFCx(v1, v2, v3, m4, m5, m6, Ircr_EQ, + False, Iop_CmpEQ32Fx4, Iop_CmpEQ64Fx2); } -static const HChar * +static void s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { /* Swap arguments and compare "low" instead. */ - return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfch", Ircr_LT, - False, Iop_CmpLT32Fx4, Iop_CmpLT64Fx2); + s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, Ircr_LT, + False, Iop_CmpLT32Fx4, Iop_CmpLT64Fx2); } -static const HChar * +static void s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { /* Swap arguments and compare "low or equal" instead. */ - return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfche", Ircr_LT, - True, Iop_CmpLE32Fx4, Iop_CmpLE64Fx2); + s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, Ircr_LT, + True, Iop_CmpLE32Fx4, Iop_CmpLE64Fx2); } -static const HChar * +static void s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5) { - s390_insn_assert("vftci", - (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); - s390_insn_assert("vftci", (m5 & 0x7) == 0); + s390_insn_assert((m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); + s390_insn_assert((m5 & 0x7) == 0); Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); @@ -19975,21 +17126,19 @@ s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5) stmt(IRStmt_Dirty(d)); s390_cc_set(cc); - - return "vftci"; } -static const HChar * +static void s390_irgen_VFMIN(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vfmin"; + return; } - s390_insn_assert("vfmin", m4 >= 2 && m4 <= 4); - s390_insn_assert("vfmin", (m5 & 0x7) == 0); - s390_insn_assert("vfmin", m6 <= 4 || (m6 >= 8 && m6 <= 12)); + s390_insn_assert(m4 >= 2 && m4 <= 4); + s390_insn_assert((m5 & 0x7) == 0); + s390_insn_assert(m6 <= 4 || (m6 >= 8 && m6 <= 12)); Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); IRDirty* d; @@ -20023,20 +17172,19 @@ s390_irgen_VFMIN(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) d->fxState[2].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - return "vfmin"; } -static const HChar * +static void s390_irgen_VFMAX(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vfmax"; + return; } - s390_insn_assert("vfmax", m4 >= 2 && m4 <= 4); - s390_insn_assert("vfmax", (m5 & 0x7) == 0); - s390_insn_assert("vfmax", m6 <= 4 || (m6 >= 8 && m6 <= 12)); + s390_insn_assert(m4 >= 2 && m4 <= 4); + s390_insn_assert((m5 & 0x7) == 0); + s390_insn_assert(m6 <= 4 || (m6 >= 8 && m6 <= 12)); Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); IRDirty* d; @@ -20070,15 +17218,14 @@ s390_irgen_VFMAX(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) d->fxState[2].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - return "vfmax"; } -static const HChar * +static void s390_irgen_VBPERM(UChar v1, UChar v2, UChar v3) { if (! s390_host_has_vxe) { emulation_failure(EmFail_S390X_vxe); - return "vbperm"; + return; } IRDirty* d; @@ -20112,31 +17259,27 @@ s390_irgen_VBPERM(UChar v1, UChar v2, UChar v3) stmt(IRStmt_Dirty(d)); s390_cc_set(cc); - return "vbperm"; } -static const HChar * +static void s390_irgen_SELR(UChar r3, UChar m4, UChar r1, UChar r2) { IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0)); put_gpr_w1(r1, mkite(cond, get_gpr_w1(r2), get_gpr_w1(r3))); - return "selr"; } -static const HChar * +static void s390_irgen_SELGR(UChar r3, UChar m4, UChar r1, UChar r2) { IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0)); put_gpr_dw0(r1, mkite(cond, get_gpr_dw0(r2), get_gpr_dw0(r3))); - return "selgr"; } -static const HChar * +static void s390_irgen_SELFHR(UChar r3, UChar m4, UChar r1, UChar r2) { IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0)); put_gpr_w0(r1, mkite(cond, get_gpr_w0(r2), get_gpr_w0(r3))); - return "selfhr"; } /* Helper function that byte-swaps each element of its V128 input operand */ @@ -20168,60 +17311,56 @@ s390_reverse_elements(IRExpr* v, UChar m) mkU64(perm[m - 1][1]))); } -static const HChar * +static void s390_irgen_VLBR(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vlbr"; + return; } - s390_insn_assert("vlbr", m3 >= 1 && m3 <= 4); + s390_insn_assert(m3 >= 1 && m3 <= 4); put_vr_qw(v1, s390_byteswap_elements(load(Ity_V128, mkexpr(op2addr)), m3)); - return "vlbr"; } -static const HChar * +static void s390_irgen_VSTBR(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vstbr"; + return; } - s390_insn_assert("vstbr", m3 >= 1 && m3 <= 4); + s390_insn_assert(m3 >= 1 && m3 <= 4); store(mkexpr(op2addr), s390_byteswap_elements(get_vr_qw(v1), m3)); - return "vstbr"; } -static const HChar * +static void s390_irgen_VLER(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vler"; + return; } - s390_insn_assert("vler", m3 >= 1 && m3 <= 3); + s390_insn_assert(m3 >= 1 && m3 <= 3); put_vr_qw(v1, s390_reverse_elements(load(Ity_V128, mkexpr(op2addr)), m3)); - return "vler"; } -static const HChar * +static void s390_irgen_VSTER(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vster"; + return; } - s390_insn_assert("vster", m3 >= 1 && m3 <= 4); + s390_insn_assert(m3 >= 1 && m3 <= 3); store(mkexpr(op2addr), s390_reverse_elements(get_vr_qw(v1), m3)); - return "vster"; } /* Helper function that combines its two V128 operands by replacing element 'to' @@ -20247,33 +17386,32 @@ s390_insert_byteswapped(IRExpr* a, IRExpr* b, UChar m, UChar to, UChar from) mkU64(permH), mkU64(permL))); } -static const HChar * +static void s390_irgen_VLEBRH(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vlebrh"; + return; } - s390_insn_assert("vlebrh", m3 <= 7); + s390_insn_assert(m3 <= 7); IRTemp op2 = newTemp(Ity_I16); assign(op2, load(Ity_I16, mkexpr(op2addr))); put_vr(v1, Ity_I16, m3, binop(Iop_Or16, binop(Iop_Shl16, mkexpr(op2), mkU8(8)), binop(Iop_Shr16, mkexpr(op2), mkU8(8)))); - return "vlebrh"; } -static const HChar * +static void s390_irgen_VLEBRF(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vlebrf"; + return; } - s390_insn_assert("vlebrf", m3 <= 3); + s390_insn_assert(m3 <= 3); IRTemp op1 = newTemp(Ity_V128); assign(op1, get_vr_qw(v1)); @@ -20281,18 +17419,17 @@ s390_irgen_VLEBRF(UChar v1, IRTemp op2addr, UChar m3) assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); IRExpr* b = binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2)); put_vr_qw(v1, s390_insert_byteswapped(mkexpr(op1), b, 2, m3, 3)); - return "vlebrf"; } -static const HChar * +static void s390_irgen_VLEBRG(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vlebrg"; + return; } - s390_insn_assert("vlebrg", m3 <= 1); + s390_insn_assert(m3 <= 1); IRTemp op1 = newTemp(Ity_V128); assign(op1, get_vr_qw(v1)); @@ -20300,18 +17437,17 @@ s390_irgen_VLEBRG(UChar v1, IRTemp op2addr, UChar m3) assign(op2, load(Ity_I64, mkexpr(op2addr))); IRExpr* b = binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2)); put_vr_qw(v1, s390_insert_byteswapped(mkexpr(op1), b, 3, m3, 1)); - return "vlebrg"; } -static const HChar * +static void s390_irgen_VLBRREP(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vlbrrep"; + return; } - s390_insn_assert("vlbrrep", m3 >= 1 && m3 <= 3); + s390_insn_assert(m3 >= 1 && m3 <= 3); static const ULong perm[3] = { 0x0f0e0f0e0f0e0f0e, /* 2-byte element */ @@ -20328,18 +17464,17 @@ s390_irgen_VLBRREP(UChar v1, IRTemp op2addr, UChar m3) put_vr_qw(v1, binop(Iop_Perm8x16, binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2)), binop(Iop_64HLtoV128, permHL, permHL))); - return "vlbrrep"; } -static const HChar * +static void s390_irgen_VLLEBRZ(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vllebrz"; + return; } - s390_insn_assert("vllebrz", (m3 >= 1 && m3 <= 3) || m3 == 6); + s390_insn_assert((m3 >= 1 && m3 <= 3) || m3 == 6); static const ULong perm[6] = { 0x0000000000000f0e, /* 2-byte element */ @@ -20359,68 +17494,64 @@ s390_irgen_VLLEBRZ(UChar v1, IRTemp op2addr, UChar m3) put_vr_qw(v1, binop(Iop_Perm8x16, binop(Iop_64HLtoV128, mkU64(0), mkexpr(op2)), binop(Iop_64HLtoV128, permH, mkU64(0)))); - return "vllebrz"; } -static const HChar * +static void s390_irgen_VSTEBRH(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vstebrh"; + return; } - s390_insn_assert("vstebrh", m3 <= 7); + s390_insn_assert(m3 <= 7); IRTemp op1 = newTemp(Ity_I16); assign(op1, get_vr(v1, Ity_I16, m3)); store(mkexpr(op2addr), binop(Iop_Or16, binop(Iop_Shl16, mkexpr(op1), mkU8(8)), binop(Iop_Shr16, mkexpr(op1), mkU8(8)))); - return "vstebrh"; } -static const HChar * +static void s390_irgen_VSTEBRF(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vstebrf"; + return; } - s390_insn_assert("vstebrf", m3 <= 3); + s390_insn_assert(m3 <= 3); IRTemp op1 = newTemp(Ity_V128); assign(op1, get_vr_qw(v1)); IRExpr* b = s390_insert_byteswapped(mkexpr(op1), mkexpr(op1), 2, 3, m3); store(mkexpr(op2addr), unop(Iop_V128to32, b)); - return "vstebrf"; } -static const HChar * +static void s390_irgen_VSTEBRG(UChar v1, IRTemp op2addr, UChar m3) { if (! s390_host_has_vxe2) { emulation_failure(EmFail_S390X_vxe2); - return "vstebrg"; + return; } - s390_insn_assert("vstebrg", m3 <= 1); + s390_insn_assert(m3 <= 1); IRTemp op1 = newTemp(Ity_V128); assign(op1, get_vr_qw(v1)); IRExpr* b = s390_insert_byteswapped(mkexpr(op1), mkexpr(op1), 3, 1, m3); store(mkexpr(op2addr), unop(Iop_V128to64, b)); - return "vstebrg"; } -static const HChar * -s390_irgen_VCxx(const HChar *mnem, s390x_vec_op_details_t details, +static void +s390_irgen_VCxx(s390x_vec_op_details_t details, UShort v2_offs, UShort v2_size) { if (! s390_host_has_nnpa) { emulation_failure(EmFail_S390X_nnpa); - return mnem; + return; } IRDirty* d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op", @@ -20439,10 +17570,9 @@ s390_irgen_VCxx(const HChar *mnem, s390x_vec_op_details_t details, d->fxState[1].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - return mnem; } -static const HChar * +static void s390_irgen_VCNF(UChar v1, UChar v2, UChar m3, UChar m4) { s390x_vec_op_details_t details = { .serialized = 0ULL }; @@ -20451,258 +17581,601 @@ s390_irgen_VCNF(UChar v1, UChar v2, UChar m3, UChar m4) details.v2 = v2; details.m3 = m3; details.m4 = m4; - return s390_irgen_VCxx("vcnf", details, 0, sizeof(V128)); + s390_irgen_VCxx( details, 0, sizeof(V128)); +} + +static void +s390_irgen_VCLFNH(UChar v1, UChar v2, UChar m3, UChar m4) +{ + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VCLFNH; + details.v1 = v1; + details.v2 = v2; + details.m3 = m3; + details.m4 = m4; + s390_irgen_VCxx(details, 0, sizeof(V128) / 2); +} + +static void +s390_irgen_VCFN(UChar v1, UChar v2, UChar m3, UChar m4) +{ + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VCFN; + details.v1 = v1; + details.v2 = v2; + details.m3 = m3; + details.m4 = m4; + s390_irgen_VCxx(details, 0, sizeof(V128)); +} + +static void +s390_irgen_VCLFNL(UChar v1, UChar v2, UChar m3, UChar m4) +{ + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VCLFNL; + details.v1 = v1; + details.v2 = v2; + details.m3 = m3; + details.m4 = m4; + s390_irgen_VCxx(details, sizeof(V128) / 2, sizeof(V128) / 2); +} + +static void +s390_irgen_VCRNF(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +{ + if (! s390_host_has_nnpa) { + emulation_failure(EmFail_S390X_nnpa); + return; + } + + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VCRNF; + details.v1 = v1; + details.v2 = v2; + details.v3 = v3; + details.m4 = m4; + details.m5 = m5; + details.m6 = 0; + IRDirty* d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op", + &s390x_dirtyhelper_vec_op, + mkIRExprVec_2(IRExpr_GSPTR(), + mkU64(details.serialized))); + d->nFxState = 3; + vex_bzero(&d->fxState, sizeof(d->fxState)); + d->fxState[0].fx = Ifx_Read; + d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); + d->fxState[0].size = sizeof(V128); + d->fxState[1].fx = Ifx_Read; + d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); + d->fxState[1].size = sizeof(V128); + d->fxState[2].fx = Ifx_Write; + d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); + d->fxState[2].size = sizeof(V128); + + stmt(IRStmt_Dirty(d)); +} + +static void +s390_irgen_NNPA(void) +{ + if (! s390_host_has_nnpa) { + emulation_failure(EmFail_S390X_nnpa); + return; + } + extension(S390_EXT_NNPA, 0); +} + +static void +s390_irgen_KM(UChar r1, UChar r2) +{ + s390_insn_assert(r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KM, r1 | (r2 << 4)); +} + +static void +s390_irgen_KMC(UChar r1, UChar r2) +{ + s390_insn_assert(r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KMC, r1 | (r2 << 4)); +} + +static void +s390_irgen_KIMD(UChar r1, UChar r2, UChar m3) +{ + /* r1 is reserved */ + s390_insn_assert(r2 != 0 && r2 % 2 == 0); + if (!s390_host_has_msa12) { + m3 = 0; + } + extension(S390_EXT_KIMD, r1 | (r2 << 4) | (m3 << 8)); +} + +static void +s390_irgen_KLMD(UChar r1, UChar r2, UChar m3) +{ + /* r1 is only used by some functions */ + s390_insn_assert(r2 != 0 && r2 % 2 == 0); + if (!s390_host_has_msa12) { + m3 = 0; + } + extension(S390_EXT_KLMD, r1 | (r2 << 4) | (m3 << 8)); +} + +static void +s390_irgen_KMAC(UChar r1, UChar r2) +{ + /* r1 is ignored */ + s390_insn_assert(r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KMAC, r1 | (r2 << 4)); +} + +static void +s390_irgen_PCC(void) +{ + extension(S390_EXT_PCC, 0); +} + +static void +s390_irgen_KMCTR(UChar r3, UChar r1, UChar r2) +{ + s390_insn_assert(r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 && + r3 % 2 == 0 && r3 != 0); + extension(S390_EXT_KMCTR, r1 | (r2 << 4) | (r3 << 8)); +} + +static void +s390_irgen_KMO(UChar r1, UChar r2) +{ + s390_insn_assert(r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KMO, r1 | (r2 << 4)); +} + +static void +s390_irgen_KMF(UChar r1, UChar r2) +{ + s390_insn_assert(r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KMF, r1 | (r2 << 4)); +} + +static void +s390_irgen_KMA(UChar r3, UChar r1, UChar r2) +{ + if (! s390_host_has_msa8) { + emulation_failure(EmFail_S390X_msa8); + return; + } + s390_insn_assert(r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 && + r3 % 2 == 0 && r3 != 0 && r3 != r1 && r3 != r2); + extension(S390_EXT_KMA, r1 | (r2 << 4) | (r3 << 8)); +} + +static void +s390_irgen_KDSA(UChar r1, UChar r2) +{ + if (! s390_host_has_msa9) { + emulation_failure(EmFail_S390X_msa9); + return; + } + /* r1 is reserved */ + s390_insn_assert(r2 != 0 && r2 % 2 == 0); + extension(S390_EXT_KDSA, r1 | (r2 << 4)); +} + +static void +s390_irgen_BPP(UChar m1, UShort i2, IRTemp op3addr) +{ + /* Treat as a no-op */ +} + +static void +s390_irgen_BPRP(UChar m1, UShort i2, UInt i3) +{ + /* Treat as a no-op */ +} + +static void +s390_irgen_NIAI(UChar i1, UChar i2) +{ + /* Treat as a no-op */ +} + +static void +s390_irgen_PPA(UChar m3, UChar r1, UChar r2) +{ + /* Treat as a no-op. m3 could indicate one of the following: + 1: transaction-abort assist -- fine, we don't support transactions + 15: in-order-execution assist -- we don't claim support */ +} + +static void +s390_irgen_CLZG(UChar r1, UChar r2) +{ + put_gpr_dw0(r1, unop(Iop_ClzNat64, get_gpr_dw0(r2))); +} + +static void +s390_irgen_CTZG(UChar r1, UChar r2) +{ + IRTemp op2 = newTemp(Ity_I64); + + assign(op2, get_gpr_dw0(r2)); + put_gpr_dw0( + r1, binop(Iop_Sub64, mkU64(64), + unop(Iop_ClzNat64, + binop(Iop_And64, binop(Iop_Sub64, mkexpr(op2), mkU64(1)), + unop(Iop_Not64, mkexpr(op2)))))); +} + +/* Helper for BEXTG and BDEPG -- they share much of the logic */ +static void +s390_irgen_BExtDep(UChar r3, UChar r1, UChar r2, Bool do_ext) +{ + IRTemp op2 = newTemp(Ity_I64); + IRTemp op3 = newTemp(Ity_I64); + IRTemp movemask[6]; + IRExpr* mk; + IRExpr* x; + + assign(op2, get_gpr_dw0(r2)); + assign(op3, get_gpr_dw0(r3)); + + x = mkexpr(op3); + mk = binop(Iop_Shr64, unop(Iop_Not64, mkexpr(op3)), mkU8(1)); + for (int i = 0; i < 6; i++) { + IRTemp mki = newTemp(Ity_I64); + IRExpr* mpx; + assign(mki, mk); + mpx = mkexpr(mki); + for (int j = 0; j < 6; j++) { + IRTemp mpj = newTemp(Ity_I64); + assign(mpj, mpx); + mpx = binop(Iop_Xor64, mkexpr(mpj), + binop(Iop_Shr64, mkexpr(mpj), mkU8(1 << j))); + } + IRTemp mp = newTemp(Ity_I64); + IRTemp m = newTemp(Ity_I64); + movemask[i] = newTemp(Ity_I64); + assign(mp, mpx); + assign(m, x); + assign(movemask[i], binop(Iop_And64, mkexpr(mp), mkexpr(m))); + if (i != 5) { + x = binop(Iop_Or64, binop(Iop_Xor64, mkexpr(m), mkexpr(movemask[i])), + binop(Iop_Shl64, mkexpr(movemask[i]), mkU8(1 << i))); + mk = binop(Iop_And64, mkexpr(mki), unop(Iop_Not64, mkexpr(mp))); + } + } + + if (do_ext) { + /* Extract */ + x = binop(Iop_And64, mkexpr(op2), mkexpr(op3)); + for (int i = 0; i < 6; i++) { + IRTemp t = newTemp(Ity_I64); + assign(t, binop(Iop_And64, x, mkexpr(movemask[i]))); + x = binop(Iop_Or64, binop(Iop_Xor64, x, mkexpr(t)), + binop(Iop_Shl64, mkexpr(t), mkU8(1 << i))); + } + } else { + /* Deposit */ + x = mkexpr(op2); + for (int i = 6; i-- > 0;) { + IRTemp xi = newTemp(Ity_I64); + assign(xi, x); + x = binop( + Iop_Or64, + binop(Iop_And64, mkexpr(xi), unop(Iop_Not64, mkexpr(movemask[i]))), + binop(Iop_And64, binop(Iop_Shr64, mkexpr(xi), mkU8(1 << i)), + mkexpr(movemask[i]))); + } + x = binop(Iop_And64, x, mkexpr(op3)); + } + put_gpr_dw0(r1, x); } -static const HChar * -s390_irgen_VCLFNH(UChar v1, UChar v2, UChar m3, UChar m4) +static void +s390_irgen_BEXTG(UChar r3, UChar r1, UChar r2) { - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCLFNH; - details.v1 = v1; - details.v2 = v2; - details.m3 = m3; - details.m4 = m4; - return s390_irgen_VCxx("vclfnh", details, 0, sizeof(V128) / 2); + s390_irgen_BExtDep(r3, r1, r2, True); } -static const HChar * -s390_irgen_VCFN(UChar v1, UChar v2, UChar m3, UChar m4) +static void +s390_irgen_BDEPG(UChar r3, UChar r1, UChar r2) { - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCFN; - details.v1 = v1; - details.v2 = v2; - details.m3 = m3; - details.m4 = m4; - return s390_irgen_VCxx("vcfn", details, 0, sizeof(V128)); + s390_irgen_BExtDep(r3, r1, r2, False); } -static const HChar * -s390_irgen_VCLFNL(UChar v1, UChar v2, UChar m3, UChar m4) +/* Implement the various "load (logical) indexed address" variants */ +static void +s390_irgen_LXAx(UChar r1, UChar x2, UChar b2, UInt dx, Bool is_signed, UChar es) { - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCLFNL; - details.v1 = v1; - details.v2 = v2; - details.m3 = m3; - details.m4 = m4; - return s390_irgen_VCxx("vclfnl", details, sizeof(V128) / 2, - sizeof(V128) / 2); + IRExpr* res; + + res = mkU32(dx); + if (x2) { + res = binop(Iop_Add32, res, get_gpr_w1(x2)); + } + res = unop(is_signed ? Iop_32Sto64 : Iop_32Uto64, res); + if (es) { + res = binop(Iop_Shl64, res, mkU8(es)); + } + if (b2) { + res = binop(Iop_Add64, res, get_gpr_dw0(b2)); + } + put_gpr_dw0(r1, res); } -static const HChar * -s390_irgen_VCRNF(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +static void +s390_irgen_LXAB(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_nnpa) { - emulation_failure(EmFail_S390X_nnpa); - return "vcrnf"; - } + s390_irgen_LXAx(r1, x2, b2, dx, True, 0); +} - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VCRNF; - details.v1 = v1; - details.v2 = v2; - details.v3 = v3; - details.m4 = m4; - details.m5 = m5; - details.m6 = 0; - IRDirty* d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - d->nFxState = 3; - vex_bzero(&d->fxState, sizeof(d->fxState)); - d->fxState[0].fx = Ifx_Read; - d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); - d->fxState[1].size = sizeof(V128); - d->fxState[2].fx = Ifx_Write; - d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); - d->fxState[2].size = sizeof(V128); +static void +s390_irgen_LXAH(UChar r1, UChar x2, UChar b2, UInt dx) +{ + s390_irgen_LXAx(r1, x2, b2, dx, True, 1); +} - stmt(IRStmt_Dirty(d)); - return "vcrnf"; +static void +s390_irgen_LXAF(UChar r1, UChar x2, UChar b2, UInt dx) +{ + s390_irgen_LXAx(r1, x2, b2, dx, True, 2); } -static const HChar * -s390_irgen_NNPA(void) +static void +s390_irgen_LXAG(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_nnpa) { - emulation_failure(EmFail_S390X_nnpa); - return "nnpa"; - } - extension(S390_EXT_NNPA, 0); - return "nnpa"; + s390_irgen_LXAx(r1, x2, b2, dx, True, 3); } -static const HChar * -s390_irgen_KM(UChar r1, UChar r2) +static void +s390_irgen_LXAQ(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa) { - emulation_failure(EmFail_S390X_msa); - return "km"; - } - s390_insn_assert("km", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KM, r1 | (r2 << 4)); - return "km"; + s390_irgen_LXAx(r1, x2, b2, dx, True, 4); } -static const HChar * -s390_irgen_KMC(UChar r1, UChar r2) +static void +s390_irgen_LLXAB(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa) { - emulation_failure(EmFail_S390X_msa); - return "kmc"; - } - s390_insn_assert("kmc", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KMC, r1 | (r2 << 4)); - return "kmc"; + s390_irgen_LXAx(r1, x2, b2, dx, False, 0); } -static const HChar * -s390_irgen_KIMD(UChar r1, UChar r2) +static void +s390_irgen_LLXAH(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa) { - emulation_failure(EmFail_S390X_msa); - return "kimd"; - } - /* r1 is reserved */ - s390_insn_assert("kimd", r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KIMD, r1 | (r2 << 4)); - return "kimd"; + s390_irgen_LXAx(r1, x2, b2, dx, False, 1); } -static const HChar * -s390_irgen_KLMD(UChar r1, UChar r2) +static void +s390_irgen_LLXAF(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa) { - emulation_failure(EmFail_S390X_msa); - return "klmd"; - } - /* r1 is only used by some functions */ - s390_insn_assert("klmd", r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KLMD, r1 | (r2 << 4)); - return "klmd"; + s390_irgen_LXAx(r1, x2, b2, dx, False, 2); } -static const HChar * -s390_irgen_KMAC(UChar r1, UChar r2) +static void +s390_irgen_LLXAG(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa) { - emulation_failure(EmFail_S390X_msa); - return "kmac"; - } - /* r1 is ignored */ - s390_insn_assert("kmac", r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KMAC, r1 | (r2 << 4)); - return "kmac"; + s390_irgen_LXAx(r1, x2, b2, dx, False, 3); } -static const HChar * -s390_irgen_PCC(void) +static void +s390_irgen_LLXAQ(UChar r1, UChar x2, UChar b2, UInt dx) { - if (! s390_host_has_msa4) { - emulation_failure(EmFail_S390X_msa4); - return "pcc"; - } - extension(S390_EXT_PCC, 0); - return "pcc"; + s390_irgen_LXAx(r1, x2, b2, dx, False, 4); } -static const HChar * -s390_irgen_KMCTR(UChar r3, UChar r1, UChar r2) +static void +s390_irgen_VBLEND(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - if (! s390_host_has_msa4) { - emulation_failure(EmFail_S390X_msa4); - return "kmctr"; - } - s390_insn_assert("kmctr", r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 && - r3 % 2 == 0 && r3 != 0); - extension(S390_EXT_KMCTR, r1 | (r2 << 4) | (r3 << 8)); - return "kmctr"; + s390_insn_assert(m5 <= 4); + IRExpr* vIfTrue = get_vr_qw(v2); + IRExpr* vIfFalse = get_vr_qw(v3); + IRExpr* vCond = s390_V128_high_set(get_vr_qw(v4), m5); + put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse)); } -static const HChar * -s390_irgen_KMO(UChar r1, UChar r2) +static void +s390_irgen_VGEM(UChar v1, UChar v2, UChar m3) { - if (! s390_host_has_msa4) { - emulation_failure(EmFail_S390X_msa4); - return "kmo"; + static const ULong pos[][2] = { + {0x0001020304050607, 0x0001020304050607}, + {0x0000000100020003, 0x0004000500060007}, + {0x0000000000000001, 0x0000000200000003}, + {0x0000000000000000, 0x0000000000000001}, + }; + static const IROp shl_op[] = {Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, + Iop_Shl64x2}; + IRTemp op2 = newTemp(Ity_V128); + IRExpr* mask; + + s390_insn_assert(m3 <= 4); + assign(op2, get_vr_qw(v2)); + if (m3 == 0) { + /* Separate into high and low half */ + mask = + binop(Iop_InterleaveHI64x2, + s390_V128_fill(binop(Iop_GetElem8x16, mkexpr(op2), mkU8(0))), + s390_V128_fill(binop(Iop_GetElem8x16, mkexpr(op2), mkU8(1)))); + } else if (m3 < 4) { + IROp getelem = S390_VEC_OP3(m3 - 1, Iop_GetElem8x16, Iop_GetElem16x8, + Iop_GetElem32x4); + mask = s390_V128_fill(binop(getelem, mkexpr(op2), mkU8(0))); + } else { + mask = mkexpr(op2); } - s390_insn_assert("kmo", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KMO, r1 | (r2 << 4)); - return "kmo"; + if (m3 < 4) { + mask = binop(shl_op[m3], mask, + binop(Iop_64HLtoV128, mkU64(pos[m3][0]), mkU64(pos[m3][1]))); + } + put_vr_qw(v1, s390_V128_high_set(mask, m3)); } -static const HChar * -s390_irgen_KMF(UChar r1, UChar r2) +static void +s390_irgen_VEVAL(UChar v1, UChar v2, UChar v3, UChar v4, UChar i5) { - if (! s390_host_has_msa4) { - emulation_failure(EmFail_S390X_msa4); - return "kmf"; + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + IRTemp c = newTemp(Ity_V128); + IRTemp not_a = newTemp(Ity_V128); + IRTemp not_b = newTemp(Ity_V128); + IRTemp not_c = newTemp(Ity_V128); + IRExpr* t = NULL; + + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + assign(c, get_vr_qw(v4)); + assign(not_a, unop(Iop_NotV128, mkexpr(a))); + assign(not_b, unop(Iop_NotV128, mkexpr(b))); + assign(not_c, unop(Iop_NotV128, mkexpr(c))); + + for (UChar i = 0; i < 8; i++) { + if ((i5 & (1 << i)) != 0) { + IRExpr* s = binop(Iop_AndV128, mkexpr(i & 4 ? not_a : a), + binop(Iop_AndV128, mkexpr(i & 2 ? not_b : b), + mkexpr(i & 1 ? not_c : c))); + if (t == NULL) { + t = s; + } else { + t = binop(Iop_OrV128, t, s); + } + } } - s390_insn_assert("kmf", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KMF, r1 | (r2 << 4)); - return "kmf"; + if (t == NULL) + t = mkV128(0); + put_vr_qw(v1, t); } -static const HChar * -s390_irgen_KMA(UChar r3, UChar r1, UChar r2) +/* Return a mask for the lanes where a/b would fail */ +static IRExpr* +s390_V128_bad_div_mask(IRTemp a, IRTemp b, UChar m4, Bool is_signed) { - if (! s390_host_has_msa8) { - emulation_failure(EmFail_S390X_msa8); - return "kma"; + IRExpr* res; + res = s390_V128_CmpEQ(mkexpr(b), mkV128(0), m4); + if (is_signed) { + IRExpr* max_neg; + switch (m4) { + case 2: + max_neg = s390_V128_fill(mkU32(0x80000000)); + break; + case 3: + max_neg = s390_V128_fill(mkU64(1ULL << 63)); + break; + case 4: + max_neg = binop(Iop_64HLtoV128, mkU64(1ULL << 63), mkU64(0)); + break; + default: + vpanic("s390_V128_bad_div_mask: bad m4"); + } + res = binop(Iop_OrV128, res, + binop(Iop_AndV128, + s390_V128_CmpEQ(mkexpr(b), mkV128(0xffff), m4), + s390_V128_CmpEQ(mkexpr(a), max_neg, m4))); } - s390_insn_assert("kma", r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 && - r3 % 2 == 0 && r3 != 0 && r3 != r1 && r3 != r2); - extension(S390_EXT_KMA, r1 | (r2 << 4) | (r3 << 8)); - return "kma"; + return res; } -static const HChar * -s390_irgen_KDSA(UChar r1, UChar r2) +static void +s390_irgen_VDx(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, + Bool is_signed, Bool do_remainder) { - if (! s390_host_has_msa9) { - emulation_failure(EmFail_S390X_msa9); - return "kdsa"; + s390_insn_assert(m4 >= 2 && m4 <= 4); + + IRTemp op1 = newTemp(Ity_V128); + IRTemp op2 = newTemp(Ity_V128); + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + Bool idc = (m5 & 8) != 0; + IRExpr* result; + + assign(op1, get_vr_qw(v2)); + assign(op2, get_vr_qw(v3)); + if (idc) { + /* Avoid bad divisions; ensure a zero result for affected lanes */ + IRTemp bad = newTemp(Ity_V128); + assign(bad, s390_V128_bad_div_mask(op1, op2, m4, is_signed)); + assign(a, + binop(Iop_AndV128, mkexpr(op1), unop(Iop_NotV128, mkexpr(bad)))); + assign(b, binop(Iop_OrV128, mkexpr(op2), mkexpr(bad))); + } else { + assign(a, mkexpr(op1)); + assign(b, mkexpr(op2)); } - /* r1 is reserved */ - s390_insn_assert("kdsa", r2 != 0 && r2 % 2 == 0); - extension(S390_EXT_KDSA, r1 | (r2 << 4)); - return "kdsa"; + + /* There are no Iops for vector divisions, so split up by lane */ + switch (m4) { + case 2: { + IRExpr* res[4]; + IROp divop = is_signed ? Iop_DivModS64to32 : Iop_DivModU64to32; + IROp widen = is_signed ? Iop_32Sto64 : Iop_32Uto64; + IROp hilo = do_remainder ? Iop_64HIto32 : Iop_64to32; + for (UChar i = 0; i < 4; i++) { + res[i] = unop( + hilo, binop(divop, + unop(widen, binop(Iop_GetElem32x4, mkexpr(a), mkU8(i))), + binop(Iop_GetElem32x4, mkexpr(b), mkU8(i)))); + } + result = binop(Iop_64HLtoV128, binop(Iop_32HLto64, res[0], res[1]), + binop(Iop_32HLto64, res[2], res[3])); + break; + } + case 3: { + IRExpr* res[2]; + IROp hilo = do_remainder ? Iop_128HIto64 : Iop_128to64; + if (is_signed) { + IROp divop = Iop_DivModS64to64; + for (UChar i = 0; i < 2; i++) { + res[i] = unop( + hilo, binop(divop, binop(Iop_GetElem64x2, mkexpr(a), mkU8(i)), + binop(Iop_GetElem64x2, mkexpr(b), mkU8(i)))); + } + } else { + IROp divop = Iop_DivModU128to64; + for (UChar i = 0; i < 2; i++) { + res[i] = unop( + hilo, binop(divop, + binop(Iop_64HLto128, mkU64(0), + binop(Iop_GetElem64x2, mkexpr(a), mkU8(i))), + binop(Iop_GetElem64x2, mkexpr(b), mkU8(i)))); + } + } + result = binop(Iop_64HLtoV128, res[0], res[1]); + break; + } + case 4: { + if (!s390_host_has_vxe3) { + emulation_failure(EmFail_S390X_vxe3); + return; + } + IROp divop = do_remainder ? (is_signed ? Iop_ModS128 : Iop_ModU128) + : (is_signed ? Iop_DivS128 : Iop_DivU128); + result = binop(divop, mkexpr(a), mkexpr(b)); + break; + } + } + put_vr_qw(v1, result); } -static const HChar * -s390_irgen_BPP(UChar m1, UShort i2, IRTemp op3addr) +static void +s390_irgen_VD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - /* Treat as a no-op */ - return "bpp"; + s390_irgen_VDx(v1, v2, v3, m4, m5, True, False); } -static const HChar * -s390_irgen_BPRP(UChar m1, UShort i2, UInt i3) +static void +s390_irgen_VDL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - /* Treat as a no-op */ - return "bprp"; + s390_irgen_VDx(v1, v2, v3, m4, m5, False, False); } -static const HChar * -s390_irgen_NIAI(UChar i1, UChar i2) +static void +s390_irgen_VR(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - /* Treat as a no-op */ - return "niai"; + s390_irgen_VDx(v1, v2, v3, m4, m5, True, True); } -static const HChar * -s390_irgen_PPA(UChar m3, UChar r1, UChar r2) +static void +s390_irgen_VRL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - /* Treat as a no-op. m3 could indicate one of the following: - 1: transaction-abort assist -- fine, we don't support transactions - 15: in-order-execution assist -- we don't claim support */ - return "ppa"; + s390_irgen_VDx(v1, v2, v3, m4, m5, False, True); } /* New insns are added here. @@ -20790,7 +18263,8 @@ s390_decode_2byte_and_irgen(const UChar *bytes) case 0x0102: /* UPT */ goto unimplemented; case 0x0104: /* PTFF */ goto unimplemented; case 0x0107: /* SCKPF */ goto unimplemented; - case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok; + case 0x010a: s390_irgen_PFPO(); + goto ok; case 0x010b: /* TAM */ goto unimplemented; case 0x010c: /* SAM24 */ goto unimplemented; case 0x010d: /* SAM31 */ goto unimplemented; @@ -20801,51 +18275,52 @@ s390_decode_2byte_and_irgen(const UChar *bytes) switch ((ovl & 0xff00) >> 8) { case 0x04: /* SPM */ goto unimplemented; case 0x05: /* BALR */ goto unimplemented; - case 0x06: s390_format_RR_RR(s390_irgen_BCTR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x07: s390_format_RR(s390_irgen_BCR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x0a: s390_format_I(s390_irgen_SVC, I_i(ovl)); goto ok; + case 0x06: s390_irgen_BCTR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x07: s390_irgen_BCR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x0a: s390_irgen_SVC(I_i(ovl)); + goto ok; case 0x0b: /* BSM */ goto unimplemented; case 0x0c: /* BASSM */ goto unimplemented; - case 0x0d: s390_format_RR_RR(s390_irgen_BASR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x0e: s390_format_RR_RR(s390_irgen_MVCL, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x0f: s390_format_RR_RR(s390_irgen_CLCL, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x10: s390_format_RR_RR(s390_irgen_LPR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x11: s390_format_RR_RR(s390_irgen_LNR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x12: s390_format_RR_RR(s390_irgen_LTR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x13: s390_format_RR_RR(s390_irgen_LCR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x14: s390_format_RR_RR(s390_irgen_NR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x15: s390_format_RR_RR(s390_irgen_CLR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x16: s390_format_RR_RR(s390_irgen_OR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x17: s390_format_RR_RR(s390_irgen_XR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x18: s390_format_RR_RR(s390_irgen_LR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x19: s390_format_RR_RR(s390_irgen_CR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1a: s390_format_RR_RR(s390_irgen_AR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1b: s390_format_RR_RR(s390_irgen_SR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1c: s390_format_RR_RR(s390_irgen_MR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1d: s390_format_RR_RR(s390_irgen_DR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1e: s390_format_RR_RR(s390_irgen_ALR, RR_r1(ovl), RR_r2(ovl)); - goto ok; - case 0x1f: s390_format_RR_RR(s390_irgen_SLR, RR_r1(ovl), RR_r2(ovl)); - goto ok; + case 0x0d: s390_irgen_BASR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x0e: s390_irgen_MVCL(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x0f: s390_irgen_CLCL(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x10: s390_irgen_LPR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x11: s390_irgen_LNR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x12: s390_irgen_LTR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x13: s390_irgen_LCR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x14: s390_irgen_NR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x15: s390_irgen_CLR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x16: s390_irgen_OR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x17: s390_irgen_XR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x18: s390_irgen_LR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x19: s390_irgen_CR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1a: s390_irgen_AR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1b: s390_irgen_SR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1c: s390_irgen_MR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1d: s390_irgen_DR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1e: s390_irgen_ALR(RR_r1(ovl), RR_r2(ovl)); + goto ok; + case 0x1f: s390_irgen_SLR(RR_r1(ovl), RR_r2(ovl)); + goto ok; case 0x20: /* LPDR */ goto unimplemented; case 0x21: /* LNDR */ goto unimplemented; case 0x22: /* LTDR */ goto unimplemented; @@ -20854,8 +18329,8 @@ s390_decode_2byte_and_irgen(const UChar *bytes) case 0x25: /* LDXR */ goto unimplemented; case 0x26: /* MXR */ goto unimplemented; case 0x27: /* MXDR */ goto unimplemented; - case 0x28: s390_format_RR_FF(s390_irgen_LDR, RR_r1(ovl), RR_r2(ovl)); - goto ok; + case 0x28: s390_irgen_LDR(RR_r1(ovl), RR_r2(ovl)); + goto ok; case 0x29: /* CDR */ goto unimplemented; case 0x2a: /* ADR */ goto unimplemented; case 0x2b: /* SDR */ goto unimplemented; @@ -20871,8 +18346,8 @@ s390_decode_2byte_and_irgen(const UChar *bytes) case 0x35: /* LEDR */ goto unimplemented; case 0x36: /* AXR */ goto unimplemented; case 0x37: /* SXR */ goto unimplemented; - case 0x38: s390_format_RR_FF(s390_irgen_LER, RR_r1(ovl), RR_r2(ovl)); - goto ok; + case 0x38: s390_irgen_LER(RR_r1(ovl), RR_r2(ovl)); + goto ok; case 0x39: /* CER */ goto unimplemented; case 0x3a: /* AER */ goto unimplemented; case 0x3b: /* SER */ goto unimplemented; @@ -20898,70 +18373,70 @@ s390_decode_4byte_and_irgen(const UChar *bytes) ((UInt)bytes[2] << 8) | (UInt)bytes[3]; switch ((ovl & 0xff0f0000) >> 16) { - case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa502: s390_format_RI_RU(s390_irgen_IILH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa503: s390_format_RI_RU(s390_irgen_IILL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa506: s390_format_RI_RU(s390_irgen_NILH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa507: s390_format_RI_RU(s390_irgen_NILL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa704: s390_format_RI(s390_irgen_BRC, RI_r1(ovl), RI_i2(ovl)); - goto ok; - case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa708: s390_format_RI_RI(s390_irgen_LHI, RI_r1(ovl), RI_i2(ovl)); - goto ok; - case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, RI_r1(ovl), RI_i2(ovl)); - goto ok; - case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, RI_r1(ovl), RI_i2(ovl)); - goto ok; - case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, RI_r1(ovl), - RI_i2(ovl)); goto ok; - case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, RI_r1(ovl), RI_i2(ovl)); - goto ok; - case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, RI_r1(ovl), - RI_i2(ovl)); goto ok; + case 0xa500: s390_irgen_IIHH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa501: s390_irgen_IIHL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa502: s390_irgen_IILH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa503: s390_irgen_IILL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa504: s390_irgen_NIHH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa505: s390_irgen_NIHL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa506: s390_irgen_NILH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa507: s390_irgen_NILL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa508: s390_irgen_OIHH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa509: s390_irgen_OIHL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50a: s390_irgen_OILH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50b: s390_irgen_OILL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50c: s390_irgen_LLIHH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50d: s390_irgen_LLIHL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50e: s390_irgen_LLILH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa50f: s390_irgen_LLILL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa700: s390_irgen_TMLH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa701: s390_irgen_TMLL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa702: s390_irgen_TMHH(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa703: s390_irgen_TMHL(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa704: s390_irgen_BRC(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa705: s390_irgen_BRAS(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa706: s390_irgen_BRCT(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa707: s390_irgen_BRCTG(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa708: s390_irgen_LHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa709: s390_irgen_LGHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70a: s390_irgen_AHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70b: s390_irgen_AGHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70c: s390_irgen_MHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70d: s390_irgen_MGHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70e: s390_irgen_CHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; + case 0xa70f: s390_irgen_CGHI(RI_r1(ovl), RI_i2(ovl)); + goto ok; } switch ((ovl & 0xffff0000) >> 16) { @@ -20972,7 +18447,7 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb201: /* STBEAR */ goto unimplemented; case 0xb202: /* STIDP */ goto unimplemented; case 0xb204: /* SCK */ goto unimplemented; - case 0xb205: s390_format_S_RD(s390_irgen_STCK, S_b2(ovl), S_d2(ovl)); + case 0xb205: s390_format_S(s390_irgen_STCK, ovl); goto ok; case 0xb206: /* SCKC */ goto unimplemented; case 0xb207: /* STCKC */ goto unimplemented; @@ -20989,7 +18464,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb219: /* SAC */ goto unimplemented; case 0xb21a: /* CFC */ goto unimplemented; case 0xb221: /* IPTE */ goto unimplemented; - case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, RRE_r1(ovl)); goto ok; + case 0xb222: s390_irgen_IPM(RRE_r1(ovl)); + goto ok; case 0xb223: /* IVSK */ goto unimplemented; case 0xb224: /* IAC */ goto unimplemented; case 0xb225: /* SSAR */ goto unimplemented; @@ -21017,8 +18493,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb23b: /* RCHP */ goto unimplemented; case 0xb23c: /* SCHM */ goto unimplemented; case 0xb240: /* BAKR */ goto unimplemented; - case 0xb241: s390_format_RRE_RR(s390_irgen_CKSM, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb241: s390_irgen_CKSM(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb244: /* SQDR */ goto unimplemented; case 0xb245: /* SQER */ goto unimplemented; case 0xb246: /* STURA */ goto unimplemented; @@ -21028,32 +18504,34 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb24a: /* ESTA */ goto unimplemented; case 0xb24b: /* LURA */ goto unimplemented; case 0xb24c: /* TAR */ goto unimplemented; - case 0xb24d: s390_format_RRE(s390_irgen_CPYA, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb24e: s390_format_RRE(s390_irgen_SAR, RRE_r1(ovl), RRE_r2(ovl)); - goto ok; - case 0xb24f: s390_format_RRE(s390_irgen_EAR, RRE_r1(ovl), RRE_r2(ovl)); - goto ok; + case 0xb24d: s390_irgen_CPYA(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb24e: s390_irgen_SAR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb24f: s390_irgen_EAR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb250: /* CSP */ goto unimplemented; - case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb252: s390_irgen_MSR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb254: /* MVPG */ goto unimplemented; - case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb255: s390_irgen_MVST(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb257: /* CUSE */ goto unimplemented; case 0xb258: /* BSG */ goto unimplemented; case 0xb25a: /* BSA */ goto unimplemented; - case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb25d: s390_irgen_CLST(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb25e: s390_irgen_SRST(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb263: /* CMPSC */ goto unimplemented; case 0xb274: /* SIGA */ goto unimplemented; case 0xb276: /* XSCH */ goto unimplemented; case 0xb277: /* RP */ goto unimplemented; - case 0xb278: s390_format_S_RD(s390_irgen_STCKE, S_b2(ovl), S_d2(ovl));goto ok; + case 0xb278: s390_format_S(s390_irgen_STCKE, ovl); + goto ok; case 0xb279: /* SACF */ goto unimplemented; - case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, S_b2(ovl), S_d2(ovl));goto ok; + case 0xb27c: s390_format_S(s390_irgen_STCKF, ovl); + goto ok; case 0xb27d: /* STSI */ goto unimplemented; case 0xb280: /* LPP */ goto unimplemented; case 0xb284: /* LCCTL */ goto unimplemented; @@ -21062,105 +18540,104 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb287: /* LSCTL */ goto unimplemented; case 0xb28e: /* QCTRI */ goto unimplemented; case 0xb28f: /* QPACI */ goto unimplemented; - case 0xb299: s390_format_S_RD(s390_irgen_SRNM, S_b2(ovl), S_d2(ovl)); - goto ok; - case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, S_b2(ovl), S_d2(ovl)); - goto ok; - case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, S_b2(ovl), S_d2(ovl)); - goto ok; - case 0xb2a5: s390_format_RRE_RR(s390_irgen_TRE, RRE_r1(ovl), RRE_r2(ovl)); goto ok; - case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); - goto ok; - case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); - goto ok; - case 0xb2b0: s390_format_S_RD_raw(s390_irgen_STFLE, S_b2(ovl), S_d2(ovl)); - goto ok; + case 0xb299: s390_format_S(s390_irgen_SRNM, ovl); + goto ok; + case 0xb29c: s390_format_S(s390_irgen_STFPC, ovl); + goto ok; + case 0xb29d: s390_format_S(s390_irgen_LFPC, ovl); + goto ok; + case 0xb2a5: s390_irgen_TRE(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb2a6: s390_irgen_CU21(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb2a7: s390_irgen_CU12(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb2b0: s390_irgen_STFLE(S_b2(ovl), S_d2(ovl)); + goto ok; case 0xb2b1: /* STFL */ goto unimplemented; case 0xb2b2: /* LPSWE */ goto unimplemented; - case 0xb2b8: s390_format_S_RD_raw(s390_irgen_SRNMB, S_b2(ovl), S_d2(ovl)); - goto ok; - case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, S_b2(ovl), S_d2(ovl)); - goto ok; + case 0xb2b8: s390_irgen_SRNMB(S_b2(ovl), S_d2(ovl)); + goto ok; + case 0xb2b9: s390_format_S(s390_irgen_SRNMT, ovl); + goto ok; case 0xb2bd: /* LFAS */ goto unimplemented; case 0xb2e0: /* SCCTR */ goto unimplemented; case 0xb2e1: /* SPCTR */ goto unimplemented; case 0xb2e4: /* ECCTR */ goto unimplemented; case 0xb2e5: /* EPCTR */ goto unimplemented; - case 0xb2e8: s390_format_RRFa_U0RR(s390_irgen_PPA, RRF2_m3(ovl), - RRF2_r1(ovl), RRF2_r2(ovl)); goto ok; + case 0xb2e8: s390_irgen_PPA(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; case 0xb2ec: /* ETND */ goto unimplemented; case 0xb2ed: /* ECPGA */ goto unimplemented; case 0xb2f8: /* TEND */ goto unimplemented; - case 0xb2fa: s390_format_IE(s390_irgen_NIAI, IE_i1(ovl), - IE_i2(ovl)); goto ok; + case 0xb2fa: s390_irgen_NIAI(IE_i1(ovl), IE_i2(ovl)); + goto ok; case 0xb2fc: /* TABORT */ goto unimplemented; case 0xb2ff: /* TRAP4 */ goto unimplemented; - case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb300: s390_irgen_LPEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb301: s390_irgen_LNEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb302: s390_irgen_LTEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb303: s390_irgen_LCEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb304: s390_irgen_LDEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb305: s390_irgen_LXDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb306: s390_irgen_LXEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb307: /* MXDBR */ goto unimplemented; - case 0xb308: s390_format_RRE_FF(s390_irgen_KEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb308: s390_irgen_KEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb309: s390_irgen_CEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb30a: s390_irgen_AEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb30b: s390_irgen_SEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb30c: /* MDEBR */ goto unimplemented; - case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, RRF_r1(ovl), - RRF_r3(ovl), RRF_r2(ovl)); goto ok; - case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, RRF_r1(ovl), - RRF_r3(ovl), RRF_r2(ovl)); goto ok; - case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb318: s390_format_RRE_FF(s390_irgen_KDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, RRF_r1(ovl), - RRF_r3(ovl), RRF_r2(ovl)); goto ok; - case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, RRF_r1(ovl), - RRF_r3(ovl), RRF_r2(ovl)); goto ok; - case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb30d: s390_irgen_DEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb30e: s390_irgen_MAEBR(RRD_r1(ovl), RRD_r3(ovl), RRD_r2(ovl)); + goto ok; + case 0xb30f: s390_irgen_MSEBR(RRD_r1(ovl), RRD_r3(ovl), RRD_r2(ovl)); + goto ok; + case 0xb310: s390_irgen_LPDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb311: s390_irgen_LNDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb312: s390_irgen_LTDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb313: s390_irgen_LCDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb314: s390_irgen_SQEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb315: s390_irgen_SQDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb316: s390_irgen_SQXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb317: s390_irgen_MEEBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb318: s390_irgen_KDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb319: s390_irgen_CDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb31a: s390_irgen_ADBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb31b: s390_irgen_SDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb31c: s390_irgen_MDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb31d: s390_irgen_DDBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb31e: s390_irgen_MADBR(RRD_r1(ovl), RRD_r3(ovl), RRD_r2(ovl)); + goto ok; + case 0xb31f: s390_irgen_MSDBR(RRD_r1(ovl), RRD_r3(ovl), RRD_r2(ovl)); + goto ok; + case 0xb324: s390_irgen_LDER(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb325: /* LXDR */ goto unimplemented; case 0xb326: /* LXER */ goto unimplemented; case 0xb32e: /* MAER */ goto unimplemented; @@ -21175,472 +18652,478 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb33d: /* MYHR */ goto unimplemented; case 0xb33e: /* MADR */ goto unimplemented; case 0xb33f: /* MSDR */ goto unimplemented; - case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb347: s390_format_RRF_UUFF2(s390_irgen_FIXBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb348: s390_format_RRE_FF(s390_irgen_KXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb340: s390_irgen_LPXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb341: s390_irgen_LNXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb342: s390_irgen_LTXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb343: s390_irgen_LCXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb344: s390_irgen_LEDBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb345: s390_irgen_LDXBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb346: s390_irgen_LEXBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb347: s390_irgen_FIXBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb348: s390_irgen_KXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb349: s390_irgen_CXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb34a: s390_irgen_AXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb34b: s390_irgen_SXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb34c: s390_irgen_MXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb34d: s390_irgen_DXBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb350: /* TBEDR */ goto unimplemented; case 0xb351: /* TBDR */ goto unimplemented; case 0xb353: /* DIEBR */ goto unimplemented; - case 0xb357: s390_format_RRF_UUFF2(s390_irgen_FIEBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb357: s390_irgen_FIEBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb358: /* THDER */ goto unimplemented; case 0xb359: /* THDR */ goto unimplemented; case 0xb35b: /* DIDBR */ goto unimplemented; - case 0xb35f: s390_format_RRF_UUFF2(s390_irgen_FIDBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb35f: s390_irgen_FIDBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb360: /* LPXR */ goto unimplemented; case 0xb361: /* LNXR */ goto unimplemented; case 0xb362: /* LTXR */ goto unimplemented; case 0xb363: /* LCXR */ goto unimplemented; - case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb365: s390_irgen_LXR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb366: /* LEXR */ goto unimplemented; case 0xb367: /* FIXR */ goto unimplemented; case 0xb369: /* CXR */ goto unimplemented; - case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); - goto ok; - case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, RRE_r1(ovl)); goto ok; - case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, RRE_r1(ovl)); goto ok; - case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, RRE_r1(ovl)); goto ok; + case 0xb370: s390_irgen_LPDFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb371: s390_irgen_LNDFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb372: s390_irgen_CPSDR(RRFb_r3(ovl), RRFb_r1(ovl), RRFb_r2(ovl)); + goto ok; + case 0xb373: s390_irgen_LCDFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb374: s390_irgen_LZER(RRE_r1(ovl)); + goto ok; + case 0xb375: s390_irgen_LZDR(RRE_r1(ovl)); + goto ok; + case 0xb376: s390_irgen_LZXR(RRE_r1(ovl)); + goto ok; case 0xb377: /* FIER */ goto unimplemented; case 0xb37f: /* FIDR */ goto unimplemented; - case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, RRE_r1(ovl)); goto ok; + case 0xb384: s390_irgen_SFPC(RRE_r1(ovl)); + goto ok; case 0xb385: /* SFASR */ goto unimplemented; - case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, RRE_r1(ovl)); goto ok; - case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb38c: s390_irgen_EFPC(RRE_r1(ovl)); + goto ok; + case 0xb390: s390_irgen_CELFBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb391: s390_irgen_CDLFBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb392: s390_irgen_CXLFBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb394: s390_irgen_CEFBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb395: s390_irgen_CDFBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb396: s390_irgen_CXFBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb398: s390_irgen_CFEBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb399: s390_irgen_CFDBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb39a: s390_irgen_CFXBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb39c: s390_irgen_CLFEBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb39d: s390_irgen_CLFDBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb39e: s390_irgen_CLFXBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a0: s390_irgen_CELGBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a1: s390_irgen_CDLGBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a2: s390_irgen_CXLGBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a4: s390_irgen_CEGBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a5: s390_irgen_CDGBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a6: s390_irgen_CXGBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a8: s390_irgen_CGEBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3a9: s390_irgen_CGDBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3aa: s390_irgen_CGXBRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3ac: s390_irgen_CLGEBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3ad: s390_irgen_CLGDBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3ae: s390_irgen_CLGXBR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb3b4: /* CEFR */ goto unimplemented; case 0xb3b5: /* CDFR */ goto unimplemented; case 0xb3b6: /* CXFR */ goto unimplemented; case 0xb3b8: /* CFER */ goto unimplemented; case 0xb3b9: /* CFDR */ goto unimplemented; case 0xb3ba: /* CFXR */ goto unimplemented; - case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb3c1: s390_irgen_LDGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb3c4: /* CEGR */ goto unimplemented; case 0xb3c5: /* CDGR */ goto unimplemented; case 0xb3c6: /* CXGR */ goto unimplemented; case 0xb3c8: /* CGER */ goto unimplemented; case 0xb3c9: /* CGDR */ goto unimplemented; case 0xb3ca: /* CGXR */ goto unimplemented; - case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, RRF5_m4(ovl), - RRF5_r1(ovl), RRF5_r2(ovl)); goto ok; - case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb3cd: s390_irgen_LGDR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3d0: s390_irgen_MDTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3d1: s390_irgen_DDTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3d2: s390_irgen_ADTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3d3: s390_irgen_SDTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3d4: s390_irgen_LDETR(RRFd_m4(ovl), RRFd_r1(ovl), RRFd_r2(ovl)); + goto ok; + case 0xb3d5: s390_irgen_LEDTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3d6: s390_irgen_LTDTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb3d7: /* FIDTR */ goto unimplemented; - case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, RRF5_m4(ovl), - RRF5_r1(ovl), RRF5_r2(ovl)); goto ok; - case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb3d8: s390_irgen_MXTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3d9: s390_irgen_DXTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3da: s390_irgen_AXTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3db: s390_irgen_SXTRA(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb3dc: s390_irgen_LXDTR(RRFd_m4(ovl), RRFd_r1(ovl), RRFd_r2(ovl)); + goto ok; + case 0xb3dd: s390_irgen_LDXTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb3de: s390_irgen_LTXTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb3df: /* FIXTR */ goto unimplemented; case 0xb3e0: /* KDTR */ goto unimplemented; - case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb3e1: s390_irgen_CGDTRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb3e2: /* CUDTR */ goto unimplemented; case 0xb3e3: /* CSDTR */ goto unimplemented; - case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb3e4: s390_irgen_CDTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3e5: s390_irgen_EEDTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3e7: s390_irgen_ESDTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb3e8: /* KXTR */ goto unimplemented; - case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb3e9: s390_irgen_CGXTRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb3ea: /* CUXTR */ goto unimplemented; case 0xb3eb: /* CSXTR */ goto unimplemented; - case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb3ec: s390_irgen_CXTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3ed: s390_irgen_EEXTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3ef: s390_irgen_ESXTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3f1: s390_irgen_CDGTRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb3f2: /* CDUTR */ goto unimplemented; case 0xb3f3: /* CDSTR */ goto unimplemented; - case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTRA, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; + case 0xb3f4: s390_irgen_CEDTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3f5: s390_irgen_QADTR(RRFb_r3(ovl), RRFb_m4(ovl), RRFb_r1(ovl), + RRFb_r2(ovl)); + goto ok; + case 0xb3f6: s390_irgen_IEDTR(RRFb_r3(ovl), RRFb_r1(ovl), RRFb_r2(ovl)); + goto ok; + case 0xb3f7: s390_irgen_RRDTR(RRFb_r3(ovl), RRFb_m4(ovl), RRFb_r1(ovl), + RRFb_r2(ovl)); + goto ok; + case 0xb3f9: s390_irgen_CXGTRA(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; case 0xb3fa: /* CXUTR */ goto unimplemented; case 0xb3fb: /* CXSTR */ goto unimplemented; - case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb3fc: s390_irgen_CEXTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb3fd: s390_irgen_QAXTR(RRFb_r3(ovl), RRFb_m4(ovl), RRFb_r1(ovl), + RRFb_r2(ovl)); + goto ok; + case 0xb3fe: s390_irgen_IEXTR(RRFb_r3(ovl), RRFb_r1(ovl), RRFb_r2(ovl)); + goto ok; + case 0xb3ff: s390_irgen_RRXTR(RRFb_r3(ovl), RRFb_m4(ovl), RRFb_r1(ovl), + RRFb_r2(ovl)); + goto ok; + case 0xb900: s390_irgen_LPGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb901: s390_irgen_LNGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb902: s390_irgen_LTGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb903: s390_irgen_LCGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb904: s390_irgen_LGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb905: /* LURAG */ goto unimplemented; - case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb906: s390_irgen_LGBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb907: s390_irgen_LGHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb908: s390_irgen_AGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb909: s390_irgen_SGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb90a: s390_irgen_ALGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb90b: s390_irgen_SLGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb90c: s390_irgen_MSGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb90d: s390_irgen_DSGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb90e: /* EREGG */ goto unimplemented; - case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91e: s390_format_RRE_RR(s390_irgen_KMAC, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb90f: s390_irgen_LRVGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb910: s390_irgen_LPGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb911: s390_irgen_LNGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb912: s390_irgen_LTGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb913: s390_irgen_LCGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb914: s390_irgen_LGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb916: s390_irgen_LLGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb917: s390_irgen_LLGTR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb918: s390_irgen_AGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb919: s390_irgen_SGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91a: s390_irgen_ALGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91b: s390_irgen_SLGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91c: s390_irgen_MSGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91d: s390_irgen_DSGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91e: s390_irgen_KMAC(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb91f: s390_irgen_LRVR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb920: s390_irgen_CGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb921: s390_irgen_CLGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb925: /* STURG */ goto unimplemented; - case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb926: s390_irgen_LBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb927: s390_irgen_LHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb928: /* PCKMO */ goto unimplemented; - case 0xb929: s390_format_RRF_R0RR2(s390_irgen_KMA, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb92a: s390_format_RRE_RR(s390_irgen_KMF, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb92b: s390_format_RRE_RR(s390_irgen_KMO, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb92c: s390_format_E(s390_irgen_PCC); goto ok; - case 0xb92d: s390_format_RRF_R0RR2(s390_irgen_KMCTR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb92e: s390_format_RRE_RR(s390_irgen_KM, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb92f: s390_format_RRE_RR(s390_irgen_KMC, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb929: s390_irgen_KMA(RRFb_r3(ovl), RRFb_r1(ovl), RRFb_r2(ovl)); + goto ok; + case 0xb92a: s390_irgen_KMF(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb92b: s390_irgen_KMO(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb92c: s390_irgen_PCC(); + goto ok; + case 0xb92d: s390_irgen_KMCTR(RRFb_r3(ovl), RRFb_r1(ovl), RRFb_r2(ovl)); + goto ok; + case 0xb92e: s390_irgen_KM(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb92f: s390_irgen_KMC(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb930: s390_irgen_CGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb931: s390_irgen_CLGFR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb938: /* SORTL */ goto unimplemented; - case 0xb939: s390_format_RRF_R0RR2(s390_irgen_DFLTCC, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb93a: s390_format_RRE_RR(s390_irgen_KDSA, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb93b: s390_format_E(s390_irgen_NNPA); goto ok; - case 0xb93c: s390_format_RRE_RR(s390_irgen_PRNO, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb93e: s390_format_RRE_RR(s390_irgen_KIMD, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb93f: s390_format_RRE_RR(s390_irgen_KLMD, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, RRF2_m3(ovl), - RRF2_m4(ovl), RRF2_r1(ovl), - RRF2_r2(ovl)); goto ok; - case 0xb960: s390_format_RRF_U0RR(s390_irgen_CGRT, RRF2_m3(ovl), - RRF2_r1(ovl), RRF2_r2(ovl), - cabt_disasm); goto ok; - case 0xb961: s390_format_RRF_U0RR(s390_irgen_CLGRT, RRF2_m3(ovl), - RRF2_r1(ovl), RRF2_r2(ovl), - cabt_disasm); goto ok; - case 0xb964: s390_format_RRF_R0RR2(s390_irgen_NNGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb965: s390_format_RRF_R0RR2(s390_irgen_OCGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb966: s390_format_RRF_R0RR2(s390_irgen_NOGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb967: s390_format_RRF_R0RR2(s390_irgen_NXGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb968: /* CLZG */ goto unimplemented; - case 0xb969: /* CTZG */ goto unimplemented; - case 0xb96c: /* BEXTG */ goto unimplemented; - case 0xb96d: /* BDEPG */ goto unimplemented; - case 0xb972: s390_format_RRF_U0RR(s390_irgen_CRT, RRF2_m3(ovl), - RRF2_r1(ovl), RRF2_r2(ovl), - cabt_disasm); goto ok; - case 0xb973: s390_format_RRF_U0RR(s390_irgen_CLRT, RRF2_m3(ovl), - RRF2_r1(ovl), RRF2_r2(ovl), - cabt_disasm); goto ok; - case 0xb974: s390_format_RRF_R0RR2(s390_irgen_NNRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb975: s390_format_RRF_R0RR2(s390_irgen_OCRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb976: s390_format_RRF_R0RR2(s390_irgen_NORK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb977: s390_format_RRF_R0RR2(s390_irgen_NXRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb939: s390_irgen_DFLTCC(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb93a: s390_irgen_KDSA(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb93b: s390_irgen_NNPA(); + goto ok; + case 0xb93c: s390_irgen_PRNO(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb93e: s390_irgen_KIMD(RRFc_r1(ovl), RRFc_r2(ovl), RRFc_m3(ovl)); + goto ok; + case 0xb93f: s390_irgen_KLMD(RRFc_r1(ovl), RRFc_r2(ovl), RRFc_m3(ovl)); + goto ok; + case 0xb941: s390_irgen_CFDTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb942: s390_irgen_CLGDTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb943: s390_irgen_CLFDTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb946: s390_irgen_BCTGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb949: s390_irgen_CFXTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb94a: s390_irgen_CLGXTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb94b: s390_irgen_CLFXTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb951: s390_irgen_CDFTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb952: s390_irgen_CDLGTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb953: s390_irgen_CDLFTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb959: s390_irgen_CXFTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb95a: s390_irgen_CXLGTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb95b: s390_irgen_CXLFTR(RRFe_m3(ovl), RRFe_m4(ovl), RRFe_r1(ovl), + RRFe_r2(ovl)); + goto ok; + case 0xb960: s390_irgen_CGRT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb961: s390_irgen_CLGRT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb964: s390_irgen_NNGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb965: s390_irgen_OCGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb966: s390_irgen_NOGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb967: s390_irgen_NXGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb968: s390_irgen_CLZG(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb969: s390_irgen_CTZG(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb96c: s390_irgen_BEXTG(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb96d: s390_irgen_BDEPG(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb972: s390_irgen_CRT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb973: s390_irgen_CLRT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb974: s390_irgen_NNRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb975: s390_irgen_OCRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb976: s390_irgen_NORK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb977: s390_irgen_NXRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb980: s390_irgen_NGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb981: s390_irgen_OGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb982: s390_irgen_XGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb983: s390_irgen_FLOGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb984: s390_irgen_LLGCR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb985: s390_irgen_LLGHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb986: s390_irgen_MLGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb987: s390_irgen_DLGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb988: s390_irgen_ALCGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb989: s390_irgen_SLBGR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb98a: /* CSPG */ goto unimplemented; case 0xb98b: /* RDP */ goto unimplemented; case 0xb98d: /* EPSW */ goto unimplemented; case 0xb98e: /* IDTE */ goto unimplemented; case 0xb98f: /* CRDTE */ goto unimplemented; - case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb990: s390_irgen_TRTT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb991: s390_irgen_TRTO(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb992: s390_irgen_TROT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb993: s390_irgen_TROO(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb994: s390_irgen_LLCR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb995: s390_irgen_LLHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb996: s390_irgen_MLR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb997: s390_irgen_DLR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb998: s390_irgen_ALCR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb999: s390_irgen_SLBR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb99a: /* EPAIR */ goto unimplemented; case 0xb99b: /* ESAIR */ goto unimplemented; case 0xb99d: /* ESEA */ goto unimplemented; @@ -21652,195 +19135,163 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb9ac: /* IRBM */ goto unimplemented; case 0xb9ae: /* RRBM */ goto unimplemented; case 0xb9af: /* PFMF */ goto unimplemented; - case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); - goto ok; - case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); - goto ok; - case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; + case 0xb9b0: s390_irgen_CU14(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9b1: s390_irgen_CU24(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9b2: s390_irgen_CU41(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb9b3: s390_irgen_CU42(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; case 0xb9bd: /* TRTRE */ goto unimplemented; case 0xb9be: /* SRSTU */ goto unimplemented; case 0xb9bf: /* TRTE */ goto unimplemented; - case 0xb9c0: s390_format_RRF_RURR(s390_irgen_SELFHR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, RRE_r1(ovl), - RRE_r2(ovl)); goto ok; - case 0xb9e0: s390_format_RRF_U0RR(s390_irgen_LOCFHR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl), - cls_disasm); goto ok; - case 0xb9e1: s390_format_RRFa_U0RR(s390_irgen_POPCNT, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl)); goto ok; - case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl), - cls_disasm); goto ok; - case 0xb9e3: s390_format_RRF_RURR(s390_irgen_SELGR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9e5: s390_format_RRF_R0RR2(s390_irgen_NCGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9ec: s390_format_RRF_R0RR2(s390_irgen_MGRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9ed: s390_format_RRF_R0RR2(s390_irgen_MSGRKC, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f0: s390_format_RRF_RURR(s390_irgen_SELR, RRF4_r3(ovl), - RRF4_m4(ovl), RRF4_r1(ovl), - RRF4_r2(ovl)); goto ok; - case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, RRF3_r3(ovl), - RRF3_r1(ovl), RRF3_r2(ovl), - cls_disasm); goto ok; - case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f5: s390_format_RRF_R0RR2(s390_irgen_NCRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; - case 0xb9fd: s390_format_RRF_R0RR2(s390_irgen_MSRKC, RRF4_r3(ovl), - RRF4_r1(ovl), RRF4_r2(ovl)); - goto ok; + case 0xb9c0: s390_irgen_SELFHR(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb9c8: s390_irgen_AHHHR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9c9: s390_irgen_SHHHR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9ca: s390_irgen_ALHHHR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9cb: s390_irgen_SLHHHR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9cd: s390_irgen_CHHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb9cf: s390_irgen_CLHHR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb9d8: s390_irgen_AHHLR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9d9: s390_irgen_SHHLR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9da: s390_irgen_ALHHLR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9db: s390_irgen_SLHHLR(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9dd: s390_irgen_CHLR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb9df: s390_irgen_CLHLR(RRE_r1(ovl), RRE_r2(ovl)); + goto ok; + case 0xb9e0: s390_irgen_LOCFHR(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9e1: s390_irgen_POPCNT(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9e2: s390_irgen_LOCGR(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9e3: s390_irgen_SELGR(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb9e4: s390_irgen_NGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9e5: s390_irgen_NCGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9e6: s390_irgen_OGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9e7: s390_irgen_XGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9e8: s390_irgen_AGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9e9: s390_irgen_SGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9ea: s390_irgen_ALGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9eb: s390_irgen_SLGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9ec: s390_irgen_MGRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9ed: s390_irgen_MSGRKC(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f0: s390_irgen_SELR(RRFa_r3(ovl), RRFa_m4(ovl), RRFa_r1(ovl), + RRFa_r2(ovl)); + goto ok; + case 0xb9f2: s390_irgen_LOCR(RRFc_m3(ovl), RRFc_r1(ovl), RRFc_r2(ovl)); + goto ok; + case 0xb9f4: s390_irgen_NRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f5: s390_irgen_NCRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f6: s390_irgen_ORK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f7: s390_irgen_XRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f8: s390_irgen_ARK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9f9: s390_irgen_SRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9fa: s390_irgen_ALRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9fb: s390_irgen_SLRK(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; + case 0xb9fd: s390_irgen_MSRKC(RRFa_r3(ovl), RRFa_r1(ovl), RRFa_r2(ovl)); + goto ok; } switch ((ovl & 0xff000000) >> 24) { - case 0x40: s390_format_RX_RRRD(s390_irgen_STH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x41: s390_format_RX_RRRD(s390_irgen_LA, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x42: s390_format_RX_RRRD(s390_irgen_STC, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x43: s390_format_RX_RRRD(s390_irgen_IC, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x44: s390_format_RX_RRRD(s390_irgen_EX, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; + case 0x40: s390_format_RX(s390_irgen_STH, ovl); + goto ok; + case 0x41: s390_format_RX(s390_irgen_LA, ovl); + goto ok; + case 0x42: s390_format_RX(s390_irgen_STC, ovl); + goto ok; + case 0x43: s390_format_RX(s390_irgen_IC, ovl); + goto ok; + case 0x44: s390_format_RX(s390_irgen_EX, ovl); + goto ok; case 0x45: /* BAL */ goto unimplemented; - case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x47: s390_format_RX(s390_irgen_BC, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x48: s390_format_RX_RRRD(s390_irgen_LH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x49: s390_format_RX_RRRD(s390_irgen_CH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x50: s390_format_RX_RRRD(s390_irgen_ST, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x54: s390_format_RX_RRRD(s390_irgen_N, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x55: s390_format_RX_RRRD(s390_irgen_CL, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x56: s390_format_RX_RRRD(s390_irgen_O, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x57: s390_format_RX_RRRD(s390_irgen_X, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x58: s390_format_RX_RRRD(s390_irgen_L, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x59: s390_format_RX_RRRD(s390_irgen_C, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5a: s390_format_RX_RRRD(s390_irgen_A, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5b: s390_format_RX_RRRD(s390_irgen_S, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5c: s390_format_RX_RRRD(s390_irgen_M, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5d: s390_format_RX_RRRD(s390_irgen_D, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x60: s390_format_RX_FRRD(s390_irgen_STD, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; + case 0x46: s390_format_RX(s390_irgen_BCT, ovl); + goto ok; + case 0x47: s390_format_RX(s390_irgen_BC, ovl); + goto ok; + case 0x48: s390_format_RX(s390_irgen_LH, ovl); + goto ok; + case 0x49: s390_format_RX(s390_irgen_CH, ovl); + goto ok; + case 0x4a: s390_format_RX(s390_irgen_AH, ovl); + goto ok; + case 0x4b: s390_format_RX(s390_irgen_SH, ovl); + goto ok; + case 0x4c: s390_format_RX(s390_irgen_MH, ovl); + goto ok; + case 0x4d: s390_format_RX(s390_irgen_BAS, ovl); + goto ok; + case 0x4e: s390_format_RX(s390_irgen_CVD, ovl); + goto ok; + case 0x4f: s390_format_RX(s390_irgen_CVB, ovl); + goto ok; + case 0x50: s390_format_RX(s390_irgen_ST, ovl); + goto ok; + case 0x51: s390_format_RX(s390_irgen_LAE, ovl); + goto ok; + case 0x54: s390_format_RX(s390_irgen_N, ovl); + goto ok; + case 0x55: s390_format_RX(s390_irgen_CL, ovl); + goto ok; + case 0x56: s390_format_RX(s390_irgen_O, ovl); + goto ok; + case 0x57: s390_format_RX(s390_irgen_X, ovl); + goto ok; + case 0x58: s390_format_RX(s390_irgen_L, ovl); + goto ok; + case 0x59: s390_format_RX(s390_irgen_C, ovl); + goto ok; + case 0x5a: s390_format_RX(s390_irgen_A, ovl); + goto ok; + case 0x5b: s390_format_RX(s390_irgen_S, ovl); + goto ok; + case 0x5c: s390_format_RX(s390_irgen_M, ovl); + goto ok; + case 0x5d: s390_format_RX(s390_irgen_D, ovl); + goto ok; + case 0x5e: s390_format_RX(s390_irgen_AL, ovl); + goto ok; + case 0x5f: s390_format_RX(s390_irgen_SL, ovl); + goto ok; + case 0x60: s390_format_RX(s390_irgen_STD, ovl); + goto ok; case 0x67: /* MXD */ goto unimplemented; - case 0x68: s390_format_RX_FRRD(s390_irgen_LD, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; + case 0x68: s390_format_RX(s390_irgen_LD, ovl); + goto ok; case 0x69: /* CD */ goto unimplemented; case 0x6a: /* AD */ goto unimplemented; case 0x6b: /* SD */ goto unimplemented; @@ -21848,12 +19299,12 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0x6d: /* DD */ goto unimplemented; case 0x6e: /* AW */ goto unimplemented; case 0x6f: /* SW */ goto unimplemented; - case 0x70: s390_format_RX_FRRD(s390_irgen_STE, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x71: s390_format_RX_RRRD(s390_irgen_MS, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; - case 0x78: s390_format_RX_FRRD(s390_irgen_LE, RX_r1(ovl), RX_x2(ovl), - RX_b2(ovl), RX_d2(ovl)); goto ok; + case 0x70: s390_format_RX(s390_irgen_STE, ovl); + goto ok; + case 0x71: s390_format_RX(s390_irgen_MS, ovl); + goto ok; + case 0x78: s390_format_RX(s390_irgen_LE, ovl); + goto ok; case 0x79: /* CE */ goto unimplemented; case 0x7a: /* AE */ goto unimplemented; case 0x7b: /* SE */ goto unimplemented; @@ -21862,57 +19313,55 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0x7e: /* AU */ goto unimplemented; case 0x7f: /* SU */ goto unimplemented; case 0x83: /* DIAG */ goto unimplemented; - case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, RSI_r1(ovl), - RSI_r3(ovl), RSI_i2(ovl)); goto ok; - case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, RSI_r1(ovl), - RSI_r3(ovl), RSI_i2(ovl)); goto ok; - case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, RS_r1(ovl), RS_b2(ovl), - RS_d2(ovl)); goto ok; - case 0x90: s390_format_RS_RRRD(s390_irgen_STM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0x91: s390_format_SI_URD(s390_irgen_TM, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x92: s390_format_SI_URD(s390_irgen_MVI, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x94: s390_format_SI_URD(s390_irgen_NI, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x95: s390_format_SI_URD(s390_irgen_CLI, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x96: s390_format_SI_URD(s390_irgen_OI, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x97: s390_format_SI_URD(s390_irgen_XI, SI_i2(ovl), SI_b1(ovl), - SI_d1(ovl)); goto ok; - case 0x98: s390_format_RS_RRRD(s390_irgen_LM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; + case 0x84: s390_irgen_BRXH(RSI_r1(ovl), RSI_r3(ovl), RSI_i2(ovl)); + goto ok; + case 0x85: s390_irgen_BRXLE(RSI_r1(ovl), RSI_r3(ovl), RSI_i2(ovl)); + goto ok; + case 0x86: s390_format_RS(s390_irgen_BXH, ovl); + goto ok; + case 0x87: s390_format_RS(s390_irgen_BXLE, ovl); + goto ok; + case 0x88: s390_format_RS0(s390_irgen_SRL, ovl); + goto ok; + case 0x89: s390_format_RS0(s390_irgen_SLL, ovl); + goto ok; + case 0x8a: s390_format_RS0(s390_irgen_SRA, ovl); + goto ok; + case 0x8b: s390_format_RS0(s390_irgen_SLA, ovl); + goto ok; + case 0x8c: s390_format_RS0(s390_irgen_SRDL, ovl); + goto ok; + case 0x8d: s390_format_RS0(s390_irgen_SLDL, ovl); + goto ok; + case 0x8e: s390_format_RS0(s390_irgen_SRDA, ovl); + goto ok; + case 0x8f: s390_format_RS0(s390_irgen_SLDA, ovl); + goto ok; + case 0x90: s390_format_RS(s390_irgen_STM, ovl); + goto ok; + case 0x91: s390_format_SI(s390_irgen_TM, ovl); + goto ok; + case 0x92: s390_format_SI(s390_irgen_MVI, ovl); + goto ok; + case 0x94: s390_format_SI(s390_irgen_NI, ovl); + goto ok; + case 0x95: s390_format_SI(s390_irgen_CLI, ovl); + goto ok; + case 0x96: s390_format_SI(s390_irgen_OI, ovl); + goto ok; + case 0x97: s390_format_SI(s390_irgen_XI, ovl); + goto ok; + case 0x98: s390_format_RS(s390_irgen_LM, ovl); + goto ok; case 0x99: /* TRACE */ goto unimplemented; - case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, RS_r1(ovl), - RS_r3(ovl), RS_b2(ovl), RS_d2(ovl)); - goto ok; - case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, RS_r1(ovl), - RS_r3(ovl), RS_b2(ovl), RS_d2(ovl)); - goto ok; + case 0x9a: s390_format_RS(s390_irgen_LAM, ovl); + goto ok; + case 0x9b: s390_format_RS(s390_irgen_STAM, ovl); + goto ok; + case 0xa8: s390_format_RS(s390_irgen_MVCLE, ovl); + goto ok; + case 0xa9: s390_format_RS(s390_irgen_CLCLE, ovl); + goto ok; case 0xac: /* STNSM */ goto unimplemented; case 0xad: /* STOSM */ goto unimplemented; case 0xae: /* SIGP */ goto unimplemented; @@ -21920,16 +19369,16 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb1: /* LRA */ goto unimplemented; case 0xb6: /* STCTL */ goto unimplemented; case 0xb7: /* LCTL */ goto unimplemented; - case 0xba: s390_format_RS_RRRD(s390_irgen_CS, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; - case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, RS_r1(ovl), RS_r3(ovl), - RS_b2(ovl), RS_d2(ovl)); goto ok; + case 0xba: s390_format_RS(s390_irgen_CS, ovl); + goto ok; + case 0xbb: s390_format_RS(s390_irgen_CDS, ovl); + goto ok; + case 0xbd: s390_format_RS(s390_irgen_CLM, ovl); + goto ok; + case 0xbe: s390_format_RS(s390_irgen_STCM, ovl); + goto ok; + case 0xbf: s390_format_RS(s390_irgen_ICM, ovl); + goto ok; } return S390_DECODE_UNKNOWN_INSN; @@ -21949,509 +19398,276 @@ s390_decode_6byte_and_irgen(const UChar *bytes) ((ULong)bytes[4] << 24) | ((ULong)bytes[5] << 16); switch ((ovl >> 16) & 0xff00000000ffULL) { - case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe30000000002ULL: s390_format_RXY(s390_irgen_LTG, ovl); + goto ok; case 0xe30000000003ULL: /* LRAG */ goto unimplemented; - case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe30000000004ULL: s390_format_RXY(s390_irgen_LG, ovl); + goto ok; + case 0xe30000000006ULL: s390_format_RXY(s390_irgen_CVBY, ovl); + goto ok; + case 0xe30000000008ULL: s390_format_RXY(s390_irgen_AG, ovl); + goto ok; + case 0xe30000000009ULL: s390_format_RXY(s390_irgen_SG, ovl); + goto ok; + case 0xe3000000000aULL: s390_format_RXY(s390_irgen_ALG, ovl); + goto ok; + case 0xe3000000000bULL: s390_format_RXY(s390_irgen_SLG, ovl); + goto ok; + case 0xe3000000000cULL: s390_format_RXY(s390_irgen_MSG, ovl); + goto ok; + case 0xe3000000000dULL: s390_format_RXY(s390_irgen_DSG, ovl); + goto ok; case 0xe3000000000eULL: /* CVBG */ goto unimplemented; - case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe3000000000fULL: s390_format_RXY(s390_irgen_LRVG, ovl); + goto ok; + case 0xe30000000012ULL: s390_format_RXY(s390_irgen_LT, ovl); + goto ok; case 0xe30000000013ULL: /* LRAY */ goto unimplemented; - case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe30000000014ULL: s390_format_RXY(s390_irgen_LGF, ovl); + goto ok; + case 0xe30000000015ULL: s390_format_RXY(s390_irgen_LGH, ovl); + goto ok; + case 0xe30000000016ULL: s390_format_RXY(s390_irgen_LLGF, ovl); + goto ok; + case 0xe30000000017ULL: s390_format_RXY(s390_irgen_LLGT, ovl); + goto ok; + case 0xe30000000018ULL: s390_format_RXY(s390_irgen_AGF, ovl); + goto ok; + case 0xe30000000019ULL: s390_format_RXY(s390_irgen_SGF, ovl); + goto ok; + case 0xe3000000001aULL: s390_format_RXY(s390_irgen_ALGF, ovl); + goto ok; + case 0xe3000000001bULL: s390_format_RXY(s390_irgen_SLGF, ovl); + goto ok; + case 0xe3000000001cULL: s390_format_RXY(s390_irgen_MSGF, ovl); + goto ok; + case 0xe3000000001dULL: s390_format_RXY(s390_irgen_DSGF, ovl); + goto ok; + case 0xe3000000001eULL: s390_format_RXY(s390_irgen_LRV, ovl); + goto ok; + case 0xe3000000001fULL: s390_format_RXY(s390_irgen_LRVH, ovl); + goto ok; + case 0xe30000000020ULL: s390_format_RXY(s390_irgen_CG, ovl); + goto ok; + case 0xe30000000021ULL: s390_format_RXY(s390_irgen_CLG, ovl); + goto ok; + case 0xe30000000024ULL: s390_format_RXY(s390_irgen_STG, ovl); + goto ok; case 0xe30000000025ULL: /* NTSTG */ goto unimplemented; - case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000002aULL: s390_format_RXY_RRRD(s390_irgen_LZRG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe30000000026ULL: s390_format_RXY(s390_irgen_CVDY, ovl); + goto ok; + case 0xe3000000002aULL: s390_format_RXY(s390_irgen_LZRG, ovl); + goto ok; case 0xe3000000002eULL: /* CVDG */ goto unimplemented; - case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG, - RXY_r1(ovl), RXY_x2(ovl), - RXY_b2(ovl), RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000038ULL: s390_format_RXY_RRRD(s390_irgen_AGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000039ULL: s390_format_RXY_RRRD(s390_irgen_SGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000003bULL: s390_format_RXY_RRRD(s390_irgen_LZRF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000003cULL: s390_format_RXY_RRRD(s390_irgen_MGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH, - RXY_r1(ovl), RXY_x2(ovl), - RXY_b2(ovl), RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000047ULL: s390_format_RXY_RRRD(s390_irgen_BIC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xe3000000002fULL: s390_format_RXY(s390_irgen_STRVG, ovl); + goto ok; + case 0xe30000000030ULL: s390_format_RXY(s390_irgen_CGF, ovl); + goto ok; + case 0xe30000000031ULL: s390_format_RXY(s390_irgen_CLGF, ovl); + goto ok; + case 0xe30000000032ULL: s390_format_RXY(s390_irgen_LTGF, ovl); + goto ok; + case 0xe30000000034ULL: s390_format_RXY(s390_irgen_CGH, ovl); + goto ok; + case 0xe30000000036ULL: s390_irgen_PFD(); + goto ok; + case 0xe30000000038ULL: s390_format_RXY(s390_irgen_AGH, ovl); + goto ok; + case 0xe30000000039ULL: s390_format_RXY(s390_irgen_SGH, ovl); + goto ok; + case 0xe3000000003aULL: s390_format_RXY(s390_irgen_LLZRGF, ovl); + goto ok; + case 0xe3000000003bULL: s390_format_RXY(s390_irgen_LZRF, ovl); + goto ok; + case 0xe3000000003cULL: s390_format_RXY(s390_irgen_MGH, ovl); + goto ok; + case 0xe3000000003eULL: s390_format_RXY(s390_irgen_STRV, ovl); + goto ok; + case 0xe3000000003fULL: s390_format_RXY(s390_irgen_STRVH, ovl); + goto ok; + case 0xe30000000046ULL: s390_format_RXY(s390_irgen_BCTG, ovl); + goto ok; + case 0xe30000000047ULL: s390_format_RXY(s390_irgen_BIC, ovl); + goto ok; case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented; case 0xe30000000049ULL: /* STGSC */ goto unimplemented; case 0xe3000000004cULL: /* LGG */ goto unimplemented; case 0xe3000000004dULL: /* LGSC */ goto unimplemented; - case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000053ULL: s390_format_RXY_RRRD(s390_irgen_MSC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000060ULL: /* LXAB */ goto unimplemented; - case 0xe30000000061ULL: /* LLXAB */ goto unimplemented; - case 0xe30000000062ULL: /* LXAH */ goto unimplemented; - case 0xe30000000063ULL: /* LLXAH */ goto unimplemented; - case 0xe30000000064ULL: /* LXAF */ goto unimplemented; - case 0xe30000000065ULL: /* LLXAF */ goto unimplemented; - case 0xe30000000066ULL: /* LXAG */ goto unimplemented; - case 0xe30000000067ULL: /* LLXAG */ goto unimplemented; - case 0xe30000000068ULL: /* LXAQ */ goto unimplemented; - case 0xe30000000069ULL: /* LLXAQ */ goto unimplemented; - case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000083ULL: s390_format_RXY_RRRD(s390_irgen_MSGC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000084ULL: s390_format_RXY_RRRD(s390_irgen_MG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - - case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000009cULL: s390_format_RXY_RRRD(s390_irgen_LLGTAT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000009dULL: s390_format_RXY_RRRD(s390_irgen_LLGFAT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe3000000009fULL: s390_format_RXY_RRRD(s390_irgen_LAT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000c8ULL: s390_format_RXY_RRRD(s390_irgen_LFHAT, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe60000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRH, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe60000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRG, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe60000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRF, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe60000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEBRZ, - VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), vllebrz_disasm); goto ok; - case 0xe60000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLBRREP, - VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; - case 0xe60000000006ULL: s390_format_VRX_VRRDM(s390_irgen_VLBR, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; - case 0xe60000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLER, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; - case 0xe60000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRH, - VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe6000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRG, - VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), vstebrg_disasm); goto ok; - case 0xe6000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRF, - VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), vstebrf_disasm); goto ok; - case 0xe6000000000eULL: s390_format_VRX_VRRDM(s390_irgen_VSTBR, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; - case 0xe6000000000fULL: s390_format_VRX_VRRDM(s390_irgen_VSTER, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; + case 0xe30000000050ULL: s390_format_RXY(s390_irgen_STY, ovl); + goto ok; + case 0xe30000000051ULL: s390_format_RXY(s390_irgen_MSY, ovl); + goto ok; + case 0xe30000000053ULL: s390_format_RXY(s390_irgen_MSC, ovl); + goto ok; + case 0xe30000000054ULL: s390_format_RXY(s390_irgen_NY, ovl); + goto ok; + case 0xe30000000055ULL: s390_format_RXY(s390_irgen_CLY, ovl); + goto ok; + case 0xe30000000056ULL: s390_format_RXY(s390_irgen_OY, ovl); + goto ok; + case 0xe30000000057ULL: s390_format_RXY(s390_irgen_XY, ovl); + goto ok; + case 0xe30000000058ULL: s390_format_RXY(s390_irgen_LY, ovl); + goto ok; + case 0xe30000000059ULL: s390_format_RXY(s390_irgen_CY, ovl); + goto ok; + case 0xe3000000005aULL: s390_format_RXY(s390_irgen_AY, ovl); + goto ok; + case 0xe3000000005bULL: s390_format_RXY(s390_irgen_SY, ovl); + goto ok; + case 0xe3000000005cULL: s390_format_RXY(s390_irgen_MFY, ovl); + goto ok; + case 0xe3000000005eULL: s390_format_RXY(s390_irgen_ALY, ovl); + goto ok; + case 0xe3000000005fULL: s390_format_RXY(s390_irgen_SLY, ovl); + goto ok; + case 0xe30000000060ULL: s390_format_RXYc(s390_irgen_LXAB, ovl); + goto ok; + case 0xe30000000061ULL: s390_format_RXYc(s390_irgen_LLXAB, ovl); + goto ok; + case 0xe30000000062ULL: s390_format_RXYc(s390_irgen_LXAH, ovl); + goto ok; + case 0xe30000000063ULL: s390_format_RXYc(s390_irgen_LLXAH, ovl); + goto ok; + case 0xe30000000064ULL: s390_format_RXYc(s390_irgen_LXAF, ovl); + goto ok; + case 0xe30000000065ULL: s390_format_RXYc(s390_irgen_LLXAF, ovl); + goto ok; + case 0xe30000000066ULL: s390_format_RXYc(s390_irgen_LXAG, ovl); + goto ok; + case 0xe30000000067ULL: s390_format_RXYc(s390_irgen_LLXAG, ovl); + goto ok; + case 0xe30000000068ULL: s390_format_RXYc(s390_irgen_LXAQ, ovl); + goto ok; + case 0xe30000000069ULL: s390_format_RXYc(s390_irgen_LLXAQ, ovl); + goto ok; + case 0xe30000000070ULL: s390_format_RXY(s390_irgen_STHY, ovl); + goto ok; + case 0xe30000000071ULL: s390_format_RXY(s390_irgen_LAY, ovl); + goto ok; + case 0xe30000000072ULL: s390_format_RXY(s390_irgen_STCY, ovl); + goto ok; + case 0xe30000000073ULL: s390_format_RXY(s390_irgen_ICY, ovl); + goto ok; + case 0xe30000000075ULL: s390_format_RXY(s390_irgen_LAEY, ovl); + goto ok; + case 0xe30000000076ULL: s390_format_RXY(s390_irgen_LB, ovl); + goto ok; + case 0xe30000000077ULL: s390_format_RXY(s390_irgen_LGB, ovl); + goto ok; + case 0xe30000000078ULL: s390_format_RXY(s390_irgen_LHY, ovl); + goto ok; + case 0xe30000000079ULL: s390_format_RXY(s390_irgen_CHY, ovl); + goto ok; + case 0xe3000000007aULL: s390_format_RXY(s390_irgen_AHY, ovl); + goto ok; + case 0xe3000000007bULL: s390_format_RXY(s390_irgen_SHY, ovl); + goto ok; + case 0xe3000000007cULL: s390_format_RXY(s390_irgen_MHY, ovl); + goto ok; + case 0xe30000000080ULL: s390_format_RXY(s390_irgen_NG, ovl); + goto ok; + case 0xe30000000081ULL: s390_format_RXY(s390_irgen_OG, ovl); + goto ok; + case 0xe30000000082ULL: s390_format_RXY(s390_irgen_XG, ovl); + goto ok; + case 0xe30000000083ULL: s390_format_RXY(s390_irgen_MSGC, ovl); + goto ok; + case 0xe30000000084ULL: s390_format_RXY(s390_irgen_MG, ovl); + goto ok; + case 0xe30000000085ULL: s390_format_RXY(s390_irgen_LGAT, ovl); + goto ok; + + case 0xe30000000086ULL: s390_format_RXY(s390_irgen_MLG, ovl); + goto ok; + case 0xe30000000087ULL: s390_format_RXY(s390_irgen_DLG, ovl); + goto ok; + case 0xe30000000088ULL: s390_format_RXY(s390_irgen_ALCG, ovl); + goto ok; + case 0xe30000000089ULL: s390_format_RXY(s390_irgen_SLBG, ovl); + goto ok; + case 0xe3000000008eULL: s390_format_RXY(s390_irgen_STPQ, ovl); + goto ok; + case 0xe3000000008fULL: s390_format_RXY(s390_irgen_LPQ, ovl); + goto ok; + case 0xe30000000090ULL: s390_format_RXY(s390_irgen_LLGC, ovl); + goto ok; + case 0xe30000000091ULL: s390_format_RXY(s390_irgen_LLGH, ovl); + goto ok; + case 0xe30000000094ULL: s390_format_RXY(s390_irgen_LLC, ovl); + goto ok; + case 0xe30000000095ULL: s390_format_RXY(s390_irgen_LLH, ovl); + goto ok; + case 0xe30000000096ULL: s390_format_RXY(s390_irgen_ML, ovl); + goto ok; + case 0xe30000000097ULL: s390_format_RXY(s390_irgen_DL, ovl); + goto ok; + case 0xe30000000098ULL: s390_format_RXY(s390_irgen_ALC, ovl); + goto ok; + case 0xe30000000099ULL: s390_format_RXY(s390_irgen_SLB, ovl); + goto ok; + case 0xe3000000009cULL: s390_format_RXY(s390_irgen_LLGTAT, ovl); + goto ok; + case 0xe3000000009dULL: s390_format_RXY(s390_irgen_LLGFAT, ovl); + goto ok; + case 0xe3000000009fULL: s390_format_RXY(s390_irgen_LAT, ovl); + goto ok; + case 0xe300000000c0ULL: s390_format_RXY(s390_irgen_LBH, ovl); + goto ok; + case 0xe300000000c2ULL: s390_format_RXY(s390_irgen_LLCH, ovl); + goto ok; + case 0xe300000000c3ULL: s390_format_RXY(s390_irgen_STCH, ovl); + goto ok; + case 0xe300000000c4ULL: s390_format_RXY(s390_irgen_LHH, ovl); + goto ok; + case 0xe300000000c6ULL: s390_format_RXY(s390_irgen_LLHH, ovl); + goto ok; + case 0xe300000000c7ULL: s390_format_RXY(s390_irgen_STHH, ovl); + goto ok; + case 0xe300000000c8ULL: s390_format_RXY(s390_irgen_LFHAT, ovl); + goto ok; + case 0xe300000000caULL: s390_format_RXY(s390_irgen_LFH, ovl); + goto ok; + case 0xe300000000cbULL: s390_format_RXY(s390_irgen_STFH, ovl); + goto ok; + case 0xe300000000cdULL: s390_format_RXY(s390_irgen_CHF, ovl); + goto ok; + case 0xe300000000cfULL: s390_format_RXY(s390_irgen_CLHF, ovl); + goto ok; + case 0xe60000000001ULL: s390_format_VRX(s390_irgen_VLEBRH, ovl); + goto ok; + case 0xe60000000002ULL: s390_format_VRX(s390_irgen_VLEBRG, ovl); + goto ok; + case 0xe60000000003ULL: s390_format_VRX(s390_irgen_VLEBRF, ovl); + goto ok; + case 0xe60000000004ULL: s390_format_VRX(s390_irgen_VLLEBRZ, ovl); + goto ok; + case 0xe60000000005ULL: s390_format_VRX(s390_irgen_VLBRREP, ovl); + goto ok; + case 0xe60000000006ULL: s390_format_VRX(s390_irgen_VLBR, ovl); + goto ok; + case 0xe60000000007ULL: s390_format_VRX(s390_irgen_VLER, ovl); + goto ok; + case 0xe60000000009ULL: s390_format_VRX(s390_irgen_VSTEBRH, ovl); + goto ok; + case 0xe6000000000aULL: s390_format_VRX(s390_irgen_VSTEBRG, ovl); + goto ok; + case 0xe6000000000bULL: s390_format_VRX(s390_irgen_VSTEBRF, ovl); + goto ok; + case 0xe6000000000eULL: s390_format_VRX(s390_irgen_VSTBR, ovl); + goto ok; + case 0xe6000000000fULL: s390_format_VRX(s390_irgen_VSTER, ovl); + goto ok; case 0xe60000000034ULL: /* VPKZ */ goto unimplemented; - case 0xe60000000035ULL: s390_format_VSI_URDV(s390_irgen_VLRL, VSI_v1(ovl), - VSI_b2(ovl), VSI_d2(ovl), - VSI_i3(ovl), - VSI_rxb(ovl)); goto ok; - case 0xe60000000037ULL: s390_format_VRS_RRDV(s390_irgen_VLRLR, VRSd_v1(ovl), - VRSd_r3(ovl), VRS_b2(ovl), - VRS_d2(ovl), - VRS_rxb(ovl)); goto ok; + case 0xe60000000035ULL: s390_format_VSI(s390_irgen_VLRL, ovl); + goto ok; + case 0xe60000000037ULL: s390_format_VRSd(s390_irgen_VLRLR, ovl); + goto ok; case 0xe6000000003cULL: /* VUPKZ */ goto unimplemented; - case 0xe6000000003dULL: s390_format_VSI_URDV(s390_irgen_VSTRL, VSI_v1(ovl), - VSI_b2(ovl), VSI_d2(ovl), - VSI_i3(ovl), - VSI_rxb(ovl)); goto ok; - case 0xe6000000003fULL: s390_format_VRS_RRDV(s390_irgen_VSTRLR, VRSd_v1(ovl), - VRSd_r3(ovl), VRS_b2(ovl), - VRS_d2(ovl), - VRS_rxb(ovl)); goto ok; + case 0xe6000000003dULL: s390_format_VSI(s390_irgen_VSTRL, ovl); + goto ok; + case 0xe6000000003fULL: s390_format_VRSd(s390_irgen_VSTRLR, ovl); + goto ok; case 0xe60000000049ULL: /* VLIP */ goto unimplemented; case 0xe6000000004aULL: /* VCVDQ */ goto unimplemented; case 0xe6000000004eULL: /* VCVBQ */ goto unimplemented; @@ -22459,22 +19675,14 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe60000000051ULL: /* VCLZDP */ goto unimplemented; case 0xe60000000052ULL: /* VCVBG */ goto unimplemented; case 0xe60000000054ULL: /* VUPKZH */ goto unimplemented; - case 0xe60000000055ULL: s390_format_VRRa_VVMM(s390_irgen_VCNF, - VRRa_v1(ovl), VRRa_v2(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), NULL); goto ok; - case 0xe60000000056ULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNH, - VRRa_v1(ovl), VRRa_v2(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), NULL); goto ok; - case 0xe6000000005dULL: s390_format_VRRa_VVMM(s390_irgen_VCFN, - VRRa_v1(ovl), VRRa_v2(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), NULL); goto ok; - case 0xe6000000005eULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNL, - VRRa_v1(ovl), VRRa_v2(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), NULL); goto ok; + case 0xe60000000055ULL: s390_format_VRRa2(s390_irgen_VCNF, ovl); + goto ok; + case 0xe60000000056ULL: s390_format_VRRa2(s390_irgen_VCLFNH, ovl); + goto ok; + case 0xe6000000005dULL: s390_format_VRRa2(s390_irgen_VCFN, ovl); + goto ok; + case 0xe6000000005eULL: s390_format_VRRa2(s390_irgen_VCLFNL, ovl); + goto ok; case 0xe60000000058ULL: /* VCVD */ goto unimplemented; case 0xe60000000059ULL: /* VSRP */ goto unimplemented; case 0xe6000000005aULL: /* VCVDG */ goto unimplemented; @@ -22485,11 +19693,8 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe60000000071ULL: /* VAP */ goto unimplemented; case 0xe60000000072ULL: /* VSRPR */ goto unimplemented; case 0xe60000000073ULL: /* VSP */ goto unimplemented; - case 0xe60000000075ULL: s390_format_VRRa_VVVMM(s390_irgen_VCRNF, - VRRa_v1(ovl), VRRa_v2(ovl), - VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), NULL); goto ok; + case 0xe60000000075ULL: s390_format_VRRc2(s390_irgen_VCRNF, ovl); + goto ok; case 0xe60000000077ULL: /* VCP */ goto unimplemented; case 0xe60000000078ULL: /* VMP */ goto unimplemented; case 0xe60000000079ULL: /* VMSP */ goto unimplemented; @@ -22500,1031 +19705,607 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe6000000007dULL: /* VCSPH */ goto unimplemented; case 0xe6000000007eULL: /* VSDP */ goto unimplemented; case 0xe6000000007fULL: /* VTZ */ goto unimplemented; - case 0xe70000000000ULL: s390_format_VRX_VRRDM(s390_irgen_VLEB, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEH, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEG, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEF, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEZ, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), vllez_disasm); goto ok; - case 0xe70000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLREP, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), va_like_disasm); goto ok; - case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; - case 0xe70000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLBB, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000008ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEB, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe70000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEH, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe7000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEG, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe7000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEF, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), NULL); goto ok; - case 0xe7000000000eULL: s390_format_VRX_VRRD(s390_irgen_VST, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; - case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, VRV_v1(ovl), - VRV_x2(ovl), VRV_b2(ovl), - VRV_d2(ovl), VRV_m3(ovl), - VRV_rxb(ovl), Ity_I64); goto ok; - case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, VRV_v1(ovl), - VRV_x2(ovl), VRV_b2(ovl), - VRV_d2(ovl), VRV_m3(ovl), - VRV_rxb(ovl), Ity_I32); goto ok; - case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, VRV_v1(ovl), - VRV_x2(ovl), VRV_b2(ovl), - VRV_d2(ovl), VRV_m3(ovl), - VRV_rxb(ovl), Ity_I64); goto ok; - case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, VRV_v1(ovl), - VRV_x2(ovl), VRV_b2(ovl), - VRV_d2(ovl), VRV_m3(ovl), - VRV_rxb(ovl), Ity_I32); goto ok; - case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, VRSc_r1(ovl), - VRSc_b2(ovl), VRSc_d2(ovl), VRSc_v3(ovl), - VRSc_m4(ovl), VRSc_rxb(ovl)); goto ok; - case 0xe70000000022ULL: s390_format_VRS_VRRDM(s390_irgen_VLVG, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_m4(ovl), VRS_rxb(ovl)); goto ok; - case 0xe70000000027ULL: s390_format_RXE_RRRDR(s390_irgen_LCBB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl), RXE_m3(ovl)); goto ok; - case 0xe70000000030ULL: s390_format_VRS_VRDVM(s390_irgen_VESL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), - VRS_v3(ovl), VRS_m4(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe70000000033ULL: s390_format_VRS_VRDVM(s390_irgen_VERLL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), - VRS_v3(ovl), VRS_m4(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe70000000036ULL: s390_format_VRS_VRDV(s390_irgen_VLM, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_m4(ovl), VRS_rxb(ovl)); goto ok; - case 0xe70000000037ULL: s390_format_VRS_VRRD(s390_irgen_VLL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_r3(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe70000000038ULL: s390_format_VRS_VRDVM(s390_irgen_VESRL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), - VRS_v3(ovl), VRS_m4(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe7000000003aULL: s390_format_VRS_VRDVM(s390_irgen_VESRA, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), - VRS_v3(ovl), VRS_m4(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe7000000003eULL: s390_format_VRS_VRDV(s390_irgen_VSTM, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_m4(ovl), VRS_rxb(ovl)); goto ok; - case 0xe7000000003fULL: s390_format_VRS_VRRD(s390_irgen_VSTL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_r3(ovl), - VRS_rxb(ovl)); goto ok; - case 0xe70000000040ULL: s390_format_VRI_VIM(s390_irgen_VLEIB, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000041ULL: s390_format_VRI_VIM(s390_irgen_VLEIH, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000042ULL: s390_format_VRI_VIM(s390_irgen_VLEIG, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000043ULL: s390_format_VRI_VIM(s390_irgen_VLEIF, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok;break; - case 0xe70000000044ULL: s390_format_VRI_V0U(s390_irgen_VGBM, VRI_v1(ovl), - VRI_i2(ovl), VRI_rxb(ovl), - vgbm_disasm); goto ok; - case 0xe70000000045ULL: s390_format_VRI_V0IU(s390_irgen_VREPI, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000046ULL: s390_format_VRI_V0UUU(s390_irgen_VGM, VRIb_v1(ovl), - VRIb_i2(ovl), VRIb_i3(ovl), VRIb_m4(ovl), - VRIb_rxb(ovl)); goto ok; - case 0xe7000000004aULL: s390_format_VRI_VVIMM(s390_irgen_VFTCI, VRIe_v1(ovl), - VRIe_v2(ovl), VRIe_i3(ovl), - VRIe_m4(ovl), VRIe_m5(ovl), - VRIe_rxb(ovl)); goto ok; - case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, VRIc_v1(ovl), - VRIc_v3(ovl), VRIc_i2(ovl), - VRIc_m4(ovl), VRIc_rxb(ovl)); goto ok; - case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe70000000054ULL: /* VGEM */ goto unimplemented; - case 0xe70000000056ULL: s390_format_VRR_VV(s390_irgen_VLR, VRR_v1(ovl), - VRR_v2(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000005cULL: s390_format_VRR_VVMM(s390_irgen_VISTR, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_m5(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe70000000060ULL: s390_format_VRR_VVVM(s390_irgen_VMRL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000061ULL: s390_format_VRR_VVVM(s390_irgen_VMRH, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000062ULL: s390_format_VRR_VRR(s390_irgen_VLVGP, VRR_v1(ovl), - VRR_r2(ovl), VRR_r3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000064ULL: s390_format_VRR_VVVM(s390_irgen_VSUM, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000065ULL: s390_format_VRR_VVVM(s390_irgen_VSUMG, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000066ULL: s390_format_VRR_VVV(s390_irgen_VCKSM, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000067ULL: s390_format_VRR_VVVM(s390_irgen_VSUMQ, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000068ULL: s390_format_VRR_VVV(s390_irgen_VN, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000069ULL: s390_format_VRR_VVV(s390_irgen_VNC, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006aULL: s390_format_VRR_VVV(s390_irgen_VO, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006cULL: s390_format_VRR_VVV(s390_irgen_VNX, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006eULL: s390_format_VRR_VVV(s390_irgen_VNN, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000006fULL: s390_format_VRR_VVV(s390_irgen_VOC, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000072ULL: s390_format_VRId_VVVIM(s390_irgen_VERIM, VRId_v1(ovl), - VRId_v2(ovl), VRId_v3(ovl), - VRId_i4(ovl), VRId_m5(ovl), - VRId_rxb(ovl)); goto ok; - case 0xe70000000073ULL: s390_format_VRR_VVVM(s390_irgen_VERLLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000074ULL: s390_format_VRR_VVV(s390_irgen_VSL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000075ULL: s390_format_VRR_VVV(s390_irgen_VSLB, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000077ULL: s390_format_VRId_VVVI(s390_irgen_VSLDB, VRId_v1(ovl), - VRId_v2(ovl), VRId_v3(ovl), - VRId_i4(ovl), VRId_rxb(ovl)); goto ok; - case 0xe70000000078ULL: s390_format_VRR_VVVM(s390_irgen_VESRLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000007aULL: s390_format_VRR_VVVM(s390_irgen_VESRAV, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000007cULL: s390_format_VRR_VVV(s390_irgen_VSRL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000007dULL: s390_format_VRR_VVV(s390_irgen_VSRLB, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000007eULL: s390_format_VRR_VVV(s390_irgen_VSRA, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe7000000007fULL: s390_format_VRR_VVV(s390_irgen_VSRAB, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000080ULL: s390_format_VRR_VVVMM(s390_irgen_VFEE, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vfae_like_disasm); goto ok; - case 0xe70000000081ULL: s390_format_VRR_VVVMM(s390_irgen_VFENE, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vfae_like_disasm); goto ok; - case 0xe70000000082ULL: s390_format_VRR_VVVMM(s390_irgen_VFAE, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vfae_like_disasm); goto ok; - case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000085ULL: s390_format_VRR_VVV(s390_irgen_VBPERM, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000086ULL: s390_format_VRId_VVVI(s390_irgen_VSLD, VRId_v1(ovl), - VRId_v2(ovl), VRId_v3(ovl), - VRId_i4(ovl), - VRId_rxb(ovl)); goto ok; - case 0xe70000000087ULL: s390_format_VRId_VVVI(s390_irgen_VSRD, VRId_v1(ovl), - VRId_v2(ovl), VRId_v3(ovl), - VRId_i4(ovl), - VRId_rxb(ovl)); goto ok; - case 0xe70000000088ULL: /* VEVAL */ goto unimplemented; - case 0xe70000000089ULL: /* VBLEND */ goto unimplemented; - case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), VRRd_rxb(ovl), - vstrc_disasm); goto ok; - case 0xe7000000008bULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRS, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), VRRd_rxb(ovl), - vfae_like_disasm); goto ok; - case 0xe7000000008cULL: s390_format_VRR_VVVV(s390_irgen_VPERM, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_v4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000008dULL: s390_format_VRR_VVVV(s390_irgen_VSEL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_v4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000008eULL: s390_format_VRR_VVVVMM(s390_irgen_VFMS, VRRe_v1(ovl), - VRRe_v2(ovl), VRRe_v3(ovl), - VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), VRRe_rxb(ovl), - vfms_like_disasm); goto ok; - case 0xe7000000008fULL: s390_format_VRR_VVVVMM(s390_irgen_VFMA, VRRe_v1(ovl), - VRRe_v2(ovl), VRRe_v3(ovl), - VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), VRRe_rxb(ovl), - vfms_like_disasm); goto ok; - case 0xe70000000094ULL: s390_format_VRR_VVVM(s390_irgen_VPK, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe70000000095ULL: s390_format_VRR_VVVMM(s390_irgen_VPKLS, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vch_like_disasm); goto ok; - case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vch_like_disasm); goto ok; - case 0xe7000000009eULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMS, VRRe_v1(ovl), - VRRe_v2(ovl), VRRe_v3(ovl), - VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), VRRe_rxb(ovl), - vfms_like_disasm); goto ok; - case 0xe7000000009fULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMA, VRRe_v1(ovl), - VRRe_v2(ovl), VRRe_v3(ovl), - VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), VRRe_rxb(ovl), - vfms_like_disasm); goto ok; - case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a2ULL: s390_format_VRR_VVVM(s390_irgen_VML, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a3ULL: s390_format_VRR_VVVM(s390_irgen_VMH, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a4ULL: s390_format_VRR_VVVM(s390_irgen_VMLE, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a5ULL: s390_format_VRR_VVVM(s390_irgen_VMLO, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a6ULL: s390_format_VRR_VVVM(s390_irgen_VME, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a7ULL: s390_format_VRR_VVVM(s390_irgen_VMO, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000a9ULL: s390_format_VRRd_VVVVM(s390_irgen_VMALH, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000aaULL: s390_format_VRRd_VVVVM(s390_irgen_VMAL, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000abULL: s390_format_VRRd_VVVVM(s390_irgen_VMAH, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000acULL: s390_format_VRRd_VVVVM(s390_irgen_VMALE, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000adULL: s390_format_VRRd_VVVVM(s390_irgen_VMALO, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000aeULL: s390_format_VRRd_VVVVM(s390_irgen_VMAE, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000afULL: s390_format_VRRd_VVVVM(s390_irgen_VMAO, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000b0ULL: /* VDL */ goto unimplemented; - case 0xe700000000b1ULL: /* VRL */ goto unimplemented; - case 0xe700000000b2ULL: /* VD */ goto unimplemented; - case 0xe700000000b3ULL: /* VR */ goto unimplemented; - case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000b8ULL: s390_format_VRR_VVVVMM(s390_irgen_VMSL, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), VRRd_rxb(ovl), - vmsl_disasm); goto ok; - case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000bbULL: s390_format_VRRd_VVVVM(s390_irgen_VAC, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000bcULL: s390_format_VRRd_VVVVM(s390_irgen_VGFMA, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000bdULL: s390_format_VRRd_VVVVM(s390_irgen_VSBCBI, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000bfULL: s390_format_VRRd_VVVVM(s390_irgen_VSBI, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_rxb(ovl)); goto ok; - case 0xe700000000c0ULL: s390_format_VRRa_VVMMM(s390_irgen_VCLGD, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000c1ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDLG, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000c2ULL: s390_format_VRRa_VVMMM(s390_irgen_VCGD, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000c3ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDG, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000c4ULL: s390_format_VRRa_VVMM(s390_irgen_VFLL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_rxb(ovl), - vfll_disasm); goto ok; - case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLR, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000c7ULL: s390_format_VRRa_VVMMM(s390_irgen_VFI, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000caULL: s390_format_VRRa_VVMM(s390_irgen_WFK, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_rxb(ovl), - wfc_like_disasm); goto ok; - case 0xe700000000cbULL: s390_format_VRRa_VVMM(s390_irgen_WFC, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_rxb(ovl), - wfc_like_disasm); goto ok; - case 0xe700000000ccULL: s390_format_VRRa_VVMMM(s390_irgen_VFPSO, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000ceULL: s390_format_VRRa_VVMM(s390_irgen_VFSQ, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), - VRRa_rxb(ovl), vfmix_like_disasm); goto ok; - case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000d8ULL: s390_format_VRR_VV(s390_irgen_VTM, VRR_v1(ovl), - VRR_v2(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000e2ULL: s390_format_VRRa_VVVMM(s390_irgen_VFS, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), vfa_like_disasm); goto ok; - case 0xe700000000e3ULL: s390_format_VRRa_VVVMM(s390_irgen_VFA, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), vfa_like_disasm); goto ok; - case 0xe700000000e5ULL: s390_format_VRRa_VVVMM(s390_irgen_VFD, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), vfa_like_disasm); goto ok; - case 0xe700000000e7ULL: s390_format_VRRa_VVVMM(s390_irgen_VFM, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl), vfa_like_disasm); goto ok; - case 0xe700000000e8ULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCE, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000eaULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCHE, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000ebULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCH, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000eeULL: s390_format_VRRa_VVVMMM2(s390_irgen_VFMIN, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000efULL: s390_format_VRRa_VVVMMM2(s390_irgen_VFMAX, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f1ULL: s390_format_VRR_VVVM(s390_irgen_VACC, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f2ULL: s390_format_VRR_VVVM(s390_irgen_VAVG, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f3ULL: s390_format_VRR_VVVM(s390_irgen_VA, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f5ULL: s390_format_VRR_VVVM(s390_irgen_VSCBI, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f7ULL: s390_format_VRR_VVVM(s390_irgen_VS, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000f8ULL: s390_format_VRR_VVVMM(s390_irgen_VCEQ, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vch_like_disasm); goto ok; - case 0xe700000000f9ULL: s390_format_VRR_VVVMM(s390_irgen_VCHL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vch_like_disasm); goto ok; - case 0xe700000000fbULL: s390_format_VRR_VVVMM(s390_irgen_VCH, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), - vch_like_disasm); goto ok; - case 0xe700000000fcULL: s390_format_VRR_VVVM(s390_irgen_VMNL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000fdULL: s390_format_VRR_VVVM(s390_irgen_VMXL, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000feULL: s390_format_VRR_VVVM(s390_irgen_VMN, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000ffULL: s390_format_VRR_VVVM(s390_irgen_VMX, VRR_v1(ovl), - VRR_v2(ovl), VRR_v3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; - case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xe70000000000ULL: s390_format_VRX(s390_irgen_VLEB, ovl); + goto ok; + case 0xe70000000001ULL: s390_format_VRX(s390_irgen_VLEH, ovl); + goto ok; + case 0xe70000000002ULL: s390_format_VRX(s390_irgen_VLEG, ovl); + goto ok; + case 0xe70000000003ULL: s390_format_VRX(s390_irgen_VLEF, ovl); + goto ok; + case 0xe70000000004ULL: s390_format_VRX(s390_irgen_VLLEZ, ovl); + goto ok; + case 0xe70000000005ULL: s390_format_VRX(s390_irgen_VLREP, ovl); + goto ok; + case 0xe70000000006ULL: s390_format_VRX(s390_irgen_VL, ovl); + goto ok; + case 0xe70000000007ULL: s390_format_VRX(s390_irgen_VLBB, ovl); + goto ok; + case 0xe70000000008ULL: s390_format_VRX(s390_irgen_VSTEB, ovl); + goto ok; + case 0xe70000000009ULL: s390_format_VRX(s390_irgen_VSTEH, ovl); + goto ok; + case 0xe7000000000aULL: s390_format_VRX(s390_irgen_VSTEG, ovl); + goto ok; + case 0xe7000000000bULL: s390_format_VRX(s390_irgen_VSTEF, ovl); + goto ok; + case 0xe7000000000eULL: s390_format_VRX(s390_irgen_VST, ovl); + goto ok; + case 0xe70000000012ULL: s390_format_VRV(s390_irgen_VGEG, ovl, Ity_I64); + goto ok; + case 0xe70000000013ULL: s390_format_VRV(s390_irgen_VGEF, ovl, Ity_I32); + goto ok; + case 0xe7000000001aULL: s390_format_VRV(s390_irgen_VSCEG, ovl, Ity_I64); + goto ok; + case 0xe7000000001bULL: s390_format_VRV(s390_irgen_VSCEF, ovl, Ity_I32); + goto ok; + case 0xe70000000021ULL: s390_format_VRSc(s390_irgen_VLGV, ovl); + goto ok; + case 0xe70000000022ULL: s390_format_VRSbm(s390_irgen_VLVG, ovl); + goto ok; + case 0xe70000000027ULL: s390_format_RXE(s390_irgen_LCBB, ovl); + goto ok; + case 0xe70000000030ULL: s390_format_VRSa(s390_irgen_VESL, ovl); + goto ok; + case 0xe70000000033ULL: s390_format_VRSa(s390_irgen_VERLL, ovl); + goto ok; + case 0xe70000000036ULL: s390_format_VRSa(s390_irgen_VLM, ovl); + goto ok; + case 0xe70000000037ULL: s390_format_VRSb(s390_irgen_VLL, ovl); + goto ok; + case 0xe70000000038ULL: s390_format_VRSa(s390_irgen_VESRL, ovl); + goto ok; + case 0xe7000000003aULL: s390_format_VRSa(s390_irgen_VESRA, ovl); + goto ok; + case 0xe7000000003eULL: s390_format_VRSa(s390_irgen_VSTM, ovl); + goto ok; + case 0xe7000000003fULL: s390_format_VRSb(s390_irgen_VSTL, ovl); + goto ok; + case 0xe70000000040ULL: s390_format_VRIa(s390_irgen_VLEIB, ovl); + goto ok; + case 0xe70000000041ULL: s390_format_VRIa(s390_irgen_VLEIH, ovl); + goto ok; + case 0xe70000000042ULL: s390_format_VRIa(s390_irgen_VLEIG, ovl); + goto ok; + case 0xe70000000043ULL: s390_format_VRIa(s390_irgen_VLEIF, ovl); + goto ok; + case 0xe70000000044ULL: s390_format_VRIa0(s390_irgen_VGBM, ovl); + goto ok; + case 0xe70000000045ULL: s390_format_VRIa(s390_irgen_VREPI, ovl); + goto ok; + case 0xe70000000046ULL: s390_format_VRIb(s390_irgen_VGM, ovl); + goto ok; + case 0xe7000000004aULL: s390_format_VRIe(s390_irgen_VFTCI, ovl); + goto ok; + case 0xe7000000004dULL: s390_format_VRIc(s390_irgen_VREP, ovl); + goto ok; + case 0xe70000000050ULL: s390_format_VRRa1(s390_irgen_VPOPCT, ovl); + goto ok; + case 0xe70000000052ULL: s390_format_VRRa1(s390_irgen_VCTZ, ovl); + goto ok; + case 0xe70000000053ULL: s390_format_VRRa1(s390_irgen_VCLZ, ovl); + goto ok; + case 0xe70000000054ULL: s390_format_VRRa1(s390_irgen_VGEM, ovl); + goto ok; + case 0xe70000000056ULL: s390_format_VRRa0(s390_irgen_VLR, ovl); + goto ok; + case 0xe7000000005cULL: s390_format_VRRa(s390_irgen_VISTR, ovl); + goto ok; + case 0xe7000000005fULL: s390_format_VRRa1(s390_irgen_VSEG, ovl); + goto ok; + case 0xe70000000060ULL: s390_format_VRRc1(s390_irgen_VMRL, ovl); + goto ok; + case 0xe70000000061ULL: s390_format_VRRc1(s390_irgen_VMRH, ovl); + goto ok; + case 0xe70000000062ULL: s390_format_VRRf(s390_irgen_VLVGP, ovl); + goto ok; + case 0xe70000000064ULL: s390_format_VRRc1(s390_irgen_VSUM, ovl); + goto ok; + case 0xe70000000065ULL: s390_format_VRRc1(s390_irgen_VSUMG, ovl); + goto ok; + case 0xe70000000066ULL: s390_format_VRRc0(s390_irgen_VCKSM, ovl); + goto ok; + case 0xe70000000067ULL: s390_format_VRRc1(s390_irgen_VSUMQ, ovl); + goto ok; + case 0xe70000000068ULL: s390_format_VRRc0(s390_irgen_VN, ovl); + goto ok; + case 0xe70000000069ULL: s390_format_VRRc0(s390_irgen_VNC, ovl); + goto ok; + case 0xe7000000006aULL: s390_format_VRRc0(s390_irgen_VO, ovl); + goto ok; + case 0xe7000000006bULL: s390_format_VRRc0(s390_irgen_VNO, ovl); + goto ok; + case 0xe7000000006cULL: s390_format_VRRc0(s390_irgen_VNX, ovl); + goto ok; + case 0xe7000000006dULL: s390_format_VRRc0(s390_irgen_VX, ovl); + goto ok; + case 0xe7000000006eULL: s390_format_VRRc0(s390_irgen_VNN, ovl); + goto ok; + case 0xe7000000006fULL: s390_format_VRRc0(s390_irgen_VOC, ovl); + goto ok; + case 0xe70000000070ULL: s390_format_VRRc1(s390_irgen_VESLV, ovl); + goto ok; + case 0xe70000000072ULL: s390_format_VRIdm(s390_irgen_VERIM, ovl); + goto ok; + case 0xe70000000073ULL: s390_format_VRRc1(s390_irgen_VERLLV, ovl); + goto ok; + case 0xe70000000074ULL: s390_format_VRRc0(s390_irgen_VSL, ovl); + goto ok; + case 0xe70000000075ULL: s390_format_VRRc0(s390_irgen_VSLB, ovl); + goto ok; + case 0xe70000000077ULL: s390_format_VRId(s390_irgen_VSLDB, ovl); + goto ok; + case 0xe70000000078ULL: s390_format_VRRc1(s390_irgen_VESRLV, ovl); + goto ok; + case 0xe7000000007aULL: s390_format_VRRc1(s390_irgen_VESRAV, ovl); + goto ok; + case 0xe7000000007cULL: s390_format_VRRc0(s390_irgen_VSRL, ovl); + goto ok; + case 0xe7000000007dULL: s390_format_VRRc0(s390_irgen_VSRLB, ovl); + goto ok; + case 0xe7000000007eULL: s390_format_VRRc0(s390_irgen_VSRA, ovl); + goto ok; + case 0xe7000000007fULL: s390_format_VRRc0(s390_irgen_VSRAB, ovl); + goto ok; + case 0xe70000000080ULL: s390_format_VRRb(s390_irgen_VFEE, ovl); + goto ok; + case 0xe70000000081ULL: s390_format_VRRb(s390_irgen_VFENE, ovl); + goto ok; + case 0xe70000000082ULL: s390_format_VRRb(s390_irgen_VFAE, ovl); + goto ok; + case 0xe70000000084ULL: s390_format_VRRc1(s390_irgen_VPDI, ovl); + goto ok; + case 0xe70000000085ULL: s390_format_VRRc0(s390_irgen_VBPERM, ovl); + goto ok; + case 0xe70000000086ULL: s390_format_VRId(s390_irgen_VSLD, ovl); + goto ok; + case 0xe70000000087ULL: s390_format_VRId(s390_irgen_VSRD, ovl); + goto ok; + case 0xe70000000088ULL: s390_format_VRIk(s390_irgen_VEVAL, ovl); + goto ok; + case 0xe70000000089ULL: s390_format_VRRd1(s390_irgen_VBLEND, ovl); + goto ok; + case 0xe7000000008aULL: s390_format_VRRd(s390_irgen_VSTRC, ovl); + goto ok; + case 0xe7000000008bULL: s390_format_VRRd(s390_irgen_VSTRS, ovl); + goto ok; + case 0xe7000000008cULL: s390_format_VRRe0(s390_irgen_VPERM, ovl); + goto ok; + case 0xe7000000008dULL: s390_format_VRRe0(s390_irgen_VSEL, ovl); + goto ok; + case 0xe7000000008eULL: s390_format_VRRe(s390_irgen_VFMS, ovl); + goto ok; + case 0xe7000000008fULL: s390_format_VRRe(s390_irgen_VFMA, ovl); + goto ok; + case 0xe70000000094ULL: s390_format_VRRc1(s390_irgen_VPK, ovl); + goto ok; + case 0xe70000000095ULL: s390_format_VRRb(s390_irgen_VPKLS, ovl); + goto ok; + case 0xe70000000097ULL: s390_format_VRRb(s390_irgen_VPKS, ovl); + goto ok; + case 0xe7000000009eULL: s390_format_VRRe(s390_irgen_VFNMS, ovl); + goto ok; + case 0xe7000000009fULL: s390_format_VRRe(s390_irgen_VFNMA, ovl); + goto ok; + case 0xe700000000a1ULL: s390_format_VRRc1(s390_irgen_VMLH, ovl); + goto ok; + case 0xe700000000a2ULL: s390_format_VRRc1(s390_irgen_VML, ovl); + goto ok; + case 0xe700000000a3ULL: s390_format_VRRc1(s390_irgen_VMH, ovl); + goto ok; + case 0xe700000000a4ULL: s390_format_VRRc1(s390_irgen_VMLE, ovl); + goto ok; + case 0xe700000000a5ULL: s390_format_VRRc1(s390_irgen_VMLO, ovl); + goto ok; + case 0xe700000000a6ULL: s390_format_VRRc1(s390_irgen_VME, ovl); + goto ok; + case 0xe700000000a7ULL: s390_format_VRRc1(s390_irgen_VMO, ovl); + goto ok; + case 0xe700000000a9ULL: s390_format_VRRd1(s390_irgen_VMALH, ovl); + goto ok; + case 0xe700000000aaULL: s390_format_VRRd1(s390_irgen_VMAL, ovl); + goto ok; + case 0xe700000000abULL: s390_format_VRRd1(s390_irgen_VMAH, ovl); + goto ok; + case 0xe700000000acULL: s390_format_VRRd1(s390_irgen_VMALE, ovl); + goto ok; + case 0xe700000000adULL: s390_format_VRRd1(s390_irgen_VMALO, ovl); + goto ok; + case 0xe700000000aeULL: s390_format_VRRd1(s390_irgen_VMAE, ovl); + goto ok; + case 0xe700000000afULL: s390_format_VRRd1(s390_irgen_VMAO, ovl); + goto ok; + case 0xe700000000b0ULL: s390_format_VRRc2(s390_irgen_VDL, ovl); + goto ok; + case 0xe700000000b1ULL: s390_format_VRRc2(s390_irgen_VRL, ovl); + goto ok; + case 0xe700000000b2ULL: s390_format_VRRc2(s390_irgen_VD, ovl); + goto ok; + case 0xe700000000b3ULL: s390_format_VRRc2(s390_irgen_VR, ovl); + goto ok; + case 0xe700000000b4ULL: s390_format_VRRc1(s390_irgen_VGFM, ovl); + goto ok; + case 0xe700000000b8ULL: s390_format_VRRd(s390_irgen_VMSL, ovl); + goto ok; + case 0xe700000000b9ULL: s390_format_VRRd1(s390_irgen_VACCC, ovl); + goto ok; + case 0xe700000000bbULL: s390_format_VRRd1(s390_irgen_VAC, ovl); + goto ok; + case 0xe700000000bcULL: s390_format_VRRd1(s390_irgen_VGFMA, ovl); + goto ok; + case 0xe700000000bdULL: s390_format_VRRd1(s390_irgen_VSBCBI, ovl); + goto ok; + case 0xe700000000bfULL: s390_format_VRRd1(s390_irgen_VSBI, ovl); + goto ok; + case 0xe700000000c0ULL: s390_format_VRRa(s390_irgen_VCLGD, ovl); + goto ok; + case 0xe700000000c1ULL: s390_format_VRRa(s390_irgen_VCDLG, ovl); + goto ok; + case 0xe700000000c2ULL: s390_format_VRRa(s390_irgen_VCGD, ovl); + goto ok; + case 0xe700000000c3ULL: s390_format_VRRa(s390_irgen_VCDG, ovl); + goto ok; + case 0xe700000000c4ULL: s390_format_VRRa2(s390_irgen_VFLL, ovl); + goto ok; + case 0xe700000000c5ULL: s390_format_VRRa(s390_irgen_VFLR, ovl); + goto ok; + case 0xe700000000c7ULL: s390_format_VRRa(s390_irgen_VFI, ovl); + goto ok; + case 0xe700000000caULL: s390_format_VRRa2(s390_irgen_WFK, ovl); + goto ok; + case 0xe700000000cbULL: s390_format_VRRa2(s390_irgen_WFC, ovl); + goto ok; + case 0xe700000000ccULL: s390_format_VRRa(s390_irgen_VFPSO, ovl); + goto ok; + case 0xe700000000ceULL: s390_format_VRRa2(s390_irgen_VFSQ, ovl); + goto ok; + case 0xe700000000d4ULL: s390_format_VRRa1(s390_irgen_VUPLL, ovl); + goto ok; + case 0xe700000000d5ULL: s390_format_VRRa1(s390_irgen_VUPLH, ovl); + goto ok; + case 0xe700000000d6ULL: s390_format_VRRa1(s390_irgen_VUPL, ovl); + goto ok; + case 0xe700000000d7ULL: s390_format_VRRa1(s390_irgen_VUPH, ovl); + goto ok; + case 0xe700000000d8ULL: s390_format_VRRa0(s390_irgen_VTM, ovl); + goto ok; + case 0xe700000000d9ULL: s390_format_VRRa1(s390_irgen_VECL, ovl); + goto ok; + case 0xe700000000dbULL: s390_format_VRRa1(s390_irgen_VEC, ovl); + goto ok; + case 0xe700000000deULL: s390_format_VRRa1(s390_irgen_VLC, ovl); + goto ok; + case 0xe700000000dfULL: s390_format_VRRa1(s390_irgen_VLP, ovl); + goto ok; + case 0xe700000000e2ULL: s390_format_VRRc2(s390_irgen_VFS, ovl); + goto ok; + case 0xe700000000e3ULL: s390_format_VRRc2(s390_irgen_VFA, ovl); + goto ok; + case 0xe700000000e5ULL: s390_format_VRRc2(s390_irgen_VFD, ovl); + goto ok; + case 0xe700000000e7ULL: s390_format_VRRc2(s390_irgen_VFM, ovl); + goto ok; + case 0xe700000000e8ULL: s390_format_VRRc(s390_irgen_VFCE, ovl); + goto ok; + case 0xe700000000eaULL: s390_format_VRRc(s390_irgen_VFCHE, ovl); + goto ok; + case 0xe700000000ebULL: s390_format_VRRc(s390_irgen_VFCH, ovl); + goto ok; + case 0xe700000000eeULL: s390_format_VRRc(s390_irgen_VFMIN, ovl); + goto ok; + case 0xe700000000efULL: s390_format_VRRc(s390_irgen_VFMAX, ovl); + goto ok; + case 0xe700000000f0ULL: s390_format_VRRc1(s390_irgen_VAVGL, ovl); + goto ok; + case 0xe700000000f1ULL: s390_format_VRRc1(s390_irgen_VACC, ovl); + goto ok; + case 0xe700000000f2ULL: s390_format_VRRc1(s390_irgen_VAVG, ovl); + goto ok; + case 0xe700000000f3ULL: s390_format_VRRc1(s390_irgen_VA, ovl); + goto ok; + case 0xe700000000f5ULL: s390_format_VRRc1(s390_irgen_VSCBI, ovl); + goto ok; + case 0xe700000000f7ULL: s390_format_VRRc1(s390_irgen_VS, ovl); + goto ok; + case 0xe700000000f8ULL: s390_format_VRRb(s390_irgen_VCEQ, ovl); + goto ok; + case 0xe700000000f9ULL: s390_format_VRRb(s390_irgen_VCHL, ovl); + goto ok; + case 0xe700000000fbULL: s390_format_VRRb(s390_irgen_VCH, ovl); + goto ok; + case 0xe700000000fcULL: s390_format_VRRc1(s390_irgen_VMNL, ovl); + goto ok; + case 0xe700000000fdULL: s390_format_VRRc1(s390_irgen_VMXL, ovl); + goto ok; + case 0xe700000000feULL: s390_format_VRRc1(s390_irgen_VMN, ovl); + goto ok; + case 0xe700000000ffULL: s390_format_VRRc1(s390_irgen_VMX, ovl); + goto ok; + case 0xeb0000000004ULL: s390_format_RSY(s390_irgen_LMG, ovl); + goto ok; + case 0xeb000000000aULL: s390_format_RSY(s390_irgen_SRAG, ovl); + goto ok; + case 0xeb000000000bULL: s390_format_RSY(s390_irgen_SLAG, ovl); + goto ok; + case 0xeb000000000cULL: s390_format_RSY(s390_irgen_SRLG, ovl); + goto ok; + case 0xeb000000000dULL: s390_format_RSY(s390_irgen_SLLG, ovl); + goto ok; case 0xeb000000000fULL: /* TRACG */ goto unimplemented; - case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xeb0000000014ULL: s390_format_RSY(s390_irgen_CSY, ovl); + goto ok; case 0xeb0000000016ULL: /* PFCR */ goto unimplemented; - case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000023ULL: s390_format_RSY_R0RD(s390_irgen_CLT, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xeb000000001cULL: s390_format_RSY(s390_irgen_RLLG, ovl); + goto ok; + case 0xeb000000001dULL: s390_format_RSY(s390_irgen_RLL, ovl); + goto ok; + case 0xeb0000000020ULL: s390_format_RSY(s390_irgen_CLMH, ovl); + goto ok; + case 0xeb0000000021ULL: s390_format_RSY(s390_irgen_CLMY, ovl); + goto ok; + case 0xeb0000000023ULL: s390_format_RSY(s390_irgen_CLT, ovl); + goto ok; + case 0xeb0000000024ULL: s390_format_RSY(s390_irgen_STMG, ovl); + goto ok; case 0xeb0000000025ULL: /* STCTG */ goto unimplemented; - case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000002bULL: s390_format_RSY_R0RD(s390_irgen_CLGT, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xeb0000000026ULL: s390_format_RSY(s390_irgen_STMH, ovl); + goto ok; + case 0xeb000000002bULL: s390_format_RSY(s390_irgen_CLGT, ovl); + goto ok; + case 0xeb000000002cULL: s390_format_RSY(s390_irgen_STCMH, ovl); + goto ok; + case 0xeb000000002dULL: s390_format_RSY(s390_irgen_STCMY, ovl); + goto ok; case 0xeb000000002fULL: /* LCTLG */ goto unimplemented; - case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; + case 0xeb0000000030ULL: s390_format_RSY(s390_irgen_CSG, ovl); + goto ok; + case 0xeb0000000031ULL: s390_format_RSY(s390_irgen_CDSY, ovl); + goto ok; + case 0xeb000000003eULL: s390_format_RSY(s390_irgen_CDSG, ovl); + goto ok; + case 0xeb0000000044ULL: s390_format_RSY(s390_irgen_BXHG, ovl); + goto ok; + case 0xeb0000000045ULL: s390_format_RSY(s390_irgen_BXLEG, ovl); + goto ok; + case 0xeb000000004cULL: s390_format_RSY(s390_irgen_ECAG, ovl); + goto ok; + case 0xeb0000000051ULL: s390_format_SIY(s390_irgen_TMY, ovl); + goto ok; + case 0xeb0000000052ULL: s390_format_SIY(s390_irgen_MVIY, ovl); + goto ok; + case 0xeb0000000054ULL: s390_format_SIY(s390_irgen_NIY, ovl); + goto ok; + case 0xeb0000000055ULL: s390_format_SIY(s390_irgen_CLIY, ovl); + goto ok; + case 0xeb0000000056ULL: s390_format_SIY(s390_irgen_OIY, ovl); + goto ok; + case 0xeb0000000057ULL: s390_format_SIY(s390_irgen_XIY, ovl); + goto ok; + case 0xeb000000006aULL: s390_format_SIY(s390_irgen_ASI, ovl); + goto ok; + case 0xeb000000006eULL: s390_format_SIY(s390_irgen_ALSI, ovl); + goto ok; case 0xeb0000000071ULL: /* LPSWEY */ goto unimplemented; - case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, SIY_i2(ovl), - SIY_b1(ovl), SIY_dl1(ovl), - SIY_dh1(ovl)); goto ok; - case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xeb000000007aULL: s390_format_SIY(s390_irgen_AGSI, ovl); + goto ok; + case 0xeb000000007eULL: s390_format_SIY(s390_irgen_ALGSI, ovl); + goto ok; + case 0xeb0000000080ULL: s390_format_RSY(s390_irgen_ICMH, ovl); + goto ok; + case 0xeb0000000081ULL: s390_format_RSY(s390_irgen_ICMY, ovl); + goto ok; case 0xeb000000008eULL: /* MVCLU */ goto unimplemented; case 0xeb000000008fULL: /* CLCLU */ goto unimplemented; - case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; + case 0xeb0000000090ULL: s390_format_RSY(s390_irgen_STMY, ovl); + goto ok; + case 0xeb0000000096ULL: s390_format_RSY(s390_irgen_LMH, ovl); + goto ok; + case 0xeb0000000098ULL: s390_format_RSY(s390_irgen_LMY, ovl); + goto ok; + case 0xeb000000009aULL: s390_format_RSY(s390_irgen_LAMY, ovl); + goto ok; + case 0xeb000000009bULL: s390_format_RSY(s390_irgen_STAMY, ovl); + goto ok; case 0xeb00000000c0ULL: /* TP */ goto unimplemented; - case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e0ULL: s390_format_RSY_RDRM(s390_irgen_LOCFH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e1ULL: s390_format_RSY_RDRM(s390_irgen_STOCFH, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG, - RSY_r1(ovl), RSY_r3(ovl), - RSY_b2(ovl), RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, RSY_r1(ovl), - RSY_r3(ovl), RSY_b2(ovl), - RSY_dl2(ovl), - RSY_dh2(ovl)); goto ok; - case 0xec0000000042ULL: s390_format_RIE_RUPIX(s390_irgen_LOCHI, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl)); goto ok; - case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, RIE_r1(ovl), - RIE_r3(ovl), RIE_i2(ovl)); - goto ok; - case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, RIE_r1(ovl), - RIE_r3(ovl), RIE_i2(ovl)); - goto ok; - case 0xec0000000046ULL: s390_format_RIE_RUPIX(s390_irgen_LOCGHI, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl)); goto ok; - case 0xec000000004eULL: s390_format_RIE_RUPIX(s390_irgen_LOCHHI, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl)); goto ok; - case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG, - RIE_RRUUU_r1(ovl), - RIE_RRUUU_r2(ovl), - RIE_RRUUU_i3(ovl), - RIE_RRUUU_i4(ovl), - RIE_RRUUU_i5(ovl)); - goto ok; - case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ, - RIE_RRPU_r1(ovl), - RIE_RRPU_r2(ovl), - RIE_RRPU_i4(ovl), - RIE_RRPU_m3(ovl)); goto ok; - case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ, - RIE_RRPU_r1(ovl), - RIE_RRPU_r2(ovl), - RIE_RRPU_i4(ovl), - RIE_RRPU_m3(ovl)); goto ok; - case 0xec0000000070ULL: s390_format_R0IU(s390_irgen_CGIT, - RIE_R0xU_r1(ovl), - RIE_R0xU_i2(ovl), - RIE_R0xU_m3(ovl)); goto ok; - case 0xec0000000071ULL: s390_format_R0UU(s390_irgen_CLGIT, - RIE_R0xU_r1(ovl), - RIE_R0xU_i2(ovl), - RIE_R0xU_m3(ovl)); goto ok; - case 0xec0000000072ULL: s390_format_R0IU(s390_irgen_CIT, - RIE_R0xU_r1(ovl), - RIE_R0xU_i2(ovl), - RIE_R0xU_m3(ovl)); goto ok; - case 0xec0000000073ULL: s390_format_R0UU(s390_irgen_CLFIT, - RIE_R0xU_r1(ovl), - RIE_R0xU_i2(ovl), - RIE_R0xU_m3(ovl)); goto ok; - case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ, - RIE_RRPU_r1(ovl), - RIE_RRPU_r2(ovl), - RIE_RRPU_i4(ovl), - RIE_RRPU_m3(ovl)); goto ok; - case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ, - RIE_RRPU_r1(ovl), - RIE_RRPU_r2(ovl), - RIE_RRPU_i4(ovl), - RIE_RRPU_m3(ovl)); goto ok; - case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl), - RIEv3_i2(ovl)); goto ok; - case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl), - RIEv3_i2(ovl)); goto ok; - case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl), - RIEv3_i2(ovl)); goto ok; - case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ, - RIEv3_r1(ovl), - RIEv3_m3(ovl), - RIEv3_i4(ovl), - RIEv3_i2(ovl)); goto ok; - case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, RIE_r1(ovl), - RIE_r3(ovl), RIE_i2(ovl)); - goto ok; - case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK, - RIE_r1(ovl), RIE_r3(ovl), - RIE_i2(ovl)); goto ok; - case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK, - RIE_r1(ovl), RIE_r3(ovl), - RIE_i2(ovl)); goto ok; - case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK, - RIE_r1(ovl), RIE_r3(ovl), - RIE_i2(ovl)); goto ok; - case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, RRS_r1(ovl), - RRS_r2(ovl), RRS_b4(ovl), - RRS_d4(ovl), RRS_m3(ovl)); - goto ok; - case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, RRS_r1(ovl), - RRS_r2(ovl), RRS_b4(ovl), - RRS_d4(ovl), RRS_m3(ovl)); - goto ok; - case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, RRS_r1(ovl), - RRS_r2(ovl), RRS_b4(ovl), - RRS_d4(ovl), RRS_m3(ovl)); - goto ok; - case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, RRS_r1(ovl), - RRS_r2(ovl), RRS_b4(ovl), - RRS_d4(ovl), RRS_m3(ovl)); - goto ok; - case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB, - RIS_r1(ovl), RIS_m3(ovl), - RIS_b4(ovl), RIS_d4(ovl), - RIS_i2(ovl)); goto ok; - case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB, - RIS_r1(ovl), RIS_m3(ovl), - RIS_b4(ovl), RIS_d4(ovl), - RIS_i2(ovl)); goto ok; - case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, RIS_r1(ovl), - RIS_m3(ovl), RIS_b4(ovl), - RIS_d4(ovl), - RIS_i2(ovl)); goto ok; - case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB, - RIS_r1(ovl), RIS_m3(ovl), - RIS_b4(ovl), RIS_d4(ovl), - RIS_i2(ovl)); goto ok; - case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; + case 0xeb00000000dcULL: s390_format_RSY(s390_irgen_SRAK, ovl); + goto ok; + case 0xeb00000000ddULL: s390_format_RSY(s390_irgen_SLAK, ovl); + goto ok; + case 0xeb00000000deULL: s390_format_RSY(s390_irgen_SRLK, ovl); + goto ok; + case 0xeb00000000dfULL: s390_format_RSY(s390_irgen_SLLK, ovl); + goto ok; + case 0xeb00000000e0ULL: s390_format_RSYcond(s390_irgen_LOCFH, ovl); + goto ok; + case 0xeb00000000e1ULL: s390_format_RSYcond(s390_irgen_STOCFH, ovl); + goto ok; + case 0xeb00000000e2ULL: s390_format_RSYcond(s390_irgen_LOCG, ovl); + goto ok; + case 0xeb00000000e3ULL: s390_format_RSYcond(s390_irgen_STOCG, ovl); + goto ok; + case 0xeb00000000e4ULL: s390_format_RSY(s390_irgen_LANG, ovl); + goto ok; + case 0xeb00000000e6ULL: s390_format_RSY(s390_irgen_LAOG, ovl); + goto ok; + case 0xeb00000000e7ULL: s390_format_RSY(s390_irgen_LAXG, ovl); + goto ok; + case 0xeb00000000e8ULL: s390_format_RSY(s390_irgen_LAAG, ovl); + goto ok; + case 0xeb00000000eaULL: s390_format_RSY(s390_irgen_LAALG, ovl); + goto ok; + case 0xeb00000000f2ULL: s390_format_RSYcond(s390_irgen_LOC, ovl); + goto ok; + case 0xeb00000000f3ULL: s390_format_RSYcond(s390_irgen_STOC, ovl); + goto ok; + case 0xeb00000000f4ULL: s390_format_RSY(s390_irgen_LAN, ovl); + goto ok; + case 0xeb00000000f6ULL: s390_format_RSY(s390_irgen_LAO, ovl); + goto ok; + case 0xeb00000000f7ULL: s390_format_RSY(s390_irgen_LAX, ovl); + goto ok; + case 0xeb00000000f8ULL: s390_format_RSY(s390_irgen_LAA, ovl); + goto ok; + case 0xeb00000000faULL: s390_format_RSY(s390_irgen_LAAL, ovl); + goto ok; + case 0xec0000000042ULL: s390_irgen_LOCHI(RIEg_r1(ovl), RIEg_m3(ovl), + RIEg_i2(ovl)); + goto ok; + case 0xec0000000044ULL: s390_irgen_BRXHG(RIEe_r1(ovl), RIEe_r3(ovl), + RIEe_i2(ovl)); + goto ok; + case 0xec0000000045ULL: s390_irgen_BRXLG(RIEe_r1(ovl), RIEe_r3(ovl), + RIEe_i2(ovl)); + goto ok; + case 0xec0000000046ULL: s390_irgen_LOCGHI(RIEg_r1(ovl), RIEg_m3(ovl), + RIEg_i2(ovl)); + goto ok; + case 0xec000000004eULL: s390_irgen_LOCHHI(RIEg_r1(ovl), RIEg_m3(ovl), + RIEg_i2(ovl)); + goto ok; + case 0xec0000000051ULL: s390_irgen_RISBLG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000054ULL: s390_irgen_RNSBG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000055ULL: s390_irgen_RISBG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000056ULL: s390_irgen_ROSBG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000057ULL: s390_irgen_RXSBG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000059ULL: s390_irgen_RISBGN(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec000000005dULL: s390_irgen_RISBHG(RIEf_r1(ovl), RIEf_r2(ovl), + RIEf_i3(ovl), RIEf_i4(ovl), + RIEf_i5(ovl)); + goto ok; + case 0xec0000000064ULL: s390_irgen_CGRJ(RIEb_r1(ovl), RIEb_r2(ovl), + RIEb_i4(ovl), RIEb_m3(ovl)); + goto ok; + case 0xec0000000065ULL: s390_irgen_CLGRJ(RIEb_r1(ovl), RIEb_r2(ovl), + RIEb_i4(ovl), RIEb_m3(ovl)); + goto ok; + case 0xec0000000070ULL: s390_irgen_CGIT(RIEa_r1(ovl), RIEa_i2(ovl), + RIEa_m3(ovl)); + goto ok; + case 0xec0000000071ULL: s390_irgen_CLGIT(RIEa_r1(ovl), RIEa_i2(ovl), + RIEa_m3(ovl)); + goto ok; + case 0xec0000000072ULL: s390_irgen_CIT(RIEa_r1(ovl), RIEa_i2(ovl), + RIEa_m3(ovl)); + goto ok; + case 0xec0000000073ULL: s390_irgen_CLFIT(RIEa_r1(ovl), RIEa_i2(ovl), + RIEa_m3(ovl)); + goto ok; + case 0xec0000000076ULL: s390_irgen_CRJ(RIEb_r1(ovl), RIEb_r2(ovl), + RIEb_i4(ovl), RIEb_m3(ovl)); + goto ok; + case 0xec0000000077ULL: s390_irgen_CLRJ(RIEb_r1(ovl), RIEb_r2(ovl), + RIEb_i4(ovl), RIEb_m3(ovl)); + goto ok; + case 0xec000000007cULL: s390_irgen_CGIJ(RIEc_r1(ovl), RIEc_m3(ovl), + RIEc_i4(ovl), RIEc_i2(ovl)); + goto ok; + case 0xec000000007dULL: s390_irgen_CLGIJ(RIEc_r1(ovl), RIEc_m3(ovl), + RIEc_i4(ovl), RIEc_i2(ovl)); + goto ok; + case 0xec000000007eULL: s390_irgen_CIJ(RIEc_r1(ovl), RIEc_m3(ovl), + RIEc_i4(ovl), RIEc_i2(ovl)); + goto ok; + case 0xec000000007fULL: s390_irgen_CLIJ(RIEc_r1(ovl), RIEc_m3(ovl), + RIEc_i4(ovl), RIEc_i2(ovl)); + goto ok; + case 0xec00000000d8ULL: s390_irgen_AHIK(RIEd_r1(ovl), RIEd_r3(ovl), + RIEd_i2(ovl)); + goto ok; + case 0xec00000000d9ULL: s390_irgen_AGHIK(RIEd_r1(ovl), RIEd_r3(ovl), + RIEd_i2(ovl)); + goto ok; + case 0xec00000000daULL: s390_irgen_ALHSIK(RIEd_r1(ovl), RIEd_r3(ovl), + RIEd_i2(ovl)); + goto ok; + case 0xec00000000dbULL: s390_irgen_ALGHSIK(RIEd_r1(ovl), RIEd_r3(ovl), + RIEd_i2(ovl)); + goto ok; + case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl); + goto ok; + case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl); + goto ok; + case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl); + goto ok; + case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl); + goto ok; + case 0xec00000000fcULL: s390_format_RIS(s390_irgen_CGIB, ovl); + goto ok; + case 0xec00000000fdULL: s390_format_RIS(s390_irgen_CLGIB, ovl); + goto ok; + case 0xec00000000feULL: s390_format_RIS(s390_irgen_CIB, ovl); + goto ok; + case 0xec00000000ffULL: s390_format_RIS(s390_irgen_CLIB, ovl); + goto ok; + case 0xed0000000004ULL: s390_format_RXE0(s390_irgen_LDEB, ovl); + goto ok; + case 0xed0000000005ULL: s390_format_RXE0(s390_irgen_LXDB, ovl); + goto ok; + case 0xed0000000006ULL: s390_format_RXE0(s390_irgen_LXEB, ovl); + goto ok; case 0xed0000000007ULL: /* MXDB */ goto unimplemented; - case 0xed0000000008ULL: s390_format_RXE_FRRD(s390_irgen_KEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; + case 0xed0000000008ULL: s390_format_RXE0(s390_irgen_KEB, ovl); + goto ok; + case 0xed0000000009ULL: s390_format_RXE0(s390_irgen_CEB, ovl); + goto ok; + case 0xed000000000aULL: s390_format_RXE0(s390_irgen_AEB, ovl); + goto ok; + case 0xed000000000bULL: s390_format_RXE0(s390_irgen_SEB, ovl); + goto ok; case 0xed000000000cULL: /* MDEB */ goto unimplemented; - case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000018ULL: s390_format_RXE_FRRD(s390_irgen_KDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE, - RXE_r1(ovl), RXE_x2(ovl), - RXE_b2(ovl), - RXE_d2(ovl)); goto ok; + case 0xed000000000dULL: s390_format_RXE0(s390_irgen_DEB, ovl); + goto ok; + case 0xed000000000eULL: s390_format_RXF(s390_irgen_MAEB, ovl); + goto ok; + case 0xed000000000fULL: s390_format_RXF(s390_irgen_MSEB, ovl); + goto ok; + case 0xed0000000010ULL: s390_format_RXE0(s390_irgen_TCEB, ovl); + goto ok; + case 0xed0000000011ULL: s390_format_RXE0(s390_irgen_TCDB, ovl); + goto ok; + case 0xed0000000012ULL: s390_format_RXE0(s390_irgen_TCXB, ovl); + goto ok; + case 0xed0000000014ULL: s390_format_RXE0(s390_irgen_SQEB, ovl); + goto ok; + case 0xed0000000015ULL: s390_format_RXE0(s390_irgen_SQDB, ovl); + goto ok; + case 0xed0000000017ULL: s390_format_RXE0(s390_irgen_MEEB, ovl); + goto ok; + case 0xed0000000018ULL: s390_format_RXE0(s390_irgen_KDB, ovl); + goto ok; + case 0xed0000000019ULL: s390_format_RXE0(s390_irgen_CDB, ovl); + goto ok; + case 0xed000000001aULL: s390_format_RXE0(s390_irgen_ADB, ovl); + goto ok; + case 0xed000000001bULL: s390_format_RXE0(s390_irgen_SDB, ovl); + goto ok; + case 0xed000000001cULL: s390_format_RXE0(s390_irgen_MDB, ovl); + goto ok; + case 0xed000000001dULL: s390_format_RXE0(s390_irgen_DDB, ovl); + goto ok; + case 0xed000000001eULL: s390_format_RXF(s390_irgen_MADB, ovl); + goto ok; + case 0xed000000001fULL: s390_format_RXF(s390_irgen_MSDB, ovl); + goto ok; + case 0xed0000000024ULL: s390_format_RXE0(s390_irgen_LDE, ovl); + goto ok; case 0xed0000000025ULL: /* LXD */ goto unimplemented; case 0xed0000000026ULL: /* LXE */ goto unimplemented; case 0xed000000002eULL: /* MAE */ goto unimplemented; @@ -23540,56 +20321,34 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xed000000003dULL: /* MYH */ goto unimplemented; case 0xed000000003eULL: /* MAD */ goto unimplemented; case 0xed000000003fULL: /* MSD */ goto unimplemented; - case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT, - RXF_r3(ovl), RXF_x2(ovl), - RXF_b2(ovl), RXF_d2(ovl), - RXF_r1(ovl)); goto ok; - case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, RXE_r1(ovl), - RXE_x2(ovl), RXE_b2(ovl), - RXE_d2(ovl)); goto ok; - case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, RXY_r1(ovl), - RXY_x2(ovl), RXY_b2(ovl), - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; + case 0xed0000000040ULL: s390_format_RXF(s390_irgen_SLDT, ovl); + goto ok; + case 0xed0000000041ULL: s390_format_RXF(s390_irgen_SRDT, ovl); + goto ok; + case 0xed0000000048ULL: s390_format_RXF(s390_irgen_SLXT, ovl); + goto ok; + case 0xed0000000049ULL: s390_format_RXF(s390_irgen_SRXT, ovl); + goto ok; + case 0xed0000000050ULL: s390_format_RXE0(s390_irgen_TDCET, ovl); + goto ok; + case 0xed0000000051ULL: s390_format_RXE0(s390_irgen_TDGET, ovl); + goto ok; + case 0xed0000000054ULL: s390_format_RXE0(s390_irgen_TDCDT, ovl); + goto ok; + case 0xed0000000055ULL: s390_format_RXE0(s390_irgen_TDGDT, ovl); + goto ok; + case 0xed0000000058ULL: s390_format_RXE0(s390_irgen_TDCXT, ovl); + goto ok; + case 0xed0000000059ULL: s390_format_RXE0(s390_irgen_TDGXT, ovl); + goto ok; + case 0xed0000000064ULL: s390_format_RXY(s390_irgen_LEY, ovl); + goto ok; + case 0xed0000000065ULL: s390_format_RXY(s390_irgen_LDY, ovl); + goto ok; + case 0xed0000000066ULL: s390_format_RXY(s390_irgen_STEY, ovl); + goto ok; + case 0xed0000000067ULL: s390_format_RXY(s390_irgen_STDY, ovl); + goto ok; case 0xed00000000a8ULL: /* CZDT */ goto unimplemented; case 0xed00000000a9ULL: /* CZXT */ goto unimplemented; case 0xed00000000aaULL: /* CDZT */ goto unimplemented; @@ -23601,104 +20360,104 @@ s390_decode_6byte_and_irgen(const UChar *bytes) } switch (((ovl >> 16) & 0xff0f00000000ULL) >> 32) { - case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; + case 0xc000ULL: s390_irgen_LARL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc001ULL: s390_irgen_LGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc004ULL: s390_irgen_BRCL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc005ULL: s390_irgen_BRASL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc006ULL: s390_irgen_XIHF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc007ULL: s390_irgen_XILF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc008ULL: s390_irgen_IIHF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc009ULL: s390_irgen_IILF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00aULL: s390_irgen_NIHF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00bULL: s390_irgen_NILF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00cULL: s390_irgen_OIHF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00dULL: s390_irgen_OILF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00eULL: s390_irgen_LLIHF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc00fULL: s390_irgen_LLILF(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc200ULL: s390_irgen_MSGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc201ULL: s390_irgen_MSFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc204ULL: s390_irgen_SLGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc205ULL: s390_irgen_SLFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc208ULL: s390_irgen_AGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc209ULL: s390_irgen_AFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20aULL: s390_irgen_ALGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20bULL: s390_irgen_ALFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20cULL: s390_irgen_CGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20dULL: s390_irgen_CFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20eULL: s390_irgen_CLGFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc20fULL: s390_irgen_CLFI(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc402ULL: s390_irgen_LLHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc404ULL: s390_irgen_LGHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc405ULL: s390_irgen_LHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc406ULL: s390_irgen_LLGHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc407ULL: s390_irgen_STHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc408ULL: s390_irgen_LGRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc40bULL: s390_irgen_STGRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc40cULL: s390_irgen_LGFRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc40dULL: s390_irgen_LRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc40eULL: s390_irgen_LLGFRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc40fULL: s390_irgen_STRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc600ULL: s390_irgen_EXRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc602ULL: s390_irgen_PFDRL(); + goto ok; + case 0xc604ULL: s390_irgen_CGHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc605ULL: s390_irgen_CHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc606ULL: s390_irgen_CLGHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc607ULL: s390_irgen_CLHRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc608ULL: s390_irgen_CGRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc60aULL: s390_irgen_CLGRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc60cULL: s390_irgen_CGFRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc60dULL: s390_irgen_CRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc60eULL: s390_irgen_CLGFRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xc60fULL: s390_irgen_CLRL(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; case 0xc800ULL: /* MVCOS */ goto unimplemented; case 0xc801ULL: /* ECTG */ goto unimplemented; case 0xc802ULL: /* CSST */ goto unimplemented; @@ -23707,62 +20466,54 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xc806ULL: /* CAL */ goto unimplemented; case 0xc807ULL: /* CALG */ goto unimplemented; case 0xc80fULL: /* CALGF */ goto unimplemented; - case 0xcc06ULL: s390_format_RIL_RP(s390_irgen_BRCTH, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; - case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, RIL_r1(ovl), - RIL_i2(ovl)); goto ok; + case 0xcc06ULL: s390_irgen_BRCTH(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xcc08ULL: s390_irgen_AIH(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xcc0aULL: s390_irgen_ALSIH(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xcc0bULL: s390_irgen_ALSIHN(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xcc0dULL: s390_irgen_CIH(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; + case 0xcc0fULL: s390_irgen_CLIH(RIL_r1(ovl), RIL_i2(ovl)); + goto ok; } switch (((ovl >> 16) & 0xff0000000000ULL) >> 40) { - case 0xc5ULL: s390_format_MII_UPP(s390_irgen_BPRP, MII_m1(ovl), MII_i2(ovl), - MII_i3(ovl)); goto ok; - case 0xc7ULL: s390_format_SMI_U0RDP(s390_irgen_BPP, SMI_m1(ovl), SMI_i2(ovl), - SMI_b3(ovl), SMI_d3(ovl)); goto ok; + case 0xc5ULL: s390_irgen_BPRP(MII_m1(ovl), MII_i2(ovl), MII_i3(ovl)); + goto ok; + case 0xc7ULL: s390_format_SMI(s390_irgen_BPP, ovl); + goto ok; case 0xd0ULL: /* TRTR */ goto unimplemented; case 0xd1ULL: /* MVN */ goto unimplemented; - case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; + case 0xd2ULL: s390_format_SSa(s390_irgen_MVC, ovl); + goto ok; case 0xd3ULL: /* MVZ */ goto unimplemented; - case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; - case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; - case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; + case 0xd4ULL: s390_format_SSa(s390_irgen_NC, ovl); + goto ok; + case 0xd5ULL: s390_format_SSa(s390_irgen_CLC, ovl); + goto ok; + case 0xd6ULL: s390_format_SSa(s390_irgen_OC, ovl); + goto ok; case 0xd7ULL: - if (SS_b1(ovl) == SS_b2(ovl) && SS_d1(ovl) == SS_d2(ovl)) - s390_irgen_XC_sameloc(SS_l(ovl), SS_b1(ovl), SS_d1(ovl)); + if (SSa_b1(ovl) == SSa_b2(ovl) && SSa_d1(ovl) == SSa_d2(ovl)) + s390_irgen_XC_sameloc(SSa_l(ovl), SSa_b1(ovl), SSa_d1(ovl)); else - s390_format_SS_L0RDRD(s390_irgen_XC, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); + s390_format_SSa(s390_irgen_XC, ovl); goto ok; case 0xd9ULL: /* MVCK */ goto unimplemented; case 0xdaULL: /* MVCP */ goto unimplemented; case 0xdbULL: /* MVCS */ goto unimplemented; - case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; + case 0xdcULL: s390_format_SSa(s390_irgen_TR, ovl); + goto ok; case 0xddULL: /* TRT */ goto unimplemented; case 0xdeULL: /* ED */ goto unimplemented; case 0xdfULL: /* EDMK */ goto unimplemented; case 0xe1ULL: /* PKU */ goto unimplemented; case 0xe2ULL: /* UNPKU */ goto unimplemented; - case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, SS_l(ovl), - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; + case 0xe8ULL: s390_format_SSa(s390_irgen_MVCIN, ovl); + goto ok; case 0xe9ULL: /* PKA */ goto unimplemented; case 0xeaULL: /* UNPKA */ goto unimplemented; case 0xeeULL: /* PLO */ goto unimplemented; @@ -23783,38 +20534,28 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe500ULL: /* LASP */ goto unimplemented; case 0xe501ULL: /* TPROT */ goto unimplemented; case 0xe502ULL: /* STRAG */ goto unimplemented; - case 0xe50aULL: s390_format_SSE_RDRD(s390_irgen_MVCRL, - SS_b1(ovl), SS_d1(ovl), - SS_b2(ovl), SS_d2(ovl)); goto ok; + case 0xe50aULL: s390_format_SSE(s390_irgen_MVCRL, ovl); + goto ok; case 0xe50eULL: /* MVCSK */ goto unimplemented; case 0xe50fULL: /* MVCDK */ goto unimplemented; - case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; - case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, SIL_b1(ovl), - SIL_d1(ovl), SIL_i2(ovl)); - goto ok; + case 0xe544ULL: s390_format_SIL(s390_irgen_MVHHI, ovl); + goto ok; + case 0xe548ULL: s390_format_SIL(s390_irgen_MVGHI, ovl); + goto ok; + case 0xe54cULL: s390_format_SIL(s390_irgen_MVHI, ovl); + goto ok; + case 0xe554ULL: s390_format_SIL(s390_irgen_CHHSI, ovl); + goto ok; + case 0xe555ULL: s390_format_SIL(s390_irgen_CLHHSI, ovl); + goto ok; + case 0xe558ULL: s390_format_SIL(s390_irgen_CGHSI, ovl); + goto ok; + case 0xe559ULL: s390_format_SIL(s390_irgen_CLGHSI, ovl); + goto ok; + case 0xe55cULL: s390_format_SIL(s390_irgen_CHSI, ovl); + goto ok; + case 0xe55dULL: s390_format_SIL(s390_irgen_CLFHSI, ovl); + goto ok; case 0xe560ULL: /* TBEGIN */ goto unimplemented; case 0xe561ULL: /* TBEGINC */ goto unimplemented; } @@ -23880,6 +20621,11 @@ s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres) s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE); } else { /* Handle normal instructions. */ + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { + HChar *str = s390_disasm(bytes, /* padmnm */ 1); + vex_printf("%s\n", str ? str : "disassembly failed"); + } + switch (insn_length) { case 2: status = s390_decode_2byte_and_irgen(bytes); @@ -23948,6 +20694,11 @@ s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres) vex_printf(" "); vex_printf("%02x%02x", bytes[i], bytes[i + 1]); } + if (status == S390_DECODE_UNIMPLEMENTED_INSN || + status == S390_DECODE_SPECIFICATION_EXCEPTION) { + const HChar *str = s390_disasm(bytes, /* padmnm */ 0); + vex_printf(" %s", str == NULL ? "??????" : str); + } vex_printf("\n"); } @@ -24036,9 +20787,9 @@ disInstr_S390(IRSB *irsb_IN, Addr guest_IP, VexArch guest_arch, const VexArchInfo *archinfo, - const VexAbiInfo *abiinfo, - VexEndness host_endness, - Bool sigill_diag_IN) + const VexAbiInfo* abiinfo, + VexEndness host_endness, + Bool sigill_diag_IN) { vassert(guest_arch == VexArchS390X); @@ -24046,7 +20797,7 @@ disInstr_S390(IRSB *irsb_IN, guest_IA_curr_instr = guest_IP; if (last_execute_target == Invalid_execute_target) guest_IA_rel_base = guest_IA_curr_instr; - irsb = irsb_IN; + irsb = irsb_IN; sigill_diag = sigill_diag_IN; return disInstr_S390_WRK(guest_code + delta); diff --git a/VEX/priv/guest_x86_helpers.c b/VEX/priv/guest_x86_helpers.c index 90722d7673..b511490837 100644 --- a/VEX/priv/guest_x86_helpers.c +++ b/VEX/priv/guest_x86_helpers.c @@ -42,6 +42,7 @@ #include "guest_generic_bb_to_IR.h" #include "guest_x86_defs.h" #include "guest_generic_x87.h" +#include "guest_generic_helpers.h" /* This file contains helper functions for x86 guest code. @@ -2651,10 +2652,6 @@ void x86g_dirtyhelper_SxDT ( void *address, UInt op ) { /*--- Helpers for MMX/SSE/SSE2. ---*/ /*---------------------------------------------------------------*/ -static inline UChar abdU8 ( UChar xx, UChar yy ) { - return toUChar(xx>yy ? xx-yy : yy-xx); -} - static inline ULong mk32x2 ( UInt w1, UInt w0 ) { return (((ULong)w1) << 32) | ((ULong)w0); } @@ -2676,39 +2673,6 @@ static inline UShort sel16x4_0 ( ULong w64 ) { return toUShort(lo32); } -static inline UChar sel8x8_7 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 24); -} -static inline UChar sel8x8_6 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 16); -} -static inline UChar sel8x8_5 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 8); -} -static inline UChar sel8x8_4 ( ULong w64 ) { - UInt hi32 = toUInt(w64 >> 32); - return toUChar(hi32 >> 0); -} -static inline UChar sel8x8_3 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 24); -} -static inline UChar sel8x8_2 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 16); -} -static inline UChar sel8x8_1 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 8); -} -static inline UChar sel8x8_0 ( ULong w64 ) { - UInt lo32 = toUInt(w64); - return toUChar(lo32 >> 0); -} - /* CALLED FROM GENERATED CODE: CLEAN HELPER */ ULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) { @@ -2912,12 +2876,6 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state ) vex_state->guest_NRADDR = 0; vex_state->guest_SC_CLASS = 0; - vex_state->guest_IP_AT_SYSCALL = 0; - - vex_state->guest_SETC = 0; - - vex_state->padding1 = 0; - vex_state->padding2 = 0; } @@ -2990,7 +2948,7 @@ VexGuestLayout /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ - .n_alwaysDefd = 24, + .n_alwaysDefd = 23, /* flags thunk: OP and NDEP are always defd, whereas DEP1 and DEP2 have to be tracked. See detailed comment in @@ -3018,8 +2976,7 @@ VexGuestLayout /* 19 */ ALWAYSDEFD(guest_SSEROUND), /* 20 */ ALWAYSDEFD(guest_CMSTART), /* 21 */ ALWAYSDEFD(guest_CMLEN), - /* 22 */ ALWAYSDEFD(guest_SC_CLASS), - /* 23 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) + /* 22 */ ALWAYSDEFD(guest_SC_CLASS) } }; diff --git a/VEX/priv/guest_x86_toIR.c b/VEX/priv/guest_x86_toIR.c index 8ecfad155c..35677385d1 100644 --- a/VEX/priv/guest_x86_toIR.c +++ b/VEX/priv/guest_x86_toIR.c @@ -277,9 +277,6 @@ static IRSB* irsb; #define OFFB_CMLEN offsetof(VexGuestX86State,guest_CMLEN) #define OFFB_NRADDR offsetof(VexGuestX86State,guest_NRADDR) -#define OFFB_IP_AT_SYSCALL offsetof(VexGuestX86State,guest_IP_AT_SYSCALL) - - /*------------------------------------------------------------*/ /*--- Helper bits and pieces for deconstructing the ---*/ /*--- x86 insn stream. ---*/ @@ -695,6 +692,8 @@ static IRExpr* mkV128 ( UShort mask ) return IRExpr_Const(IRConst_V128(mask)); } +#include "guest_generic_sse.h" + static IRExpr* loadLE ( IRType ty, IRExpr* addr ) { return IRExpr_Load(Iend_LE, ty, addr); @@ -4204,6 +4203,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, Int delta ) put_ST_UNCHECKED(r_src, mkexpr(t1)); break; + case 0xD0: /* FNOP */ + DIP("fnop\n"); + break; + case 0xE0: /* FCHS */ DIP("fchs\n"); put_ST_UNCHECKED(0, unop(Iop_NegF64, get_ST(0))); @@ -8047,6 +8050,206 @@ static IRTemp math_BSWAP ( IRTemp t1, IRType ty ) return IRTemp_INVALID; } +/*------------------------------------------------------------*/ +/*--- SSE4.1 BLEND instruction helpers ---*/ +/*------------------------------------------------------------*/ + +/* decode_sse4_blend_imm: Helper for decoding BLEND instructions + (BLENDPS, BLENDPD, PBLENDW). */ +static void decode_sse4_blend_imm (Int* delta_inout, const UChar* insn, + const HChar* insn_name, + IRTemp (*math_fn)(IRTemp, IRTemp, UInt), + UChar sorb) +{ + Int imm8, alen; + UChar modrm; + IRTemp addr; + HChar dis_buf[50]; + Int delta = *delta_inout; + IRTemp dst_vec = newTemp(Ity_V128); + IRTemp src_vec = newTemp(Ity_V128); + + //no REX prefix on 32bit + modrm = insn[3]; + assign( dst_vec, getXMMReg( gregOfRM(modrm) ) ); + + if ( epartIsReg(modrm) ) { + imm8 = insn[4]; + assign( src_vec, getXMMReg( eregOfRM(modrm) ) ); + //skip opcode bytes: +3 + delta += 1 + 1 + 3; + DIP( "%s $%d, %s,%s\n", insn_name, imm8, + nameXMMReg( eregOfRM(modrm) ), + nameXMMReg( gregOfRM(modrm) ) ); + } else { + //delta + 3 skips the opcode bytes + addr = disAMode( &alen, sorb, delta + 3, dis_buf); + assign( src_vec, loadLE( Ity_V128, mkexpr(addr) ) ); + imm8 = insn[3 + alen]; + //skip opcode bytes: +3 + delta += alen + 1 + 3; + DIP( "%s $%d, %s,%s\n", insn_name, + imm8, dis_buf, nameXMMReg( gregOfRM(modrm) ) ); + } + + putXMMReg( gregOfRM(modrm), + mkexpr( math_fn( src_vec, dst_vec, imm8) ) ); + + *delta_inout = delta; +} + +/* decode_sse4_blend: Helper for decoding BLEND instructions + (PBLENDVB, BLENDVPS, BLENDVPD) . */ +static void decode_sse4_blend (Int* delta_inout, const UChar* insn, + const HChar* insn_name, UInt gran, + UChar sorb, IROp opSAR) +{ + Int alen; + IRTemp addr; + HChar dis_buf[50]; + Int delta = *delta_inout; + IRTemp vecE = newTemp(Ity_V128); + IRTemp vecG = newTemp(Ity_V128); + IRTemp vec0 = newTemp(Ity_V128); + UChar modrm = insn[3]; + + if ( epartIsReg(modrm) ) { + assign(vecE, getXMMReg(eregOfRM(modrm))); + delta += 1 + 3; + DIP( "%s %s,%s\n", insn_name, + nameXMMReg( eregOfRM(modrm) ), + nameXMMReg( gregOfRM(modrm) ) ); + } else { + addr = disAMode( &alen, sorb, delta + 3, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); + assign(vecE, loadLE( Ity_V128, mkexpr(addr) )); + delta += alen + 3; + DIP( "%s %s,%s\n", insn_name, + dis_buf, nameXMMReg( gregOfRM(modrm) ) ); + } + + assign(vecG, getXMMReg(gregOfRM(modrm))); + assign(vec0, getXMMReg(0)); + + IRTemp res = math_PBLENDVB_128( vecE, vecG, vec0, gran, opSAR ); + putXMMReg(gregOfRM(modrm), mkexpr(res)); + + *delta_inout = delta; +} + +/*------------------------------------------------------------*/ +/*--- SSE4.1 PTEST instruction helpers ---*/ +/* Taken from amd64, but only for 128 bit, sse4 PTEST */ +/*------------------------------------------------------------*/ + +static void finish_xTESTy ( IRTemp andV, IRTemp andnV ) +{ + /* Set Z=1 iff (vecE & vecG) == 0--(128)--0 + Set C=1 iff (vecE & not vecG) == 0--(128)--0 + + Be careful to use only IROps that can be instrumented exactly + by memcheck. + This is because PTEST is used for __builtin_strcmp in gcc14. See + https://bugzilla.redhat.com/show_bug.cgi?id=2257546 + */ + + /* andV, andnV: vecE & vecG, vecE and not(vecG) */ + + /* andV resp. andnV, are reduced to 64-bit values by or-ing the top + and bottom 64-bits together. It relies on this trick: + + InterleaveLO64x2([a,b],[c,d]) == [b,d] hence + + InterleaveLO64x2([a,b],[a,b]) == [b,b] and similarly + InterleaveHI64x2([a,b],[a,b]) == [a,a] + + and so the OR of the above 2 exprs produces + [a OR b, a OR b], from which we simply take the lower half. + */ + IRTemp and64 = newTemp(Ity_I64); + IRTemp andn64 = newTemp(Ity_I64); + + assign(and64, + unop(Iop_V128to64, + binop(Iop_OrV128, + binop(Iop_InterleaveLO64x2, + mkexpr(andV), mkexpr(andV)), + binop(Iop_InterleaveHI64x2, + mkexpr(andV), mkexpr(andV))))); + + assign(andn64, + unop(Iop_V128to64, + binop(Iop_OrV128, + binop(Iop_InterleaveLO64x2, + mkexpr(andnV), mkexpr(andnV)), + binop(Iop_InterleaveHI64x2, + mkexpr(andnV), mkexpr(andnV))))); + + // Make z64 and c64 be either all-0s or all-1s + IRTemp z64 = newTemp(Ity_I64); + IRTemp c64 = newTemp(Ity_I64); + + assign(z64, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(and64), mkU64(0)), + mkU64(~0ULL), mkU64(0ULL))); + assign(c64, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(andn64), mkU64(0)), + mkU64(~0ULL), mkU64(0ULL))); + + /* And finally, slice out the Z and C flags and set the flags + thunk to COPY for them. OSAP are set to zero. */ + IRTemp newOSZACP = newTemp(Ity_I64); + assign(newOSZACP, + binop(Iop_Or64, + binop(Iop_And64, mkexpr(z64), mkU64(X86G_CC_MASK_Z)), + binop(Iop_And64, mkexpr(c64), mkU64(X86G_CC_MASK_C)))); + + stmt( IRStmt_Put( OFFB_CC_DEP1, unop(Iop_64to32, mkexpr(newOSZACP)) )); + stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) )); + stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) )); + stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) )); +} + + +/* Handles 128 bit PTEST. */ +static Long dis_xTESTy_128 ( const VexAbiInfo* vbi, UChar sorb, Long delta ) +{ + IRTemp addr = IRTemp_INVALID; + Int alen = 0; + HChar dis_buf[50]; + UChar modrm = getUChar(delta); + UInt rG = gregOfRM(modrm); + IRTemp vecE = newTemp(Ity_V128); + IRTemp vecG = newTemp(Ity_V128); + + if ( epartIsReg(modrm) ) { + UInt rE = eregOfRM(modrm); + assign(vecE, getXMMReg(rE)); + delta += 1; + DIP( "ptest %s,%s\n", nameXMMReg(rE), nameXMMReg(rG) ); + } else { + addr = disAMode( &alen, sorb, delta, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); + assign(vecE, loadLE( Ity_V128, mkexpr(addr) )); + delta += alen; + DIP( "ptest %s,%s\n", dis_buf, nameXMMReg(rG) ); + } + + assign(vecG, getXMMReg(rG)); + + /* Set Z=1 iff (vecE & vecG) == 0 + Set C=1 iff (vecE & not vecG) == 0 + */ + + /* andV, andnV: vecE & vecG, vecE and not(vecG) */ + IRTemp andV = newTemp(Ity_V128); + IRTemp andnV = newTemp(Ity_V128); + assign(andV, binop(Iop_AndV128, mkexpr(vecE), mkexpr(vecG))); + assign(andnV, binop(Iop_AndV128, + mkexpr(vecE), unop(Iop_NotV128, mkexpr(vecG)))); + + finish_xTESTy ( andV, andnV ); + return delta; +} + /*------------------------------------------------------------*/ /*--- Disassemble a single instruction ---*/ /*------------------------------------------------------------*/ @@ -12939,6 +13142,31 @@ DisResult disInstr_X86_WRK ( /* --- start of the SSE4 decoder --- */ /* ---------------------------------------------------- */ + /* 66 0F 38 17 /r = PTEST xmm1, xmm2/m128 + Logical compare (set ZF and CF from AND/ANDN of the operands) */ + if ( sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x17) { + delta = dis_xTESTy_128( vbi, sorb, delta + 3 ); + goto decode_success; + } + + /* 66 0F 38 2A /r MOVNTDQA xmm1, m128 + "non-temporal" "streaming" load + Handle like MOVDQA but only memory operand is allowed */ + if ( sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x2A ) { + modrm = insn[3]; + if ( !epartIsReg( modrm ) ) { + addr = disAMode( &alen, sorb, delta+3, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); + putXMMReg( gregOfRM(modrm), + loadLE(Ity_V128, mkexpr(addr)) ); + DIP("movntdqa %s,%s\n", dis_buf, nameXMMReg(gregOfRM(modrm))); + delta += 3 + alen; + goto decode_success; + } + } + /* 66 0F 3A 22 /r ib = PINSRD xmm1, r/m32, imm8 Extract Doubleword int from gen.reg/mem32 and insert into xmm1 */ if ( sz == 2 @@ -12995,6 +13223,190 @@ DisResult disInstr_X86_WRK ( goto decode_success; } + /* 66 0F 3A 42 /r ib MPSADBW xmm1, xmm2/m128, imm8 + Multiple Packed Sums of Absolute Difference */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x42) { + Int imm8; + IRTemp src_vec = newTemp(Ity_V128); + IRTemp dst_vec = newTemp(Ity_V128); + modrm = insn[3]; + UInt rG = gregOfRM(modrm); + + assign( dst_vec, getXMMReg(rG) ); + + /* in a case of delta + 3, +3 skips the three opcode bytes (0F 3A 42) + that insn[] already matched */ + if ( epartIsReg( modrm ) ) { + UInt rE = eregOfRM(modrm); + + imm8 = (Int)(insn[3+1]); + assign( src_vec, getXMMReg(rE) ); + delta += 3+1+1; + DIP( "mpsadbw $%d, %s,%s\n", imm8, + nameXMMReg(rE), nameXMMReg(rG) ); + } else { + addr = disAMode( &alen, sorb, delta + 3, dis_buf); + gen_SEGV_if_not_16_aligned( addr ); + assign( src_vec, loadLE( Ity_V128, mkexpr(addr) ) ); + imm8 = (Int)(insn[3+alen]); + delta += 3+alen+1; + DIP( "mpsadbw $%d, %s,%s\n", imm8, dis_buf, nameXMMReg(rG) ); + } + + putXMMReg( rG, mkexpr( math_MPSADBW_128(dst_vec, src_vec, imm8) ) ); + goto decode_success; + } + + /* 66 0F 3A 0D /r ib = BLENDPD */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x0D) { + decode_sse4_blend_imm(&delta, insn, "blendpd", math_BLENDPD_128, sorb); + goto decode_success; + } + + /* 66 0F 3A 0C /r ib = BLENDPS */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x0C) { + decode_sse4_blend_imm(&delta, insn, "blendps", math_BLENDPS_128, sorb); + goto decode_success; + } + + /* 66 0F 3A 0E /r ib = PBLENDW */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x0E) { + decode_sse4_blend_imm(&delta, insn, "pblendw", math_PBLENDW_128, sorb); + goto decode_success; + } + + /* 66 0F 38 10 /r = PBLENDVB xmm1, xmm2/m128 */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x10) { + decode_sse4_blend(&delta, insn, "pblendvb", 1, sorb, Iop_SarN8x16); + goto decode_success; + } + + /* 66 0F 38 14 /r = BLENDVPS xmm1, xmm2/m128 */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x14) { + decode_sse4_blend(&delta, insn, "blendvps", 4, sorb, Iop_SarN32x4); + goto decode_success; + } + + /* 66 0F 38 15 /r = BLENDVPD xmm1, xmm2/m128 */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x15) { + decode_sse4_blend(&delta, insn, "blendvpd", 8, sorb, Iop_SarN64x2); + goto decode_success; + } + + /* 66 0F 38 29 = PCMPEQQ + 64x2 equality comparison */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x29) { + delta = dis_SSEint_E_to_G( sorb, delta+3, "pcmpeqq", + Iop_CmpEQ64x2, False); + goto decode_success; + } + + /* 66 0F 38 38 /r - PMINSB xmm1, xmm2/m128 + 66 0F 38 3C /r - PMAXSB xmm1, xmm2/m128 + Minimum/Maximum of Packed Signed Byte Integers (XMM) + */ + if (sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 + && (insn[2] == 0x38 || insn[2] == 0x3C)) { + /* FIXME: this needs an alignment check */ + Bool isMAX = insn[2] == 0x3C; + delta = dis_SSEint_E_to_G( + sorb, delta+3, + isMAX ? "pmaxsb" : "pminsb", + isMAX ? Iop_Max8Sx16 : Iop_Min8Sx16, + False + ); + goto decode_success; + } + + /* 66 0F 38 39 /r - PMINSD xmm1, xmm2/m128 + 66 0F 38 3D /r - PMAXSD xmm1, xmm2/m128 + 66 prefix (sz == 2): SSE2/SSE4 XMM instructions (128-bit) + 0F 38 is the secondary escape used for SSSE3, SSE4, and later extensions + 39 = PMINSD (minimum of packed signed 32-bit integers) + 3D = PMAXSD (maximum of packed signed 32-bit integers) + reference: Intel Software Developer Manual (Volume 2: Instruction Set Reference) */ + if (sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 + && (insn[2] == 0x39 || insn[2] == 0x3D)) { + Bool isMAX = insn[2] == 0x3D; + delta = dis_SSEint_E_to_G( + sorb, delta+3, + isMAX ? "pmaxsd" : "pminsd", + isMAX ? Iop_Max32Sx4 : Iop_Min32Sx4, + False + ); + goto decode_success; + } + + /* 66 0F 38 3A /r - PMINUW xmm1, xmm2/m128 + 66 0F 38 3E /r - PMAXUW xmm1, xmm2/m128 + Minimum/Maximum of Packed Unsigned Word Integers (XMM) + */ + if (sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 + && (insn[2] == 0x3A || insn[2] == 0x3E)) { + /* FIXME: this needs an alignment check */ + Bool isMAX = insn[2] == 0x3E; + delta = dis_SSEint_E_to_G( + sorb, delta+3, + isMAX ? "pmaxuw" : "pminuw", + isMAX ? Iop_Max16Ux8 : Iop_Min16Ux8, + False + ); + goto decode_success; + } + + /* 66 0F 38 3B /r - PMINUD xmm1, xmm2/m128 + 66 0F 38 3F /r - PMAXUD xmm1, xmm2/m128 + Minimum/Maximum of Packed Unsigned Doubleword Integers (XMM) + */ + if (sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 + && (insn[2] == 0x3B || insn[2] == 0x3F)) { + /* FIXME: this needs an alignment check */ + Bool isMAX = insn[2] == 0x3F; + delta = dis_SSEint_E_to_G( + sorb, delta+3, + isMAX ? "pmaxud" : "pminud", + isMAX ? Iop_Max32Ux4 : Iop_Min32Ux4, + False + ); + goto decode_success; + } + + /* 66 0F 38 40 /r - PMULLD xmm1, xmm2/m128 + 32x4 integer multiply from xmm2/m128 to xmm1 */ + if (sz == 2 + && insn[0] == 0x0F && insn[1] == 0x38 && insn[2] == 0x40) { + + modrm = insn[3]; + + IRTemp argL = newTemp(Ity_V128); + IRTemp argR = newTemp(Ity_V128); + + if (epartIsReg(modrm)) { + assign( argL, getXMMReg( eregOfRM(modrm) ) ); + delta += 3+1; + DIP( "pmulld %s,%s\n", + nameXMMReg( eregOfRM(modrm) ), + nameXMMReg( gregOfRM(modrm) ) ); + } else { + addr = disAMode( &alen, sorb, delta+3, dis_buf ); + assign( argL, loadLE( Ity_V128, mkexpr(addr) )); + delta += 3+alen; + DIP( "pmulld %s,%s\n", + dis_buf, nameXMMReg( gregOfRM(modrm) ) ); + } + + assign(argR, getXMMReg( gregOfRM(modrm) )); + + putXMMReg( gregOfRM(modrm), + binop( Iop_Mul32x4, mkexpr(argL), mkexpr(argR)) ); + + goto decode_success; + } + /* 66 0F 3A 0B /r ib = ROUNDSD imm8, xmm2/m64, xmm1 (Partial implementation only -- only deal with cases where the rounding mode is specified directly by the immediate byte.) @@ -13072,6 +13484,8 @@ DisResult disInstr_X86_WRK ( nameIReg(sz, gregOfRM(modrm))); } + + IRTemp res = gen_LZCNT(ty, src); putIReg(sz, gregOfRM(modrm), mkexpr(res)); @@ -13509,8 +13923,6 @@ DisResult disInstr_X86_WRK ( goto decode_failure; } - stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, - mkU32(guest_EIP_curr_instr) ) ); jmp_lit(&dres, jump_kind, ((Addr32)guest_EIP_bbstart)+delta); vassert(dres.whatNext == Dis_StopHere); DIP("int $0x%x\n", d32); @@ -15212,11 +15624,6 @@ DisResult disInstr_X86_WRK ( thread will jump to address zero, which is probably fatal. */ - - /* Note where we are, so we can back up the guest to this - point if the syscall needs to be restarted. */ - stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, - mkU32(guest_EIP_curr_instr) ) ); jmp_lit(&dres, Ijk_Sys_sysenter, 0/*bogus next EIP value*/); vassert(dres.whatNext == Dis_StopHere); DIP("sysenter"); @@ -15369,8 +15776,6 @@ DisResult disInstr_X86_WRK ( } case 0x05: /* AMD's syscall */ - stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL, - mkU32(guest_EIP_curr_instr) ) ); jmp_lit(&dres, Ijk_Sys_syscall, ((Addr32)guest_EIP_bbstart)+delta); vassert(dres.whatNext == Dis_StopHere); DIP("syscall\n"); diff --git a/VEX/priv/host_amd64_defs.c b/VEX/priv/host_amd64_defs.c index d7d1ab1aad..e834e82536 100644 --- a/VEX/priv/host_amd64_defs.c +++ b/VEX/priv/host_amd64_defs.c @@ -2592,7 +2592,7 @@ static UChar* do_ffree_st ( UChar* p, Int n ) Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const AMD64Instr* i, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_amd64_defs.h b/VEX/priv/host_amd64_defs.h index 4c16db17bf..731fd2efd3 100644 --- a/VEX/priv/host_amd64_defs.h +++ b/VEX/priv/host_amd64_defs.h @@ -836,7 +836,7 @@ extern Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const AMD64Instr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index 6de40bccfb..3b0c459c49 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -5405,7 +5405,7 @@ HInstrArray* iselSB_AMD64 ( const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; AMD64AMode *amCounter, *amFailAddr; @@ -5430,7 +5430,7 @@ HInstrArray* iselSB_AMD64 ( const IRSB* bb, vassert(archinfo_host->endness == VexEndnessLE); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c index da52748eb9..b00aad94d5 100644 --- a/VEX/priv/host_arm64_defs.c +++ b/VEX/priv/host_arm64_defs.c @@ -3627,7 +3627,7 @@ static UInt* do_load_or_store64 ( UInt* p, Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const ARM64Instr* i, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h index 4f5b1bce3e..83bb6a286e 100644 --- a/VEX/priv/host_arm64_defs.h +++ b/VEX/priv/host_arm64_defs.h @@ -1115,7 +1115,7 @@ extern void mapRegs_ARM64Instr ( HRegRemap*, ARM64Instr*, Bool ); extern Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const ARM64Instr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo *archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c index 55d688531d..0c072d5835 100644 --- a/VEX/priv/host_arm64_isel.c +++ b/VEX/priv/host_arm64_isel.c @@ -4641,7 +4641,7 @@ HInstrArray* iselSB_ARM64 ( const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; ARM64AMode *amCounter, *amFailAddr; @@ -4655,7 +4655,7 @@ HInstrArray* iselSB_ARM64 ( const IRSB* bb, vassert(sizeof(ARM64Instr) <= 32); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/host_arm_defs.c b/VEX/priv/host_arm_defs.c index 39d89f7e87..3ca8b22a5d 100644 --- a/VEX/priv/host_arm_defs.c +++ b/VEX/priv/host_arm_defs.c @@ -39,7 +39,7 @@ #include "host_generic_regs.h" #include "host_arm_defs.h" -UInt arm_hwcaps = 0; +static UInt arm_hwcaps; /* --------- Registers. --------- */ @@ -3069,7 +3069,7 @@ static UInt* do_load_or_store32 ( UInt* p, Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const ARMInstr* i, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, @@ -3080,6 +3080,8 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, vassert(mode64 == False); vassert(0 == (((HWord)buf) & 3)); + arm_hwcaps = archinfo_host->hwcaps; + switch (i->tag) { case ARMin_Alu: { UInt instr, subopc; diff --git a/VEX/priv/host_arm_defs.h b/VEX/priv/host_arm_defs.h index 904bd0c43c..b8399075d9 100644 --- a/VEX/priv/host_arm_defs.h +++ b/VEX/priv/host_arm_defs.h @@ -32,9 +32,6 @@ #include "libvex.h" // VexArch #include "host_generic_regs.h" // HReg -extern UInt arm_hwcaps; - - /* --------- Registers. --------- */ #define ST_IN static inline @@ -1057,7 +1054,7 @@ extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool ); extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const ARMInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 90bc699fc4..75041b63b0 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -6540,7 +6540,7 @@ HInstrArray* iselSB_ARM ( const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; ARMAMode1 *amCounter, *amFailAddr; @@ -6553,11 +6553,8 @@ HInstrArray* iselSB_ARM ( const IRSB* bb, /* guard against unexpected space regressions */ vassert(sizeof(ARMInstr) <= 28); - /* hwcaps should not change from one ISEL call to another. */ - arm_hwcaps = hwcaps_host; // JRS 2012 Mar 31: FIXME (RM) - /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/host_generic_simd128.c b/VEX/priv/host_generic_simd128.c index b656aef50c..135a04d394 100644 --- a/VEX/priv/host_generic_simd128.c +++ b/VEX/priv/host_generic_simd128.c @@ -272,7 +272,7 @@ void VEX_REGPARM(3) semantics of these primops (Sar64x2, etc) it is an error if in fact we are ever given an out-of-range shift amount. */ -void /*not-regparm*/ +void VEX_REGPARM(3) h_generic_calc_SarN64x2 ( /*OUT*/V128* res, V128* argL, UInt nn) { @@ -282,7 +282,7 @@ void /*not-regparm*/ res->w64[1] = sar64(argL->w64[1], nn); } -void /*not-regparm*/ +void VEX_REGPARM(3) h_generic_calc_SarN8x16 ( /*OUT*/V128* res, V128* argL, UInt nn) { diff --git a/VEX/priv/host_generic_simd128.h b/VEX/priv/host_generic_simd128.h index 9e73e45a9a..3712baee6d 100644 --- a/VEX/priv/host_generic_simd128.h +++ b/VEX/priv/host_generic_simd128.h @@ -66,9 +66,9 @@ extern VEX_REGPARM(3) extern VEX_REGPARM(3) void h_generic_calc_CmpGT64Sx2 ( /*OUT*/V128*, V128*, V128* ); -extern /*not-regparm*/ +extern VEX_REGPARM(3) void h_generic_calc_SarN64x2 ( /*OUT*/V128*, V128*, UInt ); -extern /*not-regparm*/ +extern VEX_REGPARM(3) void h_generic_calc_SarN8x16 ( /*OUT*/V128*, V128*, UInt ); extern VEX_REGPARM(3) diff --git a/VEX/priv/host_mips_defs.c b/VEX/priv/host_mips_defs.c index ad92c055c9..d018aac841 100644 --- a/VEX/priv/host_mips_defs.c +++ b/VEX/priv/host_mips_defs.c @@ -3768,7 +3768,7 @@ static UChar *mkMoveReg(UChar * p, UInt r_dst, UInt r_src) Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const MIPSInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_mips_defs.h b/VEX/priv/host_mips_defs.h index 423f68ea09..838368b85c 100644 --- a/VEX/priv/host_mips_defs.h +++ b/VEX/priv/host_mips_defs.h @@ -1006,7 +1006,7 @@ extern void mapRegs_MIPSInstr (HRegRemap *, MIPSInstr *, Bool mode64); extern Int emit_MIPSInstr (/*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const MIPSInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index 7d57078ba8..19c761b00b 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -7410,7 +7410,7 @@ HInstrArray *iselSB_MIPS ( const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; MIPSAMode *amCounter, *amFailAddr; hwcaps_host = archinfo_host->hwcaps; @@ -7433,7 +7433,7 @@ HInstrArray *iselSB_MIPS ( const IRSB* bb, has_msa = VEX_MIPS_PROC_MSA(archinfo_host->hwcaps); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; env->mode64 = mode64; env->fp_mode64 = fp_mode64; diff --git a/VEX/priv/host_nanomips_defs.c b/VEX/priv/host_nanomips_defs.c index 3e91c904f6..19b4ee0fa4 100644 --- a/VEX/priv/host_nanomips_defs.c +++ b/VEX/priv/host_nanomips_defs.c @@ -1343,7 +1343,7 @@ Int emit_NANOMIPSInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const NANOMIPSInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_nanomips_defs.h b/VEX/priv/host_nanomips_defs.h index beb8084797..aa40b1e140 100644 --- a/VEX/priv/host_nanomips_defs.h +++ b/VEX/priv/host_nanomips_defs.h @@ -393,7 +393,7 @@ extern Int emit_NANOMIPSInstr (/*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const NANOMIPSInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_nanomips_isel.c b/VEX/priv/host_nanomips_isel.c index 65998fd8aa..c14dfbc106 100644 --- a/VEX/priv/host_nanomips_isel.c +++ b/VEX/priv/host_nanomips_isel.c @@ -1515,7 +1515,7 @@ HInstrArray *iselSB_NANOMIPS(const IRSB * bb, { Int i, j; HReg hreg, hregHI; - ISelEnv *env; + ISelEnv *env, envmem; hwcaps_host = archinfo_host->hwcaps; /* sanity ... */ vassert(arch_host == VexArchNANOMIPS); @@ -1523,7 +1523,7 @@ HInstrArray *iselSB_NANOMIPS(const IRSB * bb, vassert(archinfo_host->endness == VexEndnessLE || archinfo_host->endness == VexEndnessBE); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ env->code = newHInstrArray(); diff --git a/VEX/priv/host_ppc_defs.c b/VEX/priv/host_ppc_defs.c index dfefcb3fd4..7dc9714572 100644 --- a/VEX/priv/host_ppc_defs.c +++ b/VEX/priv/host_ppc_defs.c @@ -4154,7 +4154,7 @@ static UChar* mkFormVA ( UChar* p, UInt opc1, UInt r1, UInt r2, */ Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const PPCInstr* i, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, @@ -4167,6 +4167,7 @@ Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc, vex_printf("asm ");ppPPCInstr(i, mode64); vex_printf("\n"); } + VexEndness endness_host = archinfo_host->endness; switch (i->tag) { case Pin_LI: diff --git a/VEX/priv/host_ppc_defs.h b/VEX/priv/host_ppc_defs.h index c57afd50b5..df376e21c7 100644 --- a/VEX/priv/host_ppc_defs.h +++ b/VEX/priv/host_ppc_defs.h @@ -1269,7 +1269,7 @@ extern void mapRegs_PPCInstr ( HRegRemap*, PPCInstr* , Bool mode64); extern Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const PPCInstr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index ea7ff89a9d..daac1ed16f 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -7259,7 +7259,7 @@ HInstrArray* iselSB_PPC ( const IRSB* bb, { Int i, j; HReg hregLo, hregMedLo, hregMedHi, hregHi; - ISelEnv* env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; Bool mode64 = False; UInt mask32, mask64; @@ -7297,7 +7297,7 @@ HInstrArray* iselSB_PPC ( const IRSB* bb, IEndianess = Iend_LE; /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Are we being ppc32 or ppc64? */ diff --git a/VEX/priv/host_riscv64_defs.c b/VEX/priv/host_riscv64_defs.c index 152d4ae92c..dcb1a968de 100644 --- a/VEX/priv/host_riscv64_defs.c +++ b/VEX/priv/host_riscv64_defs.c @@ -1774,7 +1774,7 @@ Int emit_RISCV64Instr(/*MB_MOD*/ Bool* is_profInc, Int nbuf, const RISCV64Instr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_riscv64_defs.h b/VEX/priv/host_riscv64_defs.h index 7a97f90ef4..97a8420f79 100644 --- a/VEX/priv/host_riscv64_defs.h +++ b/VEX/priv/host_riscv64_defs.h @@ -612,7 +612,7 @@ Int emit_RISCV64Instr(/*MB_MOD*/ Bool* is_profInc, Int nbuf, const RISCV64Instr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_riscv64_isel.c b/VEX/priv/host_riscv64_isel.c index b174d260d0..ca1b8babe5 100644 --- a/VEX/priv/host_riscv64_isel.c +++ b/VEX/priv/host_riscv64_isel.c @@ -2014,7 +2014,7 @@ HInstrArray* iselSB_RISCV64(const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; /* Do some sanity checks. */ vassert(arch_host == VexArchRISCV64); @@ -2026,7 +2026,7 @@ HInstrArray* iselSB_RISCV64(const IRSB* bb, vassert(sizeof(RISCV64Instr) <= 32); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 9389364da8..df5f398517 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2020 + Copyright IBM Corp. 2010-2026 Copyright (C) 2012-2017 Florian Krohm (britzel@acm.org) This program is free software; you can redistribute it and/or @@ -40,7 +40,9 @@ #include "host_s390_defs.h" #include "s390_disasm.h" #include "guest_s390_defs.h" /* S390X_GUEST_OFFSET */ -#include + +/* Whether or not names of guest registers should be written symbolically. */ +#define SYMBOLIC_REGNAMES 1 /*------------------------------------------------------------*/ /*--- Forward declarations ---*/ @@ -49,6 +51,7 @@ static void s390_insn_map_regs(HRegRemap *, s390_insn *); static void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *); static UInt s390_tchain_load64_len(void); +static const HChar *s390_guest_regname(UInt); /*------------------------------------------------------------*/ @@ -294,15 +297,26 @@ s390_amode_as_string(const s390_amode *am) switch (am->tag) { case S390_AMODE_B12: case S390_AMODE_B20: - vex_sprintf(p, "%d(%s)", am->d, s390_hreg_as_string(am->b)); + if (SYMBOLIC_REGNAMES && + hregNumber(am->b) == S390_REGNO_GUEST_STATE_POINTER) { + vex_sprintf(p, "%s", s390_guest_regname(am->d)); + } else { + vex_sprintf(p, "%d(%s)", am->d, s390_hreg_as_string(am->b)); + } break; case S390_AMODE_BX12: case S390_AMODE_BX20: - /* s390_hreg_as_string returns pointer to local buffer. Need to - split this into two printfs */ - p += vex_sprintf(p, "%d(%s,", am->d, s390_hreg_as_string(am->x)); - vex_sprintf(p, "%s)", s390_hreg_as_string(am->b)); + if (SYMBOLIC_REGNAMES && + hregNumber(am->b) == S390_REGNO_GUEST_STATE_POINTER && + hregNumber(am->x) == 0) { + vex_sprintf(p, "%s", s390_guest_regname(am->d)); + } else { + /* s390_hreg_as_string returns a pointer to a static buffer. + Need to split this into two printfs */ + p += vex_sprintf(p, "%d(%s,", am->d, s390_hreg_as_string(am->x)); + vex_sprintf(p, "%s)", s390_hreg_as_string(am->b)); + } break; default: @@ -322,7 +336,8 @@ is_virtual_gpr(HReg reg) /* Helper function for all vector operations */ static UChar -s390_getM_from_size(const UChar size) { +s390_getM_from_size(const UChar size) +{ switch(size) { case 1: return 0; @@ -342,7 +357,8 @@ s390_getM_from_size(const UChar size) { /* Helper for generating RXB field in vector instructions */ static UChar -s390_update_rxb(const UChar rxb, const UChar index, UChar* vr) { +s390_update_rxb(const UChar rxb, const UChar index, UChar* vr) +{ vassert((index >= 1) && (index <= 4)); UChar result = rxb; if(vr != NULL) { @@ -684,7 +700,8 @@ directReload_S390(HInstr* i, HReg vreg, Short spill_off) return NULL; } -s390_insn* genMove_S390(HReg from, HReg to, Bool mode64) +s390_insn * +genMove_S390(HReg from, HReg to, Bool mode64) { switch (hregClass(from)) { case HRcInt64: @@ -778,6 +795,12 @@ s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn) s390_opnd_RMI_get_reg_usage(u, insn->variant.alu.op2); break; + case S390_INSN_ALU3: + addHRegUse(u, HRmWrite, insn->variant.alu3.dst); + addHRegUse(u, HRmRead, insn->variant.alu3.op1); + addHRegUse(u, HRmRead, insn->variant.alu3.op2); + break; + case S390_INSN_SMUL: case S390_INSN_UMUL: addHRegUse(u, HRmModify, insn->variant.mul.dst_lo); /* op1 */ @@ -1134,6 +1157,12 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) s390_opnd_RMI_map_regs(m, &insn->variant.alu.op2); break; + case S390_INSN_ALU3: + insn->variant.alu3.dst = lookupHRegRemap(m, insn->variant.alu3.dst); + insn->variant.alu3.op1 = lookupHRegRemap(m, insn->variant.alu3.op1); + insn->variant.alu3.op2 = lookupHRegRemap(m, insn->variant.alu3.op2); + break; + case S390_INSN_SMUL: case S390_INSN_UMUL: insn->variant.mul.dst_hi = lookupHRegRemap(m, insn->variant.mul.dst_hi); @@ -1468,24 +1497,42 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) /*--- Functions to emit a sequence of bytes ---*/ /*------------------------------------------------------------*/ +static __inline__ UChar * +emit(UChar *p, const UChar *insn, UInt len) +{ + if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) { + HChar *str = s390_disasm(insn, /* padmnm */ 1); + vex_printf("%s\n", str ? str : "disassembly failed"); + } + + return (UChar *)__builtin_memcpy(p, insn, len) + len; +} + + static __inline__ UChar * emit_2bytes(UChar *p, ULong val) { - return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 6, 2) + 2; + const UChar *insn = (UChar *)&val + 6; + + return emit(p, insn, 2); } static __inline__ UChar * emit_4bytes(UChar *p, ULong val) { - return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 4, 4) + 4; + const UChar *insn = (UChar *)&val + 4; + + return emit(p, insn, 4); } static __inline__ UChar * emit_6bytes(UChar *p, ULong val) { - return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 2, 6) + 6; + const UChar *insn = (UChar *)&val + 2; + + return emit(p, insn, 6); } @@ -1637,6 +1684,19 @@ emit_RRF5(UChar *p, UInt op, UChar m4, UChar r1, UChar r2) } +static UChar * +emit_RRF6(UChar *p, UInt op, UChar r1, UChar r2, UChar r3) +{ + ULong the_insn = op; + + the_insn |= ((ULong)r3) << 12; + the_insn |= ((ULong)r1) << 4; + the_insn |= ((ULong)r2) << 0; + + return emit_4bytes(p, the_insn); +} + + static UChar * emit_RS(UChar *p, UInt op, UChar r1, UChar r3, UChar b2, UShort d2) { @@ -1998,9 +2058,6 @@ emit_VRR_VVVMM(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar m4, static UChar * s390_emit_AR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ar"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1a00, r1, r2); } @@ -2008,9 +2065,6 @@ s390_emit_AR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_AGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("agr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9080000, r1, r2); } @@ -2018,9 +2072,6 @@ s390_emit_AGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_A(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("a"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x5a000000, r1, x2, b2, d2); } @@ -2028,9 +2079,6 @@ s390_emit_A(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ay"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000005aULL, r1, x2, b2, dl2, dh2); } @@ -2038,9 +2086,6 @@ s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ag"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000008ULL, r1, x2, b2, dl2, dh2); } @@ -2048,11 +2093,6 @@ s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_AFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("afi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20900000000ULL, r1, i2); } @@ -2060,11 +2100,6 @@ s390_emit_AFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_AGFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("agfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20800000000ULL, r1, i2); } @@ -2072,9 +2107,6 @@ s390_emit_AGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_AH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ah"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x4a000000, r1, x2, b2, d2); } @@ -2082,9 +2114,6 @@ s390_emit_AH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_AHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ahy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000007aULL, r1, x2, b2, dl2, dh2); } @@ -2092,9 +2121,6 @@ s390_emit_AHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_AHI(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ahi"), GPR(r1), INT((Int)(Short)i2)); - return emit_RI(p, 0xa70a0000, r1, i2); } @@ -2102,9 +2128,6 @@ s390_emit_AHI(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_AGHI(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("aghi"), GPR(r1), INT((Int)(Short)i2)); - return emit_RI(p, 0xa70b0000, r1, i2); } @@ -2112,11 +2135,6 @@ s390_emit_AGHI(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_AGSI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("agsi"), SDXB(dh1, dl1, 0, b1), INT((Int)(Char)i2)); - return emit_SIY(p, 0xeb000000007aULL, i2, b1, dl1, dh1); } @@ -2124,11 +2142,6 @@ s390_emit_AGSI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) static UChar * s390_emit_ASI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("asi"), SDXB(dh1, dl1, 0, b1), INT((Int)(Char)i2)); - return emit_SIY(p, 0xeb000000006aULL, i2, b1, dl1, dh1); } @@ -2136,9 +2149,6 @@ s390_emit_ASI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) static UChar * s390_emit_NR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("nr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1400, r1, r2); } @@ -2146,9 +2156,6 @@ s390_emit_NR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_NGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ngr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9800000, r1, r2); } @@ -2156,9 +2163,6 @@ s390_emit_NGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_N(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("n"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x54000000, r1, x2, b2, d2); } @@ -2166,9 +2170,6 @@ s390_emit_N(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ny"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000054ULL, r1, x2, b2, dl2, dh2); } @@ -2176,9 +2177,6 @@ s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ng"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000080ULL, r1, x2, b2, dl2, dh2); } @@ -2186,11 +2184,6 @@ s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_NIHF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("nihf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00a00000000ULL, r1, i2); } @@ -2198,11 +2191,6 @@ s390_emit_NIHF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_NILF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("nilf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00b00000000ULL, r1, i2); } @@ -2210,9 +2198,6 @@ s390_emit_NILF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_NILL(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("nill"), GPR(r1), UINT(i2)); - return emit_RI(p, 0xa5070000, r1, i2); } @@ -2220,9 +2205,6 @@ s390_emit_NILL(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_TM(UChar *p, UChar i2, UChar b1, UShort d1) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("tm"), UDXB(d1, 0, b1), UINT(i2)); - return emit_SI(p, 0x91000000, i2, b1, d1); } @@ -2230,9 +2212,6 @@ s390_emit_TM(UChar *p, UChar i2, UChar b1, UShort d1) static UChar * s390_emit_TMY(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("tmy"), SDXB(dh1, dl1, 0, b1), UINT(i2)); - return emit_SIY(p, 0xeb0000000051ULL, i2, b1, dl1, dh1); } @@ -2240,9 +2219,6 @@ s390_emit_TMY(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1) static UChar * s390_emit_TMLL(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("tmll"), GPR(r1), UINT(i2)); - return emit_RI(p, 0xa7010000, r1, i2); } @@ -2250,9 +2226,6 @@ s390_emit_TMLL(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_BASR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("basr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x0d00, r1, r2); } @@ -2260,9 +2233,6 @@ s390_emit_BASR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_BCR(UChar *p, UChar m1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("bcr", bcr_disasm), MASK(m1), GPR(r2)); - return emit_RR(p, 0x0700, m1, r2); } @@ -2270,9 +2240,6 @@ s390_emit_BCR(UChar *p, UChar m1, UChar r2) static UChar * s390_emit_BRC(UChar *p, UChar m1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("brc", brc_disasm), MASK(m1), PCREL((Int)(Short)i2)); - return emit_RI(p, 0xa7040000, m1, i2); } @@ -2280,9 +2247,6 @@ s390_emit_BRC(UChar *p, UChar m1, UShort i2) static UChar * s390_emit_BRCL(UChar *p, UChar m1, ULong i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("brcl", brcl_disasm), MASK(m1), PCREL(i2)); - return emit_RIL(p, 0xc00400000000ULL, m1, i2); } @@ -2290,9 +2254,6 @@ s390_emit_BRCL(UChar *p, UChar m1, ULong i2) static UChar * s390_emit_CR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1900, r1, r2); } @@ -2300,9 +2261,6 @@ s390_emit_CR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9200000, r1, r2); } @@ -2310,9 +2268,6 @@ s390_emit_CGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_C(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("c"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x59000000, r1, x2, b2, d2); } @@ -2320,9 +2275,6 @@ s390_emit_C(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000059ULL, r1, x2, b2, dl2, dh2); } @@ -2330,9 +2282,6 @@ s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000020ULL, r1, x2, b2, dl2, dh2); } @@ -2340,11 +2289,6 @@ s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20d00000000ULL, r1, i2); } @@ -2352,11 +2296,6 @@ s390_emit_CFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_CGFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cgfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20c00000000ULL, r1, i2); } @@ -2364,9 +2303,6 @@ s390_emit_CGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_CS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cs"), GPR(r1), GPR(r3), UDXB(d2, 0, b2)); - return emit_RS(p, 0xba000000, r1, r3, b2, d2); } @@ -2374,9 +2310,6 @@ s390_emit_CS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2) static UChar * s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("csy"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb0000000014ULL, r1, r3, b2, dl2, dh2); } @@ -2384,9 +2317,6 @@ s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("csg"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb0000000030ULL, r1, r3, b2, dl2, dh2); } @@ -2394,9 +2324,6 @@ s390_emit_CSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CDS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cds"), GPR(r1), GPR(r3), UDXB(d2, 0, b2)); - return emit_RS(p, 0xbb000000, r1, r3, b2, d2); } @@ -2404,9 +2331,6 @@ s390_emit_CDS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2) static UChar * s390_emit_CDSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cdsy"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb0000000031ULL, r1, r3, b2, dl2, dh2); } @@ -2414,9 +2338,6 @@ s390_emit_CDSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CDSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cdsg"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb000000003eULL, r1, r3, b2, dl2, dh2); } @@ -2424,9 +2345,6 @@ s390_emit_CDSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CLR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("clr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1500, r1, r2); } @@ -2434,9 +2352,6 @@ s390_emit_CLR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CLGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("clgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9210000, r1, r2); } @@ -2444,9 +2359,6 @@ s390_emit_CLGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CL(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cl"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x55000000, r1, x2, b2, d2); } @@ -2454,9 +2366,6 @@ s390_emit_CL(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cly"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000055ULL, r1, x2, b2, dl2, dh2); } @@ -2464,9 +2373,6 @@ s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("clg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000021ULL, r1, x2, b2, dl2, dh2); } @@ -2474,11 +2380,6 @@ s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_CLFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("clfi"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc20f00000000ULL, r1, i2); } @@ -2486,11 +2387,6 @@ s390_emit_CLFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_CLGFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("clgfi"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc20e00000000ULL, r1, i2); } @@ -2498,9 +2394,6 @@ s390_emit_CLGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_DR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1d00, r1, r2); } @@ -2508,9 +2401,6 @@ s390_emit_DR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_D(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("d"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x5d000000, r1, x2, b2, d2); } @@ -2518,9 +2408,6 @@ s390_emit_D(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_DLR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dlr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9970000, r1, r2); } @@ -2528,9 +2415,6 @@ s390_emit_DLR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_DLGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dlgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9870000, r1, r2); } @@ -2538,9 +2422,6 @@ s390_emit_DLGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dl"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000097ULL, r1, x2, b2, dl2, dh2); } @@ -2548,9 +2429,6 @@ s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_DLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dlg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000087ULL, r1, x2, b2, dl2, dh2); } @@ -2558,9 +2436,6 @@ s390_emit_DLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_DSGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dsgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb90d0000, r1, r2); } @@ -2568,9 +2443,6 @@ s390_emit_DSGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_DSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dsg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000000dULL, r1, x2, b2, dl2, dh2); } @@ -2578,9 +2450,6 @@ s390_emit_DSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_XR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1700, r1, r2); } @@ -2588,9 +2457,6 @@ s390_emit_XR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_XGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9820000, r1, r2); } @@ -2598,9 +2464,6 @@ s390_emit_XGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_X(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("x"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x57000000, r1, x2, b2, d2); } @@ -2608,9 +2471,6 @@ s390_emit_X(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000057ULL, r1, x2, b2, dl2, dh2); } @@ -2618,9 +2478,6 @@ s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000082ULL, r1, x2, b2, dl2, dh2); } @@ -2628,11 +2485,6 @@ s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_XIHF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xihf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00600000000ULL, r1, i2); } @@ -2640,11 +2492,6 @@ s390_emit_XIHF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_XILF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xilf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00700000000ULL, r1, i2); } @@ -2652,9 +2499,6 @@ s390_emit_XILF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_XC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("xc"), UDLB(d1, l, b1), UDXB(d2, 0, b2)); - return emit_SSa(p, 0xd70000000000ULL, l, b1, d1, b2, d2); } @@ -2662,21 +2506,20 @@ s390_emit_XC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2) static UChar * s390_emit_FLOGR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); + return emit_RRE(p, 0xb9830000, r1, r2); +} - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("flogr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9830000, r1, r2); +static UChar * +s390_emit_POPCNT(UChar *p, UChar r1, UChar r2) +{ + return emit_RRF3(p, 0xb9e10000, 8, r1, r2); } static UChar * s390_emit_IC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ic"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x43000000, r1, x2, b2, d2); } @@ -2684,9 +2527,6 @@ s390_emit_IC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("icy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000073ULL, r1, x2, b2, dl2, dh2); } @@ -2694,83 +2534,27 @@ s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_IIHF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iihf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00800000000ULL, r1, i2); } -static UChar * -s390_emit_IIHH(UChar *p, UChar r1, UShort i2) -{ - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iihh"), GPR(r1), UINT(i2)); - - return emit_RI(p, 0xa5000000, r1, i2); -} - - -static UChar * -s390_emit_IIHL(UChar *p, UChar r1, UShort i2) -{ - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iihl"), GPR(r1), UINT(i2)); - - return emit_RI(p, 0xa5010000, r1, i2); -} - - static UChar * s390_emit_IILF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iilf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00900000000ULL, r1, i2); } static UChar * -s390_emit_IILH(UChar *p, UChar r1, UShort i2) -{ - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iilh"), GPR(r1), UINT(i2)); - - return emit_RI(p, 0xa5020000, r1, i2); -} - - -static UChar * -s390_emit_IILL(UChar *p, UChar r1, UShort i2) -{ - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iill"), GPR(r1), UINT(i2)); - - return emit_RI(p, 0xa5030000, r1, i2); -} - - -static UChar * -s390_emit_IPM(UChar *p, UChar r1, UChar r2) +s390_emit_IPM(UChar *p, UChar r1) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ipm"), GPR(r1)); - - return emit_RRE(p, 0xb2220000, r1, r2); + return emit_RRE(p, 0xb2220000, r1, 0); } static UChar * s390_emit_LR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1800, r1, r2); } @@ -2778,9 +2562,6 @@ s390_emit_LR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9040000, r1, r2); } @@ -2788,9 +2569,6 @@ s390_emit_LGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LGFR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgfr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9140000, r1, r2); } @@ -2798,9 +2576,6 @@ s390_emit_LGFR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_L(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("l"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x58000000, r1, x2, b2, d2); } @@ -2808,19 +2583,27 @@ s390_emit_L(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_LY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ly"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000058ULL, r1, x2, b2, dl2, dh2); } static UChar * -s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) +s390_emit_LA(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) +{ + return emit_RX(p, 0x41000000, r1, x2, b2, d2); +} + + +static UChar * +s390_emit_LAY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); + return emit_RXY(p, 0xe30000000071ULL, r1, x2, b2, dl2, dh2); +} + +static UChar * +s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) +{ return emit_RXY(p, 0xe30000000004ULL, r1, x2, b2, dl2, dh2); } @@ -2828,9 +2611,6 @@ s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgf"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000014ULL, r1, x2, b2, dl2, dh2); } @@ -2838,11 +2618,6 @@ s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LGFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc00100000000ULL, r1, i2); } @@ -2850,9 +2625,6 @@ s390_emit_LGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_LTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ltr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1200, r1, r2); } @@ -2860,9 +2632,6 @@ s390_emit_LTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LTGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ltgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9020000, r1, r2); } @@ -2870,11 +2639,6 @@ s390_emit_LTGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lt"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000012ULL, r1, x2, b2, dl2, dh2); } @@ -2882,11 +2646,6 @@ s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ltg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000002ULL, r1, x2, b2, dl2, dh2); } @@ -2894,11 +2653,6 @@ s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LBR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lbr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9260000, r1, r2); } @@ -2906,11 +2660,6 @@ s390_emit_LBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LGBR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgbr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9060000, r1, r2); } @@ -2918,9 +2667,6 @@ s390_emit_LGBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lb"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000076ULL, r1, x2, b2, dl2, dh2); } @@ -2928,9 +2674,6 @@ s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LGB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgb"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000077ULL, r1, x2, b2, dl2, dh2); } @@ -2938,9 +2681,6 @@ s390_emit_LGB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LCR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lcr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1300, r1, r2); } @@ -2948,9 +2688,6 @@ s390_emit_LCR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LCGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lcgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9030000, r1, r2); } @@ -2958,11 +2695,6 @@ s390_emit_LCGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LHR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lhr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9270000, r1, r2); } @@ -2970,11 +2702,6 @@ s390_emit_LHR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LGHR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lghr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9070000, r1, r2); } @@ -2982,9 +2709,6 @@ s390_emit_LGHR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lh"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x48000000, r1, x2, b2, d2); } @@ -2992,9 +2716,6 @@ s390_emit_LH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lhy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000078ULL, r1, x2, b2, dl2, dh2); } @@ -3002,9 +2723,6 @@ s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgh"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000015ULL, r1, x2, b2, dl2, dh2); } @@ -3012,9 +2730,6 @@ s390_emit_LGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LHI(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lhi"), GPR(r1), INT((Int)(Short)i2)); - return emit_RI(p, 0xa7080000, r1, i2); } @@ -3022,9 +2737,6 @@ s390_emit_LHI(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_LGHI(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lghi"), GPR(r1), INT((Int)(Short)i2)); - return emit_RI(p, 0xa7090000, r1, i2); } @@ -3032,9 +2744,6 @@ s390_emit_LGHI(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_LLGFR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llgfr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9160000, r1, r2); } @@ -3042,9 +2751,6 @@ s390_emit_LLGFR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llgf"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000016ULL, r1, x2, b2, dl2, dh2); } @@ -3052,11 +2758,6 @@ s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LLCR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llcr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9940000, r1, r2); } @@ -3064,11 +2765,6 @@ s390_emit_LLCR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LLGCR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llgcr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9840000, r1, r2); } @@ -3076,11 +2772,6 @@ s390_emit_LLGCR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llc"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000094ULL, r1, x2, b2, dl2, dh2); } @@ -3088,9 +2779,6 @@ s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llgc"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000090ULL, r1, x2, b2, dl2, dh2); } @@ -3098,11 +2786,6 @@ s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LLHR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llhr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9950000, r1, r2); } @@ -3110,11 +2793,6 @@ s390_emit_LLHR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LLGHR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llghr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9850000, r1, r2); } @@ -3122,11 +2800,6 @@ s390_emit_LLGHR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llh"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000095ULL, r1, x2, b2, dl2, dh2); } @@ -3134,9 +2807,6 @@ s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llgh"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000091ULL, r1, x2, b2, dl2, dh2); } @@ -3144,31 +2814,13 @@ s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LLILF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llilf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00f00000000ULL, r1, i2); } -static UChar * -s390_emit_LLILH(UChar *p, UChar r1, UShort i2) -{ - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llilh"), GPR(r1), UINT(i2)); - - return emit_RI(p, 0xa50e0000, r1, i2); -} - - static UChar * s390_emit_LLILL(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("llill"), GPR(r1), UINT(i2)); - return emit_RI(p, 0xa50f0000, r1, i2); } @@ -3176,9 +2828,6 @@ s390_emit_LLILL(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_MR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1c00, r1, r2); } @@ -3186,9 +2835,6 @@ s390_emit_MR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_M(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("m"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x5c000000, r1, x2, b2, d2); } @@ -3196,11 +2842,6 @@ s390_emit_M(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mfy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000005cULL, r1, x2, b2, dl2, dh2); } @@ -3208,9 +2849,6 @@ s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000084ULL, r1, x2, b2, dl2, dh2); } @@ -3218,9 +2856,6 @@ s390_emit_MG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MGRK(UChar *p, UChar r3, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mgrk"), GPR(r1), GPR(r2), GPR(r3)); - return emit_RRF3(p, 0xb9ec0000, r3, r1, r2); } @@ -3228,9 +2863,6 @@ s390_emit_MGRK(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mh"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x4c000000, r1, x2, b2, d2); } @@ -3238,11 +2870,6 @@ s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_MHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mhy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000007cULL, r1, x2, b2, dl2, dh2); } @@ -3250,9 +2877,6 @@ s390_emit_MHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MHI(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mhi"), GPR(r1), INT((Int)(Short)i2)); - return emit_RI(p, 0xa70c0000, r1, i2); } @@ -3260,9 +2884,6 @@ s390_emit_MHI(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_MLR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mlr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9960000, r1, r2); } @@ -3270,9 +2891,6 @@ s390_emit_MLR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MLGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mlgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9860000, r1, r2); } @@ -3280,9 +2898,6 @@ s390_emit_MLGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ml"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000096ULL, r1, x2, b2, dl2, dh2); } @@ -3290,9 +2905,6 @@ s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mlg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000086ULL, r1, x2, b2, dl2, dh2); } @@ -3300,9 +2912,6 @@ s390_emit_MLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MSR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb2520000, r1, r2); } @@ -3310,9 +2919,6 @@ s390_emit_MSR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MSGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb90c0000, r1, r2); } @@ -3320,9 +2926,6 @@ s390_emit_MSGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MS(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ms"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x71000000, r1, x2, b2, d2); } @@ -3330,9 +2933,6 @@ s390_emit_MS(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000051ULL, r1, x2, b2, dl2, dh2); } @@ -3340,9 +2940,6 @@ s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000000cULL, r1, x2, b2, dl2, dh2); } @@ -3350,11 +2947,6 @@ s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_MSFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20100000000ULL, r1, i2); } @@ -3362,11 +2954,6 @@ s390_emit_MSFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_MSGFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msgfi"), GPR(r1), INT(i2)); - return emit_RIL(p, 0xc20000000000ULL, r1, i2); } @@ -3374,9 +2961,6 @@ s390_emit_MSGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_MVC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mvc"), UDLB(d1, l, b1), UDXB(d2, 0, b2)); - return emit_SSa(p, 0xd20000000000ULL, l, b1, d1, b2, d2); } @@ -3384,9 +2968,6 @@ s390_emit_MVC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2) static UChar * s390_emit_MVI(UChar *p, UChar i2, UChar b1, UShort d1) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mvi"), UDXB(d1, 0, b1), UINT(i2)); - return emit_SI(p, 0x92000000, i2, b1, d1); } @@ -3394,11 +2975,6 @@ s390_emit_MVI(UChar *p, UChar i2, UChar b1, UShort d1) static UChar * s390_emit_MVHHI(UChar *p, UChar b1, UShort d1, UShort i2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mvhhi"), UDXB(d1, 0, b1), INT((Int)(Short)i2)); - return emit_SIL(p, 0xe54400000000ULL, b1, d1, i2); } @@ -3406,11 +2982,6 @@ s390_emit_MVHHI(UChar *p, UChar b1, UShort d1, UShort i2) static UChar * s390_emit_MVHI(UChar *p, UChar b1, UShort d1, UShort i2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mvhi"), UDXB(d1, 0, b1), INT((Int)(Short)i2)); - return emit_SIL(p, 0xe54c00000000ULL, b1, d1, i2); } @@ -3418,11 +2989,6 @@ s390_emit_MVHI(UChar *p, UChar b1, UShort d1, UShort i2) static UChar * s390_emit_MVGHI(UChar *p, UChar b1, UShort d1, UShort i2) { - vassert(s390_host_has_gie); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mvghi"), UDXB(d1, 0, b1), INT((Int)(Short)i2)); - return emit_SIL(p, 0xe54800000000ULL, b1, d1, i2); } @@ -3430,9 +2996,6 @@ s390_emit_MVGHI(UChar *p, UChar b1, UShort d1, UShort i2) static UChar * s390_emit_OR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("or"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1600, r1, r2); } @@ -3440,9 +3003,6 @@ s390_emit_OR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_OGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ogr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9810000, r1, r2); } @@ -3450,9 +3010,6 @@ s390_emit_OGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_O(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("o"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x56000000, r1, x2, b2, d2); } @@ -3460,9 +3017,6 @@ s390_emit_O(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("oy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000056ULL, r1, x2, b2, dl2, dh2); } @@ -3470,9 +3024,6 @@ s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("og"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000081ULL, r1, x2, b2, dl2, dh2); } @@ -3480,11 +3031,6 @@ s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_OIHF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("oihf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00c00000000ULL, r1, i2); } @@ -3492,11 +3038,6 @@ s390_emit_OIHF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_OILF(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("oilf"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc00d00000000ULL, r1, i2); } @@ -3504,9 +3045,6 @@ s390_emit_OILF(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_OILL(UChar *p, UChar r1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("oill"), GPR(r1), UINT(i2)); - return emit_RI(p, 0xa50b0000, r1, i2); } @@ -3514,9 +3052,6 @@ s390_emit_OILL(UChar *p, UChar r1, UShort i2) static UChar * s390_emit_SLL(UChar *p, UChar r1, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sll"), GPR(r1), UDXB(d2, 0, b2)); - return emit_RS(p, 0x89000000, r1, 0, b2, d2); } @@ -3524,9 +3059,6 @@ s390_emit_SLL(UChar *p, UChar r1, UChar b2, UShort d2) static UChar * s390_emit_SLLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sllg"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb000000000dULL, r1, r3, b2, dl2, dh2); } @@ -3534,9 +3066,6 @@ s390_emit_SLLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SRA(UChar *p, UChar r1, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sra"), GPR(r1), UDXB(d2, 0, b2)); - return emit_RS(p, 0x8a000000, r1, 0, b2, d2); } @@ -3544,9 +3073,6 @@ s390_emit_SRA(UChar *p, UChar r1, UChar b2, UShort d2) static UChar * s390_emit_SRAG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("srag"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb000000000aULL, r1, r3, b2, dl2, dh2); } @@ -3554,9 +3080,6 @@ s390_emit_SRAG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SRL(UChar *p, UChar r1, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("srl"), GPR(r1), UDXB(d2, 0, b2)); - return emit_RS(p, 0x88000000, r1, 0, b2, d2); } @@ -3564,9 +3087,6 @@ s390_emit_SRL(UChar *p, UChar r1, UChar b2, UShort d2) static UChar * s390_emit_SRLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("srlg"), GPR(r1), GPR(r3), SDXB(dh2, dl2, 0, b2)); - return emit_RSY(p, 0xeb000000000cULL, r1, r3, b2, dl2, dh2); } @@ -3574,9 +3094,6 @@ s390_emit_SRLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_ST(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("st"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x50000000, r1, x2, b2, d2); } @@ -3584,9 +3101,6 @@ s390_emit_ST(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sty"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000050ULL, r1, x2, b2, dl2, dh2); } @@ -3594,9 +3108,6 @@ s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_STG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("stg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000024ULL, r1, x2, b2, dl2, dh2); } @@ -3604,9 +3115,6 @@ s390_emit_STG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_STC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("stc"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x42000000, r1, x2, b2, d2); } @@ -3614,9 +3122,6 @@ s390_emit_STC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_STCY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("stcy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000072ULL, r1, x2, b2, dl2, dh2); } @@ -3624,9 +3129,6 @@ s390_emit_STCY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_STH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sth"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x40000000, r1, x2, b2, d2); } @@ -3634,9 +3136,6 @@ s390_emit_STH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_STHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sthy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000070ULL, r1, x2, b2, dl2, dh2); } @@ -3644,9 +3143,6 @@ s390_emit_STHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sr"), GPR(r1), GPR(r2)); - return emit_RR(p, 0x1b00, r1, r2); } @@ -3654,9 +3150,6 @@ s390_emit_SR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SGR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sgr"), GPR(r1), GPR(r2)); - return emit_RRE(p, 0xb9090000, r1, r2); } @@ -3664,9 +3157,6 @@ s390_emit_SGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_S(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("s"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x5b000000, r1, x2, b2, d2); } @@ -3674,9 +3164,6 @@ s390_emit_S(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000005bULL, r1, x2, b2, dl2, dh2); } @@ -3684,9 +3171,6 @@ s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sg"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe30000000009ULL, r1, x2, b2, dl2, dh2); } @@ -3694,9 +3178,6 @@ s390_emit_SG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sh"), GPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x4b000000, r1, x2, b2, d2); } @@ -3704,9 +3185,6 @@ s390_emit_SH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("shy"), GPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xe3000000007bULL, r1, x2, b2, dl2, dh2); } @@ -3714,11 +3192,6 @@ s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_SLFI(UChar *p, UChar r1, UInt i2) { - vassert(s390_host_has_eimm); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("slfi"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc20500000000ULL, r1, i2); } @@ -3726,9 +3199,6 @@ s390_emit_SLFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_SLGFI(UChar *p, UChar r1, UInt i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("slgfi"), GPR(r1), UINT(i2)); - return emit_RIL(p, 0xc20400000000ULL, r1, i2); } @@ -3736,9 +3206,6 @@ s390_emit_SLGFI(UChar *p, UChar r1, UInt i2) static UChar * s390_emit_LDR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ldr"), FPR(r1), FPR(r2)); - return emit_RR(p, 0x2800, r1, r2); } @@ -3746,9 +3213,6 @@ s390_emit_LDR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("le"), FPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x78000000, r1, x2, b2, d2); } @@ -3756,9 +3220,6 @@ s390_emit_LE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_LD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ld"), FPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x68000000, r1, x2, b2, d2); } @@ -3766,9 +3227,6 @@ s390_emit_LD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ley"), FPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xed0000000064ULL, r1, x2, b2, dl2, dh2); } @@ -3776,9 +3234,6 @@ s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ldy"), FPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xed0000000065ULL, r1, x2, b2, dl2, dh2); } @@ -3786,11 +3241,6 @@ s390_emit_LDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LDGR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_fgx); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ldgr"), FPR(r1), GPR(r2)); - return emit_RRE(p, 0xb3c10000, r1, r2); } @@ -3798,11 +3248,6 @@ s390_emit_LDGR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LGDR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_fgx); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lgdr"), GPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3cd0000, r1, r2); } @@ -3810,9 +3255,6 @@ s390_emit_LGDR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LZER(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lzer"), FPR(r1)); - return emit_RRE(p, 0xb3740000, r1, r2); } @@ -3820,9 +3262,6 @@ s390_emit_LZER(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LZDR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lzdr"), FPR(r1)); - return emit_RRE(p, 0xb3750000, r1, r2); } @@ -3830,9 +3269,6 @@ s390_emit_LZDR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SFPC(UChar *p, UChar r1) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sfpc"), GPR(r1)); - return emit_RRE(p, 0xb3840000, r1, 0); } @@ -3840,9 +3276,6 @@ s390_emit_SFPC(UChar *p, UChar r1) static UChar * s390_emit_STE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ste"), FPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x70000000, r1, x2, b2, d2); } @@ -3850,9 +3283,6 @@ s390_emit_STE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_STD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("std"), FPR(r1), UDXB(d2, x2, b2)); - return emit_RX(p, 0x60000000, r1, x2, b2, d2); } @@ -3860,9 +3290,6 @@ s390_emit_STD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("stey"), FPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xed0000000066ULL, r1, x2, b2, dl2, dh2); } @@ -3870,9 +3297,6 @@ s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_STDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("stdy"), FPR(r1), SDXB(dh2, dl2, x2, b2)); - return emit_RXY(p, 0xed0000000067ULL, r1, x2, b2, dl2, dh2); } @@ -3880,9 +3304,6 @@ s390_emit_STDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_AEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("aebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb30a0000, r1, r2); } @@ -3890,9 +3311,6 @@ s390_emit_AEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_ADBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("adbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb31a0000, r1, r2); } @@ -3900,9 +3318,6 @@ s390_emit_ADBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_AXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("axbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb34a0000, r1, r2); } @@ -3910,9 +3325,6 @@ s390_emit_AXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3090000, r1, r2); } @@ -3920,9 +3332,6 @@ s390_emit_CEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3190000, r1, r2); } @@ -3930,9 +3339,6 @@ s390_emit_CDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3490000, r1, r2); } @@ -3941,10 +3347,6 @@ static UChar * s390_emit_CEFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cefbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3940000, m3, m4, r1, r2); } @@ -3954,10 +3356,6 @@ static UChar * s390_emit_CDFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdfbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3950000, m3, m4, r1, r2); } @@ -3967,10 +3365,6 @@ static UChar * s390_emit_CXFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxfbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3960000, m3, m4, r1, r2); } @@ -3980,10 +3374,6 @@ static UChar * s390_emit_CEGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cegbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a40000, m3, m4, r1, r2); } @@ -3993,10 +3383,6 @@ static UChar * s390_emit_CDGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdgbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a50000, m3, m4, r1, r2); } @@ -4006,10 +3392,6 @@ static UChar * s390_emit_CXGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxgbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a60000, m3, m4, r1, r2); } @@ -4019,10 +3401,6 @@ static UChar * s390_emit_CELFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("celfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3900000, m3, m4, r1, r2); } @@ -4032,10 +3410,6 @@ static UChar * s390_emit_CDLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdlfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3910000, m3, m4, r1, r2); } @@ -4045,10 +3419,6 @@ static UChar * s390_emit_CXLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxlfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3920000, m3, m4, r1, r2); } @@ -4058,10 +3428,6 @@ static UChar * s390_emit_CELGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("celgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a00000, m3, m4, r1, r2); } @@ -4071,10 +3437,6 @@ static UChar * s390_emit_CDLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdlgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a10000, m3, m4, r1, r2); } @@ -4084,10 +3446,6 @@ static UChar * s390_emit_CXLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxlgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3a20000, m3, m4, r1, r2); } @@ -4097,10 +3455,6 @@ static UChar * s390_emit_CLFEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clfebr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb39c0000, m3, m4, r1, r2); } @@ -4110,10 +3464,6 @@ static UChar * s390_emit_CLFDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clfdbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb39d0000, m3, m4, r1, r2); } @@ -4123,10 +3473,6 @@ static UChar * s390_emit_CLFXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clfxbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb39e0000, m3, m4, r1, r2); } @@ -4136,10 +3482,6 @@ static UChar * s390_emit_CLGEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clgebr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3ac0000, m3, m4, r1, r2); } @@ -4149,10 +3491,6 @@ static UChar * s390_emit_CLGDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clgdbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3ad0000, m3, m4, r1, r2); } @@ -4162,10 +3500,6 @@ static UChar * s390_emit_CLGXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clgxbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3ae0000, m3, m4, r1, r2); } @@ -4174,9 +3508,6 @@ s390_emit_CLGXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CFEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cfebra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb3980000, m3, r1, r2); } @@ -4184,9 +3515,6 @@ s390_emit_CFEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CFDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cfdbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb3990000, m3, r1, r2); } @@ -4194,9 +3522,6 @@ s390_emit_CFDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CFXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cfxbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb39a0000, m3, r1, r2); } @@ -4204,9 +3529,6 @@ s390_emit_CFXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CGEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cgebra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb3a80000, m3, r1, r2); } @@ -4214,9 +3536,6 @@ s390_emit_CGEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CGDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cgdbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb3a90000, m3, r1, r2); } @@ -4224,9 +3543,6 @@ s390_emit_CGDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CGXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cgxbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF3(p, 0xb3aa0000, m3, r1, r2); } @@ -4234,9 +3550,6 @@ s390_emit_CGXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_DEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("debr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb30d0000, r1, r2); } @@ -4244,9 +3557,6 @@ s390_emit_DEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_DDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ddbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb31d0000, r1, r2); } @@ -4254,9 +3564,6 @@ s390_emit_DDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_DXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("dxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb34d0000, r1, r2); } @@ -4264,9 +3571,6 @@ s390_emit_DXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LCEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lcebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3030000, r1, r2); } @@ -4274,9 +3578,6 @@ s390_emit_LCEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LCDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lcdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3130000, r1, r2); } @@ -4284,9 +3585,6 @@ s390_emit_LCDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LCXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lcxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3430000, r1, r2); } @@ -4294,9 +3592,6 @@ s390_emit_LCXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LDEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ldebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3040000, r1, r2); } @@ -4304,9 +3599,6 @@ s390_emit_LDEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LXDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lxdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3050000, r1, r2); } @@ -4314,9 +3606,6 @@ s390_emit_LXDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LXEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lxebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3060000, r1, r2); } @@ -4324,9 +3613,6 @@ s390_emit_LXEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LNEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lnebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3010000, r1, r2); } @@ -4334,9 +3620,6 @@ s390_emit_LNEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LNDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lndbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3110000, r1, r2); } @@ -4344,9 +3627,6 @@ s390_emit_LNDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LNXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lnxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3410000, r1, r2); } @@ -4354,9 +3634,6 @@ s390_emit_LNXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LPEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lpebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3000000, r1, r2); } @@ -4364,9 +3641,6 @@ s390_emit_LPEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LPDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lpdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3100000, r1, r2); } @@ -4374,9 +3648,6 @@ s390_emit_LPDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_LPXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lpxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3400000, r1, r2); } @@ -4385,10 +3656,6 @@ static UChar * s390_emit_LEDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("ledbra", fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3440000, m3, m4, r1, r2); } @@ -4398,10 +3665,6 @@ static UChar * s390_emit_LDXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("ldxbra", fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3450000, m3, m4, r1, r2); } @@ -4411,10 +3674,6 @@ static UChar * s390_emit_LEXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("lexbra", fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3460000, m3, m4, r1, r2); } @@ -4423,11 +3682,6 @@ s390_emit_LEXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_FIEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("fiebra", fp_convt_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF2(p, 0xb3570000, m3, m4, r1, r2); } @@ -4435,11 +3689,6 @@ s390_emit_FIEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_FIDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("fidbra", fp_convt_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF2(p, 0xb35f0000, m3, m4, r1, r2); } @@ -4447,11 +3696,6 @@ s390_emit_FIDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_FIXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("fixbra", fp_convt_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); - return emit_RRF2(p, 0xb3470000, m3, m4, r1, r2); } @@ -4459,9 +3703,6 @@ s390_emit_FIXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_MEEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("meebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3170000, r1, r2); } @@ -4469,9 +3710,6 @@ s390_emit_MEEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb31c0000, r1, r2); } @@ -4479,9 +3717,6 @@ s390_emit_MDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("mxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb34c0000, r1, r2); } @@ -4489,9 +3724,6 @@ s390_emit_MXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_MAEBR(UChar *p, UChar r1, UChar r3, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("maebr"), FPR(r1), FPR(r3), FPR(r2)); - return emit_RRF(p, 0xb30e0000, r1, r3, r2); } @@ -4499,9 +3731,6 @@ s390_emit_MAEBR(UChar *p, UChar r1, UChar r3, UChar r2) static UChar * s390_emit_MADBR(UChar *p, UChar r1, UChar r3, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("madbr"), FPR(r1), FPR(r3), FPR(r2)); - return emit_RRF(p, 0xb31e0000, r1, r3, r2); } @@ -4509,9 +3738,6 @@ s390_emit_MADBR(UChar *p, UChar r1, UChar r3, UChar r2) static UChar * s390_emit_MSEBR(UChar *p, UChar r1, UChar r3, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msebr"), FPR(r1), FPR(r3), FPR(r2)); - return emit_RRF(p, 0xb30f0000, r1, r3, r2); } @@ -4519,9 +3745,6 @@ s390_emit_MSEBR(UChar *p, UChar r1, UChar r3, UChar r2) static UChar * s390_emit_MSDBR(UChar *p, UChar r1, UChar r3, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("msdbr"), FPR(r1), FPR(r3), FPR(r2)); - return emit_RRF(p, 0xb31f0000, r1, r3, r2); } @@ -4529,9 +3752,6 @@ s390_emit_MSDBR(UChar *p, UChar r1, UChar r3, UChar r2) static UChar * s390_emit_SQEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sqebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3140000, r1, r2); } @@ -4539,9 +3759,6 @@ s390_emit_SQEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SQDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sqdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3150000, r1, r2); } @@ -4549,9 +3766,6 @@ s390_emit_SQDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SQXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sqxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3160000, r1, r2); } @@ -4559,9 +3773,6 @@ s390_emit_SQXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SEBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sebr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb30b0000, r1, r2); } @@ -4569,9 +3780,6 @@ s390_emit_SEBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SDBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sdbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb31b0000, r1, r2); } @@ -4579,9 +3787,6 @@ s390_emit_SDBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_SXBR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sxbr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb34b0000, r1, r2); } @@ -4589,11 +3794,6 @@ s390_emit_SXBR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_ADTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("adtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d20000, r3, m4, r1, r2); } @@ -4601,11 +3801,6 @@ s390_emit_ADTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_AXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("axtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3da0000, r3, m4, r1, r2); } @@ -4613,10 +3808,6 @@ s390_emit_AXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CDTR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cdtr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3e40000, r1, r2); } @@ -4624,10 +3815,6 @@ s390_emit_CDTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CXTR(UChar *p, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cxtr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3ec0000, r1, r2); } @@ -4635,12 +3822,7 @@ s390_emit_CXTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CDGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); - vassert(m3 == 0 || s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdgtra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3f10000, m3, m4, r1, r2); } @@ -4649,15 +3831,11 @@ s390_emit_CDGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CXGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); /* rounding mode m3 is not considered, as the corresponding IRop (Iop_I64StoD128) does not take rounding mode. */ vassert(m3 == 0); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxgtra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); - return emit_RRF2(p, 0xb3f90000, m3, m4, r1, r2); } @@ -4666,11 +3844,6 @@ static UChar * s390_emit_CDFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9510000, m3, m4, r1, r2); } @@ -4680,11 +3853,6 @@ static UChar * s390_emit_CXFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9590000, m3, m4, r1, r2); } @@ -4694,11 +3862,6 @@ static UChar * s390_emit_CDLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdlftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9530000, m3, m4, r1, r2); } @@ -4708,11 +3871,6 @@ static UChar * s390_emit_CXLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxlftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb95b0000, m3, m4, r1, r2); } @@ -4722,11 +3880,6 @@ static UChar * s390_emit_CDLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cdlgtr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9520000, m3, m4, r1, r2); } @@ -4736,11 +3889,6 @@ static UChar * s390_emit_CXLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cxlgtr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4)); return emit_RRF2(p, 0xb95a0000, m3, m4, r1, r2); } @@ -4749,9 +3897,6 @@ s390_emit_CXLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CEDTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cedtr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3f40000, r1, r2); } @@ -4759,9 +3904,6 @@ s390_emit_CEDTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_CEXTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("cextr"), FPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3fc0000, r1, r2); } @@ -4770,11 +3912,6 @@ static UChar * s390_emit_CFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cfdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9410000, m3, m4, r1, r2); } @@ -4784,11 +3921,6 @@ static UChar * s390_emit_CFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cfxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9490000, m3, m4, r1, r2); } @@ -4797,12 +3929,7 @@ s390_emit_CFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CGDTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); - vassert(s390_host_has_fpext || m3 < 1 || m3 > 7); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cgdtra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3e10000, m3, m4, r1, r2); } @@ -4811,12 +3938,7 @@ s390_emit_CGDTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_CGXTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); - vassert(s390_host_has_fpext || m3 < 1 || m3 > 7); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("cgxtra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3e90000, m3, m4, r1, r2); } @@ -4826,11 +3948,6 @@ static UChar * s390_emit_CLFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clfdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9430000, m3, m4, r1, r2); } @@ -4840,11 +3957,6 @@ static UChar * s390_emit_CLFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clfxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb94b0000, m3, m4, r1, r2); } @@ -4854,11 +3966,6 @@ static UChar * s390_emit_CLGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clgdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb9420000, m3, m4, r1, r2); } @@ -4868,11 +3975,6 @@ static UChar * s390_emit_CLGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { vassert(m4 == 0); - vassert(s390_host_has_dfp); - vassert(s390_host_has_fpext); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("clgxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb94a0000, m3, m4, r1, r2); } @@ -4881,11 +3983,6 @@ s390_emit_CLGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_DDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("ddtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d10000, r3, m4, r1, r2); } @@ -4893,11 +3990,6 @@ s390_emit_DDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_DXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("dxtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d90000, r3, m4, r1, r2); } @@ -4905,9 +3997,6 @@ s390_emit_DXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_EEDTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("eedtr"), GPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3e50000, r1, r2); } @@ -4915,9 +4004,6 @@ s390_emit_EEDTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_EEXTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("eextr"), GPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3ed0000, r1, r2); } @@ -4925,9 +4011,6 @@ s390_emit_EEXTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_ESDTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("esdtr"), GPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3e70000, r1, r2); } @@ -4935,9 +4018,6 @@ s390_emit_ESDTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_ESXTR(UChar *p, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("esxtr"), GPR(r1), FPR(r2)); - return emit_RRE(p, 0xb3ef0000, r1, r2); } @@ -4945,9 +4025,6 @@ s390_emit_ESXTR(UChar *p, UChar r1, UChar r2) static UChar * s390_emit_IEDTR(UChar *p, UChar r3, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iedtr"), FPR(r1), FPR(r3), GPR(r2)); - return emit_RRF(p, 0xb3f60000, r3, r1, r2); } @@ -4955,9 +4032,6 @@ s390_emit_IEDTR(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_IEXTR(UChar *p, UChar r3, UChar r1, UChar r2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("iextr"), FPR(r1), FPR(r3), GPR(r2)); - return emit_RRF(p, 0xb3fe0000, r3, r1, r2); } @@ -4965,10 +4039,6 @@ s390_emit_IEXTR(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_LDETR(UChar *p, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("ldetr"), FPR(r1), FPR(r2), UINT(m4)); - return emit_RRF5(p, 0xb3d40000, m4, r1, r2); } @@ -4976,10 +4046,6 @@ s390_emit_LDETR(UChar *p, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_LXDTR(UChar *p, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("lxdtr"), FPR(r1), FPR(r2), UINT(m4)); - return emit_RRF5(p, 0xb3dc0000, m4, r1, r2); } @@ -4987,12 +4053,7 @@ s390_emit_LXDTR(UChar *p, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_LEDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); - vassert(s390_host_has_fpext || m3 < 1 || m3 > 7); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("ledtr", fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3d50000, m3, m4, r1, r2); } @@ -5001,12 +4062,7 @@ s390_emit_LEDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_LDXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); vassert(m4 == 0); - vassert(s390_host_has_fpext || m3 < 1 || m3 > 7); - - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("ldxtr", fp_convf_disasm), FPR(r1), MASK(m3), FPR(r2), MASK(m4)); return emit_RRF2(p, 0xb3dd0000, m3, m4, r1, r2); } @@ -5015,11 +4071,6 @@ s390_emit_LDXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_MDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("mdtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d00000, r3, m4, r1, r2); } @@ -5027,11 +4078,6 @@ s390_emit_MDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_MXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("mxtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d80000, r3, m4, r1, r2); } @@ -5048,11 +4094,6 @@ emit_E(UChar *p, UInt op) static UChar * s390_emit_PFPO(UChar *p) { - vassert(s390_host_has_pfpo); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) { - S390_DISASM(MNM("pfpo")); - } - return emit_E(p, 0x010a); } @@ -5060,10 +4101,6 @@ s390_emit_PFPO(UChar *p) static UChar * s390_emit_QADTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("qadtr"), FPR(r1), FPR(r3), FPR(r2), UINT(m4)); - return emit_RRF4(p, 0xb3f50000, r3, m4, r1, r2); } @@ -5071,10 +4108,6 @@ s390_emit_QADTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_QAXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("qaxtr"), FPR(r1), FPR(r3), FPR(r2), UINT(m4)); - return emit_RRF4(p, 0xb3fd0000, r3, m4, r1, r2); } @@ -5082,10 +4115,6 @@ s390_emit_QAXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_RRDTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("rrdtr"), FPR(r1), FPR(r3), GPR(r2), UINT(m4)); - return emit_RRF4(p, 0xb3f70000, r3, m4, r1, r2); } @@ -5093,10 +4122,6 @@ s390_emit_RRDTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_RRXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("rrxtr"), FPR(r1), FPR(r3), GPR(r2), UINT(m4)); - return emit_RRF4(p, 0xb3ff0000, r3, m4, r1, r2); } @@ -5104,11 +4129,6 @@ s390_emit_RRXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("sdtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3d30000, r3, m4, r1, r2); } @@ -5116,11 +4136,6 @@ s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_SXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - vassert(m4 == 0 || s390_host_has_fpext); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("sxtra", adtra_like_disasm), FPR(r1), FPR(r2), FPR(r3), MASK(m4)); - return emit_RRF4(p, 0xb3db0000, r3, m4, r1, r2); } @@ -5128,10 +4143,6 @@ s390_emit_SXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2) static UChar * s390_emit_SLDT(UChar *p, UChar r3, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("sldt"), FPR(r1), FPR(r3), UDXB(0, 0, r2)); - return emit_RXF(p, 0xED0000000040ULL, r3, 0, r2, 0, r1); } @@ -5139,10 +4150,6 @@ s390_emit_SLDT(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_SLXT(UChar *p, UChar r3, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("slxt"), FPR(r1), FPR(r3), UDXB(0, 0, r2)); - return emit_RXF(p, 0xED0000000048ULL, r3, 0, r2, 0, r1); } @@ -5150,10 +4157,6 @@ s390_emit_SLXT(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_SRDT(UChar *p, UChar r3, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("srdt"), FPR(r1), FPR(r3), UDXB(0, 0, r2)); - return emit_RXF(p, 0xED0000000041ULL, r3, 0, r2, 0, r1); } @@ -5161,10 +4164,6 @@ s390_emit_SRDT(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_SRXT(UChar *p, UChar r3, UChar r1, UChar r2) { - vassert(s390_host_has_dfp); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("srxt"), FPR(r1), FPR(r3), UDXB(0, 0, r2)); - return emit_RXF(p, 0xED0000000049ULL, r3, 0, r2, 0, r1); } @@ -5172,10 +4171,6 @@ s390_emit_SRXT(UChar *p, UChar r3, UChar r1, UChar r2) static UChar * s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2) { - vassert(s390_host_has_lsc); - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("locgr", cls_disasm), GPR(r1), GPR(r2), MASK(m3)); - return emit_RRF3(p, 0xb9e20000, m3, r1, r2); } @@ -5183,9 +4178,6 @@ s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2) static UChar * s390_emit_LOC(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("loc", cls_disasm), GPR(r1), SDXB(dh2, dl2, 0, b2), MASK(m3)); - return emit_RSY(p, 0xeb00000000f2ULL, r1, m3, b2, dl2, dh2); } @@ -5193,534 +4185,154 @@ s390_emit_LOC(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) static UChar * s390_emit_LOCG(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("locg", cls_disasm), GPR(r1), SDXB(dh2, dl2, 0, b2), MASK(m3)); - return emit_RSY(p, 0xeb00000000e2ULL, r1, m3, b2, dl2, dh2); } static UChar * s390_emit_LOCGHI(UChar *p, UChar r1, UShort i2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("locghi", cls_disasm), GPR(r1), INT((Int)(Short)i2), MASK(m3)); - return emit_RIE(p, 0xec0000000046ULL, r1, i2, m3); } static UChar * s390_emit_RISBG(UChar *p, UChar r1, UChar r2, UChar i3, Char i4, UChar i5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("risbg", rotate_disasm), GPR(r1), GPR(r2), MASK(i3), MASK(i4), MASK(i5)); - return emit_RIEf(p, 0xec0000000055ULL, r1, r2, i3, i4, i5); } - -/* Provide a symbolic name for register "R0" */ -#define R0 0 - -/* Split up a 20-bit displacement into its high and low piece - suitable for passing as function arguments */ -#define DISP20(d) (((UInt)d) & 0xFFF), ((((UInt)d) >> 12) & 0xFF) - -/*---------------------------------------------------------------*/ -/*--- Helper functions ---*/ -/*---------------------------------------------------------------*/ - -static __inline__ Bool -uint_fits_signed_16bit(UInt val) -{ - UInt v = val & 0xFFFFu; - - /* sign extend */ - v = (Int)(v << 16) >> 16; - - return val == v; -} - - -static __inline__ Bool -ulong_fits_signed_16bit(ULong val) -{ - ULong v = val & 0xFFFFu; - - /* sign extend */ - v = (Long)(v << 48) >> 48; - - return val == v; -} - - -static __inline__ Bool -ulong_fits_signed_32bit(ULong val) -{ - ULong v = val & 0xFFFFFFFFu; - - /* sign extend */ - v = (Long)(v << 32) >> 32; - - return val == v; -} - - -static __inline__ Bool -ulong_fits_unsigned_32bit(ULong val) -{ - return (val & 0xFFFFFFFFu) == val; -} - - -/* Load a 64-bit immediate VAL into register REG. */ -static UChar * -s390_emit_load_64imm(UChar *p, UChar reg, ULong val) -{ - if (ulong_fits_signed_16bit(val)) { - return s390_emit_LGHI(p, reg, val); - } - - if (s390_host_has_eimm) { - if (ulong_fits_unsigned_32bit(val)) { - return s390_emit_LLILF(p, reg, val); - } - if (ulong_fits_signed_32bit(val)) { - /* LGFI's sign extension will recreate the correct 64-bit value */ - return s390_emit_LGFI(p, reg, val); - } - /* Do it in two steps: upper half [0:31] and lower half [32:63] */ - p = s390_emit_IIHF(p, reg, val >> 32); - return s390_emit_IILF(p, reg, val & 0xFFFFFFFF); - } - - /* Fall back */ - if (ulong_fits_unsigned_32bit(val)) { - p = s390_emit_LLILH(p, reg, (val >> 16) & 0xFFFF); /* sets val[32:47] - val[0:31] = 0 */ - p = s390_emit_IILL(p, reg, val & 0xFFFF); /* sets val[48:63] */ - return p; - } - - p = s390_emit_IIHH(p, reg, (val >> 48) & 0xFFFF); - p = s390_emit_IIHL(p, reg, (val >> 32) & 0xFFFF); - p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF); - p = s390_emit_IILL(p, reg, val & 0xFFFF); - - return p; -} - -/* Load a 32-bit immediate VAL into register REG. */ -static UChar * -s390_emit_load_32imm(UChar *p, UChar reg, UInt val) -{ - if (uint_fits_signed_16bit(val)) { - /* LHI's sign extension will recreate the correct 32-bit value */ - return s390_emit_LHI(p, reg, val); - } - if (s390_host_has_eimm) { - return s390_emit_IILF(p, reg, val); - } - /* val[0:15] --> (val >> 16) & 0xFFFF - val[16:31] --> val & 0xFFFF */ - p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF); - return s390_emit_IILL(p, reg, val & 0xFFFF); -} - -/*------------------------------------------------------------*/ -/*--- Wrapper functions ---*/ -/*------------------------------------------------------------*/ - -/* r1[32:63],r1+1[32:63] = r1+1[32:63] * memory[op2addr][0:31] */ -static UChar * -s390_emit_MFYw(UChar *p, UChar r1, UChar x, UChar b, UShort dl, UChar dh) -{ - if (s390_host_has_gie) { - return s390_emit_MFY(p, r1, x, b, dl, dh); - } - - /* Load from memory into R0, then MULTIPLY with R1 */ - p = s390_emit_LY(p, R0, x, b, dl, dh); - return s390_emit_MR(p, r1, R0); -} - -/* r1[32:63] = r1[32:63] * memory[op2addr][0:15] */ -static UChar * -s390_emit_MHYw(UChar *p, UChar r1, UChar x, UChar b, UShort dl, UChar dh) -{ - if (s390_host_has_gie) { - return s390_emit_MHY(p, r1, x, b, dl, dh); - } - - /* Load from memory into R0, then MULTIPLY with R1 */ - p = s390_emit_LHY(p, R0, x, b, dl, dh); - return s390_emit_MSR(p, r1, R0); -} - -/* r1[32:63] = r1[32:63] * i2 */ -static UChar * -s390_emit_MSFIw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_gie) { - return s390_emit_MSFI(p, r1, i2); - } - - /* Load I2 into R0; then MULTIPLY R0 with R1 */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_MSR(p, r1, R0); -} - - -/* r1[32:63] = r1[32:63] & i2 */ -static UChar * -s390_emit_NILFw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_NILF(p, r1, i2); - } - - /* Load I2 into R0; then AND R0 with R1 */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_NR(p, r1, R0); -} - - -/* r1[32:63] = r1[32:63] | i2 */ -static UChar * -s390_emit_OILFw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_OILF(p, r1, i2); - } - - /* Load I2 into R0; then AND R0 with R1 */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_OR(p, r1, R0); -} - - -/* r1[32:63] = r1[32:63] ^ i2 */ -static UChar * -s390_emit_XILFw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_XILF(p, r1, i2); - } - - /* Load I2 into R0; then AND R0 with R1 */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_XR(p, r1, R0); -} - - -/* r1[32:63] = sign_extend(r2[56:63]) */ -static UChar * -s390_emit_LBRw(UChar *p, UChar r1, UChar r2) -{ - if (s390_host_has_eimm) { - return s390_emit_LBR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); /* r1 = r2 */ - p = s390_emit_SLL(p, r1, R0, 24); /* r1 = r1 << 24 */ - return s390_emit_SRA(p, r1, R0, 24); /* r1 = r1 >>a 24 */ -} - - -/* r1[0:63] = sign_extend(r2[56:63]) */ -static UChar * -s390_emit_LGBRw(UChar *p, UChar r1, UChar r2) -{ - if (s390_host_has_eimm) { - return s390_emit_LGBR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); /* r1 = r2 */ - p = s390_emit_SLLG(p, r1, r1, R0, DISP20(56)); /* r1 = r1 << 56 */ - return s390_emit_SRAG(p, r1, r1, R0, DISP20(56)); /* r1 = r1 >>a 56 */ -} - - -/* r1[32:63] = sign_extend(r2[48:63]) */ -static UChar * -s390_emit_LHRw(UChar *p, UChar r1, UChar r2) -{ - if (s390_host_has_eimm) { - return s390_emit_LHR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); /* r1 = r2 */ - p = s390_emit_SLL(p, r1, R0, 16); /* r1 = r1 << 16 */ - return s390_emit_SRA(p, r1, R0, 16); /* r1 = r1 >>a 16 */ -} - - -/* r1[0:63] = sign_extend(r2[48:63]) */ -static UChar * -s390_emit_LGHRw(UChar *p, UChar r1, UChar r2) -{ - if (s390_host_has_eimm) { - return s390_emit_LGHR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); /* r1 = r2 */ - p = s390_emit_SLLG(p, r1, r1, R0, DISP20(48)); /* r1 = r1 << 48 */ - return s390_emit_SRAG(p, r1, r1, R0, DISP20(48)); /* r1 = r1 >>a 48 */ -} - - -/* r1[0:63] = sign_extend(i2) */ static UChar * -s390_emit_LGFIw(UChar *p, UChar r1, UInt i2) +s390_emit_NCRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LGFI(p, r1, i2); - } - - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_LGFR(p, r1, R0); + return emit_RRF6(p, 0xb9f50000, r1, r2, r3); } - -/* r1[32:63] = zero_extend($r2[56:63]) */ static UChar * -s390_emit_LLCRw(UChar *p, UChar r1, UChar r2) +s390_emit_NCGRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLCR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); - p = s390_emit_LHI(p, R0, 0xFF); - return s390_emit_NR(p, r1, R0); + return emit_RRF6(p, 0xb9e50000, r1, r2, r3); } - -/* r1[0:63] = zero_extend($r2[56:63]) */ static UChar * -s390_emit_LLGCRw(UChar *p, UChar r1, UChar r2) +s390_emit_OCRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLGCR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); - p = s390_emit_LLILL(p, R0, 0xFF); - return s390_emit_NGR(p, r1, R0); + return emit_RRF6(p, 0xb9750000, r1, r2, r3); } - -/* r1[32:63] = zero_extend(r2[48:63]) */ static UChar * -s390_emit_LLHRw(UChar *p, UChar r1, UChar r2) +s390_emit_OCGRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLHR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); - p = s390_emit_LLILL(p, R0, 0xFFFF); - return s390_emit_NR(p, r1, R0); + return emit_RRF6(p, 0xb9650000, r1, r2, r3); } - -/* r1[0:63] = zero_extend(r2[48:63]) */ static UChar * -s390_emit_LLGHRw(UChar *p, UChar r1, UChar r2) +s390_emit_NNRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLGHR(p, r1, r2); - } - - p = s390_emit_LR(p, r1, r2); - p = s390_emit_LLILL(p, R0, 0xFFFF); - return s390_emit_NGR(p, r1, R0); + return emit_RRF6(p, 0xb9740000, r1, r2, r3); } - -/* r1[32:63] = zero_extend(mem[op2addr][0:7]) */ static UChar * -s390_emit_LLCw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh) +s390_emit_NNGRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLC(p, r1, x2, b2, dl, dh); - } - - if (dh == 0) { - p = s390_emit_IC(p, r1, x2, b2, dl); - } else { - p = s390_emit_ICY(p, r1, x2, b2, dl, dh); - } - p = s390_emit_LLILL(p, R0, 0xFF); - return s390_emit_NR(p, r1, R0); + return emit_RRF6(p, 0xb9640000, r1, r2, r3); } - -/* r1[32:63] = zero_extend(mem[op2addr][0:15]) */ static UChar * -s390_emit_LLHw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh) +s390_emit_NORK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLH(p, r1, x2, b2, dl, dh); - } - - p = s390_emit_LLGH(p, r1, x2, b2, dl, dh); - p = s390_emit_LLILL(p, R0, 0xFFFF); - return s390_emit_NR(p, r1, R0); + return emit_RRF6(p, 0xb9760000, r1, r2, r3); } - -/* r1[0:63] = zero_extend(i2) */ static UChar * -s390_emit_LLILFw(UChar *p, UChar r1, UInt i2) +s390_emit_NOGRK(UChar *p, UChar r1, UChar r2, UChar r3) { - if (s390_host_has_eimm) { - return s390_emit_LLILF(p, r1, i2); - } - - p = s390_emit_LLILH(p, r1, (i2 >> 16) & 0xFFFF); /* i2[0:15] */ - return s390_emit_OILL(p, r1, i2 & 0xFFFF); + return emit_RRF6(p, 0xb9660000, r1, r2, r3); } -/* r1[32:63] = r1[32:63] + i2 */ -static UChar * -s390_emit_AFIw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_AFI(p, r1, i2); - } - /* Load 32 bit immediate to R0 then add */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_AR(p, r1, R0); -} - - -/* r1[32:63] = r1[32:63] - i2 */ -static UChar * -s390_emit_SLFIw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_SLFI(p, r1, i2); - } - - /* Load 32 bit immediate to R0 then subtract */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_SR(p, r1, R0); -} - - -/* r1[0:63] = r1[0:63] - zero_extend(i2) */ -static UChar * -s390_emit_SLGFIw(UChar *p, UChar r1, UInt i2) -{ - if (s390_host_has_eimm) { - return s390_emit_SLGFI(p, r1, i2); - } +/* Provide a symbolic name for register "R0" */ +#define R0 0 - /* Load zero-extended 32 bit immediate to R0 then subtract */ - p = s390_emit_load_64imm(p, R0, i2); - return s390_emit_SGR(p, r1, R0); -} +/* Split up a 20-bit displacement into its high and low piece + suitable for passing as function arguments */ +#define DISP20(d) (((UInt)d) & 0xFFF), ((((UInt)d) >> 12) & 0xFF) +/*---------------------------------------------------------------*/ +/*--- Helper functions ---*/ +/*---------------------------------------------------------------*/ -static UChar * -s390_emit_LTw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh) +static __inline__ Bool +uint_fits_signed_16bit(UInt val) { - if (s390_host_has_eimm) { - return s390_emit_LT(p, r1, x2, b2, dl, dh); - } - /* Load 32 bit from memory to R0 then compare */ - if (dh == 0) { - p = s390_emit_L(p, R0, x2, b2, dl); - } else { - p = s390_emit_LY(p, R0, x2, b2, dl, dh); - } - return s390_emit_LTR(p, r1, R0); + return val + 0x8000 <= 0xFFFF; } -static UChar * -s390_emit_LTGw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh) +static __inline__ Bool +ulong_fits_signed_16bit(ULong val) { - if (s390_host_has_eimm) { - return s390_emit_LTG(p, r1, x2, b2, dl, dh); - } - /* Load 64 bit from memory to R0 then compare */ - p = s390_emit_LG(p, R0, x2, b2, dl, dh); - return s390_emit_LTGR(p, r1, R0); + return val + 0x8000 <= 0xFFFF; } -static UChar * -s390_emit_CFIw(UChar *p, UChar r1, UInt i2) +static __inline__ Bool +ulong_fits_signed_32bit(ULong val) { - if (s390_host_has_eimm) { - return s390_emit_CFI(p, r1, i2); - } - /* Load 32 bit immediate to R0 then compare */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_CR(p, r1, R0); + return val + 0x80000000 <= 0xFFFFFFFF; } -static UChar * -s390_emit_CLFIw(UChar *p, UChar r1, UInt i2) +static __inline__ Bool +ulong_fits_unsigned_32bit(ULong val) { - if (s390_host_has_eimm) { - return s390_emit_CLFI(p, r1, i2); - } - /* Load 32 bit immediate to R0 then compare */ - p = s390_emit_load_32imm(p, R0, i2); - return s390_emit_CLR(p, r1, R0); + return val <= 0xFFFFFFFFu; } +/* Load a 64-bit immediate VAL into register REG. */ static UChar * -s390_emit_LGDRw(UChar *p, UChar r1, UChar r2) +s390_emit_load_64imm(UChar *p, UChar reg, ULong val) { - if (s390_host_has_fgx) { - return s390_emit_LGDR(p, r1, r2); + if (ulong_fits_signed_16bit(val)) { + return s390_emit_LGHI(p, reg, val); } - /* Store the FPR at memory[sp - 8]. This is safe because SP grows towards - smaller addresses and is 8-byte aligned. Then load the GPR from that - memory location/ */ - p = s390_emit_STDY(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8)); - return s390_emit_LG(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8)); + if (ulong_fits_unsigned_32bit(val)) { + return s390_emit_LLILF(p, reg, val); + } + if (ulong_fits_signed_32bit(val)) { + /* LGFI's sign extension will recreate the correct 64-bit value */ + return s390_emit_LGFI(p, reg, val); + } + /* Do it in two steps: upper half [0:31] and lower half [32:63] */ + p = s390_emit_IIHF(p, reg, val >> 32); + return s390_emit_IILF(p, reg, val & 0xFFFFFFFF); } - +/* Load a 32-bit immediate VAL into register REG. */ static UChar * -s390_emit_LDGRw(UChar *p, UChar r1, UChar r2) +s390_emit_load_32imm(UChar *p, UChar reg, UInt val) { - if (s390_host_has_fgx) { - return s390_emit_LDGR(p, r1, r2); + if (uint_fits_signed_16bit(val)) { + /* LHI's sign extension will recreate the correct 32-bit value */ + return s390_emit_LHI(p, reg, val); } - - /* Store the GPR at memory[sp - 8]. This is safe because SP grows towards - smaller addresses and is 8-byte aligned. Then load the FPR from that - memory location/ */ - p = s390_emit_STG(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8)); - return s390_emit_LDY(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8)); + return s390_emit_IILF(p, reg, val); } +/*------------------------------------------------------------*/ +/*--- Emit functions for vector insns ---*/ +/*------------------------------------------------------------*/ static UChar * s390_emit_VL(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - /* m3 = 0 --> no alignment indicated */ - S390_DISASM(XMNM("vl", mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(0)); - + /* m3 = 0 --> no alignment indicated */ return emit_VRX(p, 0xE70000000006ULL, v1, x2, b2, d2, 0); } static UChar * s390_emit_VLR(UChar *p, UChar v1, UChar v2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlr"), VR(v1), VR(v2)); - return emit_VRR_VV(p, 0xE70000000056ULL, v1, v2); } @@ -5728,9 +4340,6 @@ s390_emit_VLR(UChar *p, UChar v1, UChar v2) static UChar * s390_emit_VLREP(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2, UShort m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlrep"), VR(v1), UDXB(d2, x2, b2), UINT(m3)); - return emit_VRX(p, 0xE70000000005ULL, v1, x2, b2, d2, m3); } @@ -5738,10 +4347,7 @@ s390_emit_VLREP(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2, UShort m3) static UChar * s390_emit_VST(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - /* As the alignment of the 2nd operand is unknown --> m3 = 0 */ - S390_DISASM(XMNM("vst", mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(0)); - + /* As the alignment of the 2nd operand is unknown --> m3 = 0 */ return emit_VRX(p, 0xE7000000000eULL, v1, x2, b2, d2, 0); } @@ -5749,9 +4355,6 @@ s390_emit_VST(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2) static UChar * s390_emit_VLGV(UChar *p, UChar r1, UChar b2, UShort d2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vlgv", va_like_disasm), GPR(r1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); - return emit_VRS(p, 0xE70000000021ULL, r1, b2, d2, v3, m4); } @@ -5759,9 +4362,6 @@ s390_emit_VLGV(UChar *p, UChar r1, UChar b2, UShort d2, UChar v3, UChar m4) static UChar * s390_emit_VLVG(UChar *p, UChar v1, UChar b2, UShort d2, UChar r3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vlvg", va_like_disasm), VR(v1), GPR(r3), UDXB(d2, 0, b2), MASK(m4)); - return emit_VRS(p, 0xE70000000022ULL, v1, b2, d2, r3, m4); } @@ -5769,54 +4369,36 @@ s390_emit_VLVG(UChar *p, UChar v1, UChar b2, UShort d2, UChar r3, UChar m4) static UChar * s390_emit_VPERM(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vperm"), VR(v1), VR(v2), VR(v3), VR(v4)); - return emit_VRR_VVVV(p, 0xE7000000008cULL, v1, v2, v3, v4); } static UChar * s390_emit_VO(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vo"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000006aULL, v1, v2, v3); } static UChar * s390_emit_VOC(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("voc"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000006fULL, v1, v2, v3); } static UChar * s390_emit_VX(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vx"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000006dULL, v1, v2, v3); } static UChar * s390_emit_VN(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vn"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE70000000068ULL, v1, v2, v3); } static UChar* s390_emit_VCEQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vceq", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); - return emit_VRR_VVVM(p, 0xE700000000f8ULL, v1, v2, v3, m4); } @@ -5824,9 +4406,6 @@ s390_emit_VCEQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) static UChar * s390_emit_VGBM(UChar *p, UChar v1, UShort i2) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vgbm", vgbm_disasm), VR(v1), UINT(i2)); - return emit_VRI_VI(p, 0xE70000000044ULL, v1, i2); } @@ -5834,9 +4413,6 @@ s390_emit_VGBM(UChar *p, UChar v1, UShort i2) static UChar * s390_emit_VPK(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vpk", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000094ULL, v1, v2, v3, m4); } @@ -5844,9 +4420,6 @@ s390_emit_VPK(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) static UChar * s390_emit_VPKS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vpks", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); - return emit_VRR_VVVM(p, 0xE70000000097ULL, v1, v2, v3, m4); } @@ -5854,9 +4427,6 @@ s390_emit_VPKS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) static UChar * s390_emit_VPKLS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vpkls", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); - return emit_VRR_VVVM(p, 0xE70000000095ULL, v1, v2, v3, m4); } @@ -5864,9 +4434,6 @@ s390_emit_VPKLS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) static UChar * s390_emit_VREP(UChar *p, UChar v1, UChar v3, UShort i2, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vrep", va_like_disasm), VR(v1), VR(v3), UINT(i2), MASK(m4)); - return emit_VRI_VVMM(p, 0xE7000000004DULL, v1, v3, i2, m4); } @@ -5874,9 +4441,6 @@ s390_emit_VREP(UChar *p, UChar v1, UChar v3, UShort i2, UChar m4) static UChar * s390_emit_VREPI(UChar *p, UChar v1, UShort i2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vrepi", va_like_disasm), VR(v1), INT((Short)i2), MASK(m3)); - return emit_VRI_VIM(p, 0xE70000000045ULL, v1, i2, m3); } @@ -5884,9 +4448,6 @@ s390_emit_VREPI(UChar *p, UChar v1, UShort i2, UChar m3) static UChar * s390_emit_VUPH(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vuph", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE700000000D7ULL, v1, v2, m3); } @@ -5894,9 +4455,6 @@ s390_emit_VUPH(UChar *p, UChar v1, UChar v2, UChar m3) static UChar * s390_emit_VUPLH(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vuplh", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE700000000D5ULL, v1, v2, m3); } @@ -5904,9 +4462,6 @@ s390_emit_VUPLH(UChar *p, UChar v1, UChar v2, UChar m3) static UChar* s390_emit_VMRH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmrh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000061ULL, v1, v2, v3, m4); } @@ -5914,396 +4469,288 @@ s390_emit_VMRH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) static UChar* s390_emit_VMRL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmrl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000060ULL, v1, v2, v3, m4); } static UChar * s390_emit_VA(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("va", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000f3ULL, v1, v2, v3, m4); } static UChar * s390_emit_VS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vs", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000f7ULL, v1, v2, v3, m4); } static UChar * s390_emit_VNO(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vno"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000006bULL, v1, v2, v3); } static UChar * s390_emit_VCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vch", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); - return emit_VRR_VVVM(p, 0xE700000000fbULL, v1, v2, v3, m4); } static UChar * s390_emit_VCHL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vchl", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); - return emit_VRR_VVVM(p, 0xE700000000f9ULL, v1, v2, v3, m4); } static UChar * s390_emit_VCLZ(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vclz", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE70000000053ULL, v1, v2, m3); } static UChar * s390_emit_VCTZ(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vctz", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE70000000052ULL, v1, v2, m3); } static UChar * s390_emit_VPOPCT(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vpopct", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE70000000050ULL, v1, v2, m3); } static UChar * s390_emit_VMX(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmx", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000ffULL, v1, v2, v3, m4); } static UChar * s390_emit_VMXL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmxl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000fdULL, v1, v2, v3, m4); } static UChar * s390_emit_VMN(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmn", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000feULL, v1, v2, v3, m4); } static UChar * s390_emit_VMNL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmnl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000fcULL, v1, v2, v3, m4); } static UChar * s390_emit_VAVG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vavg", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000f2ULL, v1, v2, v3, m4); } static UChar * s390_emit_VAVGL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vavgl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000f0ULL, v1, v2, v3, m4); } static UChar * s390_emit_VLP(UChar *p, UChar v1, UChar v2, UChar m3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vlp", va_like_disasm), VR(v1), VR(v2), MASK(m3)); - return emit_VRR_VVM(p, 0xE700000000DFULL, v1, v2, m3); } static UChar * s390_emit_VMH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a3ULL, v1, v2, v3, m4); } static UChar * s390_emit_VMLH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmlh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a1ULL, v1, v2, v3, m4); } static UChar * s390_emit_VML(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vml", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a2ULL, v1, v2, v3, m4); } static UChar * s390_emit_VMO(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmo", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a7ULL, v1, v2, v3, m4); } static UChar * s390_emit_VMLO(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmlo", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a5ULL, v1, v2, v3, m4); } static UChar * -s390_emit_VESLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) +s390_emit_VD(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +{ + return emit_VRR_VVVMM(p, 0xE700000000b2ULL, v1, v2, v3, m4, m5); +} + +static UChar * +s390_emit_VDL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +{ + return emit_VRR_VVVMM(p, 0xE700000000b0ULL, v1, v2, v3, m4, m5); +} + +static UChar * +s390_emit_VR(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) +{ + return emit_VRR_VVVMM(p, 0xE700000000b3ULL, v1, v2, v3, m4, m5); +} + +static UChar * +s390_emit_VRL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("veslv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); + return emit_VRR_VVVMM(p, 0xE700000000b1ULL, v1, v2, v3, m4, m5); +} +static UChar * +s390_emit_VESLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) +{ return emit_VRR_VVVM(p, 0xE70000000070ULL, v1, v2, v3, m4); } static UChar * s390_emit_VESRAV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vesrav", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE7000000007aULL, v1, v2, v3, m4); } static UChar * s390_emit_VESRLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vesrlv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000078ULL, v1, v2, v3, m4); } static UChar * s390_emit_VESL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vesl", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); - return emit_VRS(p, 0xE70000000030ULL, v1, b2, d2, v3, m4); } static UChar * s390_emit_VESRA(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vesra", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); - return emit_VRS(p, 0xE7000000003aULL, v1, b2, d2, v3, m4); } static UChar * s390_emit_VESRL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vesrl", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); - return emit_VRS(p, 0xE70000000038ULL, v1, b2, d2, v3, m4); } static UChar * s390_emit_VERLLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("verllv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000073ULL, v1, v2, v3, m4); } static UChar * s390_emit_VSL(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsl"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE70000000074ULL, v1, v2, v3); } static UChar * s390_emit_VSRL(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsrl"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000007cULL, v1, v2, v3); } static UChar * s390_emit_VSRA(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsra"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000007eULL, v1, v2, v3); } static UChar * s390_emit_VSLB(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vslb"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE70000000075ULL, v1, v2, v3); } static UChar * s390_emit_VSRLB(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsrlb"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000007dULL, v1, v2, v3); } static UChar * s390_emit_VSRAB(UChar *p, UChar v1, UChar v2, UChar v3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsrab"), VR(v1), VR(v2), VR(v3)); - return emit_VRR_VVV(p, 0xE7000000007fULL, v1, v2, v3); } static UChar * s390_emit_VSUM(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vsum", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000064ULL, v1, v2, v3, m4); } static UChar * s390_emit_VSUMG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vsumg", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000065ULL, v1, v2, v3, m4); } static UChar * s390_emit_VSUMQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vsumq", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE70000000067ULL, v1, v2, v3, m4); } static UChar * s390_emit_VLVGP(UChar *p, UChar v1, UChar r2, UChar r3) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlvgp"), VR(v1), GPR(r2), GPR(r3)); - return emit_VRR_VRR(p, 0xE70000000062ULL, v1, r2, r3); } static UChar * s390_emit_VFPSO(UChar *p, UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfpso"), VR(v1), VR(v2), UINT(m3), UINT(m4), UINT(m5)); - return emit_VRR_VVMMM(p, 0xE700000000CCULL, v1, v2, m3, m4, m5); } static UChar * s390_emit_VFA(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfa"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); - return emit_VRR_VVVMM(p, 0xE700000000e3ULL, v1, v2, v3, m4, m5); } static UChar * s390_emit_VFS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfs"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); - return emit_VRR_VVVMM(p, 0xE700000000e2ULL, v1, v2, v3, m4, m5); } static UChar * s390_emit_VFM(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfm"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); - return emit_VRR_VVVMM(p, 0xE700000000e7ULL, v1, v2, v3, m4, m5); } static UChar * s390_emit_VFD(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfd"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); - return emit_VRR_VVVMM(p, 0xE700000000e5ULL, v1, v2, v3, m4, m5); } static UChar * s390_emit_VFSQ(UChar *p, UChar v1, UChar v2, UChar m3, UChar m4) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfsq"), VR(v1), VR(v2), UINT(m3), UINT(m4)); - return emit_VRR_VVMMM(p, 0xE700000000CEULL, v1, v2, m3, m4, 0); } @@ -6311,9 +4758,6 @@ static UChar * s390_emit_VFMA(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vfma", vfms_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); - return emit_VRRe_VVVVMM(p, 0xE7000000008fULL, v1, v2, v3, v4, m5, m6); } @@ -6321,9 +4765,6 @@ static UChar * s390_emit_VFMS(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vfms", vfms_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); - return emit_VRRe_VVVVMM(p, 0xE7000000008eULL, v1, v2, v3, v4, m5, m6); } @@ -6331,9 +4772,6 @@ static UChar * s390_emit_VFCE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vfce", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); - return emit_VRR_VVVMMM(p, 0xE700000000e8ULL, v1, v2, v3, m4, m5, m6); } @@ -6341,9 +4779,6 @@ static UChar * s390_emit_VFCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vfch", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); - return emit_VRR_VVVMMM(p, 0xE700000000ebULL, v1, v2, v3, m4, m5, m6); } @@ -6351,9 +4786,6 @@ static UChar * s390_emit_VFCHE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { - if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vfche", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); - return emit_VRR_VVVMMM(p, 0xE700000000eaULL, v1, v2, v3, m4, m5, m6); } @@ -6476,6 +4908,24 @@ s390_insn_alu(UChar size, s390_alu_t tag, HReg dst, s390_opnd_RMI op2) } +s390_insn * +s390_insn_alu3(UChar size, s390_alu3_t tag, HReg dst, HReg op1, HReg op2) +{ + s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); + + vassert(size == 4 || size == 8); + + insn->tag = S390_INSN_ALU3; + insn->size = size; + insn->variant.alu3.tag = tag; + insn->variant.alu3.dst = dst; + insn->variant.alu3.op1 = op1; + insn->variant.alu3.op2 = op2; + + return insn; +} + + s390_insn * s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo, s390_opnd_RMI op2, Bool signed_multiply) @@ -7313,8 +5763,6 @@ s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value) /* This insn will be mapped to an ASI or AGSI so we can only allow base register plus 12-bit / 20-bit displacement. */ vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20); - /* ASI and AGSI require the GIE facility */ - vassert(s390_host_has_gie); insn->tag = S390_INSN_MADD; insn->size = size; @@ -7446,7 +5894,7 @@ s390_insn_profinc(void) s390_insn * s390_insn_vec_amodeop(UChar size, s390_vec_amodeop_t tag, HReg dst, HReg op1, - s390_amode *op2) + s390_amode *op2) { s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); @@ -7462,8 +5910,9 @@ s390_insn_vec_amodeop(UChar size, s390_vec_amodeop_t tag, HReg dst, HReg op1, return insn; } -s390_insn *s390_insn_vec_amodeintop(UChar size, s390_vec_amodeintop_t tag, HReg dst, - s390_amode* op2, HReg op3) +s390_insn * +s390_insn_vec_amodeintop(UChar size, s390_vec_amodeintop_t tag, HReg dst, + s390_amode* op2, HReg op3) { s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); @@ -7479,8 +5928,9 @@ s390_insn *s390_insn_vec_amodeintop(UChar size, s390_vec_amodeintop_t tag, HReg return insn; } -s390_insn *s390_insn_vec_binop(UChar size, s390_vec_binop_t tag, HReg dst, - HReg op1, HReg op2) +s390_insn * +s390_insn_vec_binop(UChar size, s390_vec_binop_t tag, HReg dst, + HReg op1, HReg op2) { s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); @@ -7496,8 +5946,9 @@ s390_insn *s390_insn_vec_binop(UChar size, s390_vec_binop_t tag, HReg dst, return insn; } -s390_insn *s390_insn_vec_triop(UChar size, s390_vec_triop_t tag, HReg dst, - HReg op1, HReg op2, HReg op3) +s390_insn * +s390_insn_vec_triop(UChar size, s390_vec_triop_t tag, HReg dst, + HReg op1, HReg op2, HReg op3) { s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); @@ -7513,8 +5964,8 @@ s390_insn *s390_insn_vec_triop(UChar size, s390_vec_triop_t tag, HReg dst, return insn; } -s390_insn *s390_insn_vec_replicate(UChar size, HReg dst, HReg op1, - UChar idx) +s390_insn * +s390_insn_vec_replicate(UChar size, HReg dst, HReg op1, UChar idx) { s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn)); @@ -7531,6 +5982,110 @@ s390_insn *s390_insn_vec_replicate(UChar size, HReg dst, HReg op1, /*--- Debug print ---*/ /*---------------------------------------------------------------*/ +/* Convenience macro to test whether OFFSET lies within the interval + [FROM, TO] */ +#define in_range(offset, from, to) \ + ((offset) >= S390X_GUEST_OFFSET(from) && \ + (offset) <= S390X_GUEST_OFFSET(to)) + +static const HChar * +s390_guest_regname_WRK(UInt offset, const HChar *prefix) +{ + static HChar buf[30]; /* large enough */ + UInt regno; + + vassert(vex_strlen(prefix) < 10); /* precaution against buffer overflow */ + + if (vex_streq(prefix, "spill")) { + vex_sprintf(buf, "%s_%u", prefix, offset); + } else if (in_range(offset, guest_a0, guest_a15)) { + regno = (offset - S390X_GUEST_OFFSET(guest_a0)) / 4; + vex_sprintf(buf, "%s_a%u", prefix, regno); + } else if (in_range(offset, guest_r0, guest_r15)) { + regno = (offset - S390X_GUEST_OFFSET(guest_r0)) / 8; + vex_sprintf(buf, "%s_r%u", prefix, regno); + } else if (in_range(offset, guest_v0, guest_v31)) { + regno = (offset - S390X_GUEST_OFFSET(guest_v0)) / 16; + vex_sprintf(buf, "%s_v%u", prefix, regno); + } else if (vex_streq(prefix, "spill")) { + vex_sprintf(buf, "%s_%u", prefix, offset); + } else { + +#define NUM_SPECIAL_REGS (sizeof special_regs / sizeof special_regs[0]) +#define SPECIAL_REG_NAME(prefix,name) #name +#define SPECIAL_REG_OFFSET(prefix,name) S390X_GUEST_OFFSET(prefix##_##name) +#define SPECIAL_REG_NBYTES(prefix,name) (sizeof((VexGuestS390XState *)0)->prefix##_##name) + +#define SPECIAL_REG(prefix,name) \ + SPECIAL_REG_NAME(prefix, name), \ + SPECIAL_REG_OFFSET(prefix, name), \ + SPECIAL_REG_NBYTES(prefix, name) + static const struct { + const HChar *name; + const UInt offset; + const UInt nbytes; + } special_regs[] = { + { SPECIAL_REG(guest, counter) }, + { SPECIAL_REG(guest, fpc) }, + { SPECIAL_REG(guest, IA) }, + { SPECIAL_REG(guest, SYSNO) }, + { SPECIAL_REG(guest, CC_OP) }, + { SPECIAL_REG(guest, CC_DEP1) }, + { SPECIAL_REG(guest, CC_DEP2) }, + { SPECIAL_REG(guest, CC_NDEP) }, + { SPECIAL_REG(guest, NRADDR) }, + { SPECIAL_REG(guest, CMSTART) }, + { SPECIAL_REG(guest, CMLEN) }, + { SPECIAL_REG(guest, EMNOTE) }, + { SPECIAL_REG(host, EvC_COUNTER) }, + { SPECIAL_REG(host, EvC_FAILADDR) }, + }; + + Int found = 0; + for (UInt i = 0; i < NUM_SPECIAL_REGS; ++i) { + if (offset >= special_regs[i].offset && + offset < special_regs[i].offset + special_regs[i].nbytes ) { + vex_sprintf(buf, "%s_%s", prefix, special_regs[i].name); + found = 1; + break; + } + } + if (! found) + vex_sprintf(buf, "%s_%u ???", prefix, offset); + } + + return buf; +} + + +/* Construct a symbolic name for a guest register. The name is constructed + in a static array which will be overwritten on every invocation. You + have been warned. */ +static const HChar * +s390_guest_regname(UInt offset) +{ + if (offset < sizeof(VexGuestS390XState)) + return s390_guest_regname_WRK(offset, "guest"); + + if (offset >= sizeof(VexGuestS390XState) && + offset < 2*sizeof(VexGuestS390XState)) { + offset -= sizeof(VexGuestS390XState); + return s390_guest_regname_WRK(offset, "shadow1"); + } + if (offset >= 2*sizeof(VexGuestS390XState) && + offset < 3*sizeof(VexGuestS390XState)) { + offset -= 2*sizeof(VexGuestS390XState); + return s390_guest_regname_WRK(offset, "shadow2"); + } + if (offset >= 3*sizeof(VexGuestS390XState) && + offset < 3*sizeof(VexGuestS390XState) + LibVEX_N_SPILL_BYTES) { + offset -= 3*sizeof(VexGuestS390XState); + return s390_guest_regname_WRK(offset, "spill"); + } + vpanic("s390_guest_regname"); +} + + static const HChar * s390_cc_as_string(s390_cc_t cc) { @@ -7753,6 +6308,18 @@ s390_insn_as_string(const s390_insn *insn) &insn->variant.alu.op2); break; + case S390_INSN_ALU3: + switch (insn->variant.alu3.tag) { + case S390_ALU3_ANDC: op = "v-andc"; break; + case S390_ALU3_ORC: op = "v-orc"; break; + case S390_ALU3_NAND: op = "v-nand"; break; + case S390_ALU3_NOR: op = "v-nor"; break; + default: goto fail; + } + s390_sprintf(buf, "%M %R,%R,%R", op, insn->variant.alu3.dst, + insn->variant.alu3.op1, insn->variant.alu3.op2); + break; + case S390_INSN_SMUL: case S390_INSN_UMUL: if (insn->tag == S390_INSN_SMUL) { @@ -7784,6 +6351,7 @@ s390_insn_as_string(const s390_insn *insn) s390_sprintf(buf, "%M %R,%O", "v-clz", insn->variant.clz.num_bits, &insn->variant.clz.src); break; + break; case S390_INSN_UNOP: switch (insn->variant.unop.tag) { @@ -7799,10 +6367,18 @@ s390_insn_as_string(const s390_insn *insn) op = "v-signx"; break; + case S390_LOAD_ADDRESS: + op = "v-laddr"; + break; + case S390_NEGATE: op = "v-neg"; break; + case S390_POPCNT: + op = "v-popcnt"; + break; + case S390_VEC_FILL: op = "v-vfill"; break; @@ -8210,6 +6786,10 @@ s390_insn_as_string(const s390_insn *insn) case S390_VEC_INT_MUL_LOW: op = "v-vintmullo"; break; case S390_VEC_INT_MUL_ODDS: op = "v-vintmulodds"; break; case S390_VEC_INT_MUL_ODDU: op = "v-vintmuloddu"; break; + case S390_VEC_INT_DIVU: op = "v-vintdivu"; break; + case S390_VEC_INT_DIVS: op = "v-vintdivs"; break; + case S390_VEC_INT_MODU: op = "v-vintmodu"; break; + case S390_VEC_INT_MODS: op = "v-vintmods"; break; case S390_VEC_ELEM_SHL_V: op = "v-velemshl"; break; case S390_VEC_ELEM_SHRA_V: op = "v-vshrav"; break; case S390_VEC_ELEM_SHRL_V: op = "v-vshrlv"; break; @@ -8441,7 +7021,7 @@ static UChar * s390_emit_load_cc(UChar *p, UChar reg) { p = s390_emit_LGHI(p, reg, 0); /* Clear out, cc not affected */ - p = s390_emit_IPM(p, reg, reg); + p = s390_emit_IPM(p, reg); /* Shift 28 bits to the right --> [0,1,2,3] */ return s390_emit_SRL(p, reg, 0, 28); /* REG = cc */ } @@ -8628,17 +7208,17 @@ s390_insn_move_emit(UChar *buf, const s390_insn *insn) if (dst_class == HRcFlt64 && src_class == HRcInt64) { if (insn->size == 4) { buf = s390_emit_SLLG(buf, R0, src, 0, DISP20(32)); /* r0 = src << 32 */ - return s390_emit_LDGRw(buf, dst, R0); + return s390_emit_LDGR(buf, dst, R0); } else { - return s390_emit_LDGRw(buf, dst, src); + return s390_emit_LDGR(buf, dst, src); } } if (dst_class == HRcInt64 && src_class == HRcFlt64) { if (insn->size == 4) { - buf = s390_emit_LGDRw(buf, dst, src); + buf = s390_emit_LGDR(buf, dst, src); return s390_emit_SRLG(buf, dst, dst, 0, DISP20(32)); /* dst >>= 32 */ } else { - return s390_emit_LGDRw(buf, dst, src); + return s390_emit_LGDR(buf, dst, src); } } if (dst_class == HRcFlt64 && src_class == HRcVec128) { @@ -8701,17 +7281,8 @@ s390_insn_load_immediate_emit(UChar *buf, const s390_insn *insn) static UChar * s390_emit_ilih(UChar *buf, UChar size, UChar dst, UChar r2) { - if (s390_host_has_gie) - return s390_emit_RISBG(buf, dst, r2, 64 - 8 * size, 63 - 4 * size, - 4 * size); - - /* Clear dst's upper half. */ - buf = s390_emit_SLLG(buf, dst, dst, 0, DISP20(64 - 4 * size)); - buf = s390_emit_SRLG(buf, dst, dst, 0, DISP20(64 - 4 * size)); - - /* Shift r2 by appropriate amount and OR it into dst. */ - buf = s390_emit_SLLG(buf, R0, r2, 0, DISP20(4 * size)); - return s390_emit_OGR(buf, dst, R0); + return s390_emit_RISBG(buf, dst, r2, 64 - 8 * size, 63 - 4 * size, + 4 * size); } @@ -8894,7 +7465,7 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) return s390_emit_SHY(buf, dst, x, b, DISP20(d)); case S390_ALU_MUL: - return s390_emit_MHYw(buf, dst, x, b, DISP20(d)); + return s390_emit_MHY(buf, dst, x, b, DISP20(d)); /* For bitwise operations: Move two bytes from memory into scratch register r0; then perform operation */ @@ -8990,7 +7561,7 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) return s390_emit_AHI(buf, dst, value); case S390_ALU_SUB: - return s390_emit_SLFIw(buf, dst, value); + return s390_emit_SLFI(buf, dst, value); case S390_ALU_MUL: return s390_emit_MHI(buf, dst, value); @@ -9022,13 +7593,13 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) if (uint_fits_signed_16bit(value)) { return s390_emit_AHI(buf, dst, value); } - return s390_emit_AFIw(buf, dst, value); + return s390_emit_AFI(buf, dst, value); - case S390_ALU_SUB: return s390_emit_SLFIw(buf, dst, value); - case S390_ALU_MUL: return s390_emit_MSFIw(buf, dst, value); - case S390_ALU_AND: return s390_emit_NILFw(buf, dst, value); - case S390_ALU_OR: return s390_emit_OILFw(buf, dst, value); - case S390_ALU_XOR: return s390_emit_XILFw(buf, dst, value); + case S390_ALU_SUB: return s390_emit_SLFI(buf, dst, value); + case S390_ALU_MUL: return s390_emit_MSFI(buf, dst, value); + case S390_ALU_AND: return s390_emit_NILF(buf, dst, value); + case S390_ALU_OR: return s390_emit_OILF(buf, dst, value); + case S390_ALU_XOR: return s390_emit_XILF(buf, dst, value); case S390_ALU_LSH: return s390_emit_SLL(buf, dst, 0, value); case S390_ALU_RSH: return s390_emit_SRL(buf, dst, 0, value); case S390_ALU_RSHA: return s390_emit_SRA(buf, dst, 0, value); @@ -9042,7 +7613,7 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) if (ulong_fits_signed_16bit(value)) { return s390_emit_AGHI(buf, dst, value); } - if (ulong_fits_signed_32bit(value) && s390_host_has_eimm) { + if (ulong_fits_signed_32bit(value)) { return s390_emit_AGFI(buf, dst, value); } /* Load constant into R0 then add */ @@ -9051,14 +7622,14 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) case S390_ALU_SUB: if (ulong_fits_unsigned_32bit(value)) { - return s390_emit_SLGFIw(buf, dst, value); + return s390_emit_SLGFI(buf, dst, value); } /* Load value into R0; then subtract from destination reg */ buf = s390_emit_load_64imm(buf, R0, value); return s390_emit_SGR(buf, dst, R0); case S390_ALU_MUL: - if (ulong_fits_signed_32bit(value) && s390_host_has_gie) { + if (ulong_fits_signed_32bit(value)) { return s390_emit_MSGFI(buf, dst, value); } /* Load constant into R0 then add */ @@ -9066,32 +7637,35 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) return s390_emit_MSGR(buf, dst, R0); /* Do it in two steps: upper half [0:31] and lower half [32:63] */ - case S390_ALU_AND: - if (s390_host_has_eimm) { - buf = s390_emit_NIHF(buf, dst, value >> 32); - return s390_emit_NILF(buf, dst, value & 0xFFFFFFFF); - } - /* Load value into R0; then combine with destination reg */ - buf = s390_emit_load_64imm(buf, R0, value); - return s390_emit_NGR(buf, dst, R0); + case S390_ALU_AND: { + UInt high = value >> 32; + UInt low = value & 0xffffffff; + if (high != 0xffffffff) + buf = s390_emit_NIHF(buf, dst, high); + if (low != 0xffffffff) + buf = s390_emit_NILF(buf, dst, low); + return buf; + } - case S390_ALU_OR: - if (s390_host_has_eimm) { - buf = s390_emit_OIHF(buf, dst, value >> 32); - return s390_emit_OILF(buf, dst, value & 0xFFFFFFFF); - } - /* Load value into R0; then combine with destination reg */ - buf = s390_emit_load_64imm(buf, R0, value); - return s390_emit_OGR(buf, dst, R0); + case S390_ALU_OR: { + UInt high = value >> 32; + UInt low = value & 0xffffffff; + if (high != 0) + buf = s390_emit_OIHF(buf, dst, high); + if (low != 0) + buf = s390_emit_OILF(buf, dst, low); + return buf; + } - case S390_ALU_XOR: - if (s390_host_has_eimm) { - buf = s390_emit_XIHF(buf, dst, value >> 32); - return s390_emit_XILF(buf, dst, value & 0xFFFFFFFF); - } - /* Load value into R0; then combine with destination reg */ - buf = s390_emit_load_64imm(buf, R0, value); - return s390_emit_XGR(buf, dst, R0); + case S390_ALU_XOR: { + UInt high = value >> 32; + UInt low = value & 0xffffffff; + if (high != 0) + buf = s390_emit_XIHF(buf, dst, high); + if (low != 0) + buf = s390_emit_XILF(buf, dst, low); + return buf; + } /* No special considerations for long displacement here. Only the six least significant bits of VALUE will be taken; all other bits are @@ -9112,6 +7686,36 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn) vpanic("s390_insn_alu_emit"); } +static UChar * +s390_insn_alu3_emit(UChar *buf, const s390_insn *insn) +{ + UInt dst, op1, op2; + + dst = hregNumber(insn->variant.alu3.dst); + op1 = hregNumber(insn->variant.alu3.op1); + op2 = hregNumber(insn->variant.alu3.op2); + + switch (insn->variant.alu3.tag) { + case S390_ALU3_ANDC: + return insn->size == 4 ? s390_emit_NCRK(buf, dst, op1, op2) + : s390_emit_NCGRK(buf, dst, op1, op2); + case S390_ALU3_ORC: + return insn->size == 4 ? s390_emit_OCRK(buf, dst, op1, op2) + : s390_emit_OCGRK(buf, dst, op1, op2); + case S390_ALU3_NAND: + return insn->size == 4 ? s390_emit_NNRK(buf, dst, op1, op2) + : s390_emit_NNGRK(buf, dst, op1, op2); + case S390_ALU3_NOR: + return insn->size == 4 ? s390_emit_NORK(buf, dst, op1, op2) + : s390_emit_NOGRK(buf, dst, op1, op2); + default: + goto fail; + } + + fail: + vpanic("s390_insn_alu3_emit"); +} + static UChar * s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size, @@ -9130,30 +7734,30 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size, because the upper half-word will not be looked at. */ if (insn->size == 4 || insn->size == 2) { /* 8 --> 32 8 --> 16 */ if (sign_extend) - return s390_emit_LBRw(buf, r1, r2); + return s390_emit_LBR(buf, r1, r2); else - return s390_emit_LLCRw(buf, r1, r2); + return s390_emit_LLCR(buf, r1, r2); } if (insn->size == 8) { /* 8 --> 64 */ if (sign_extend) - return s390_emit_LGBRw(buf, r1, r2); + return s390_emit_LGBR(buf, r1, r2); else - return s390_emit_LLGCRw(buf, r1, r2); + return s390_emit_LLGCR(buf, r1, r2); } goto fail; case 2: if (insn->size == 4) { /* 16 --> 32 */ if (sign_extend) - return s390_emit_LHRw(buf, r1, r2); + return s390_emit_LHR(buf, r1, r2); else - return s390_emit_LLHRw(buf, r1, r2); + return s390_emit_LLHR(buf, r1, r2); } if (insn->size == 8) { /* 16 --> 64 */ if (sign_extend) - return s390_emit_LGHRw(buf, r1, r2); + return s390_emit_LGHR(buf, r1, r2); else - return s390_emit_LLGHRw(buf, r1, r2); + return s390_emit_LLGHR(buf, r1, r2); } goto fail; @@ -9184,7 +7788,7 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size, if (sign_extend) return s390_emit_LB(buf, r1, x, b, DISP20(d)); else - return s390_emit_LLCw(buf, r1, x, b, DISP20(d)); + return s390_emit_LLC(buf, r1, x, b, DISP20(d)); } if (insn->size == 8) { if (sign_extend) @@ -9197,7 +7801,7 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size, case 2: if (insn->size == 4) { /* 16 --> 32 */ if (sign_extend == 0) - return s390_emit_LLHw(buf, r1, x, b, DISP20(d)); + return s390_emit_LLH(buf, r1, x, b, DISP20(d)); switch (src->tag) { case S390_AMODE_B12: @@ -9274,9 +7878,9 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size, case 4: if (insn->size == 8) { /* 32 --> 64 */ if (sign_extend) - return s390_emit_LGFIw(buf, r1, value); + return s390_emit_LGFI(buf, r1, value); else - return s390_emit_LLILFw(buf, r1, value); + return s390_emit_LLILF(buf, r1, value); } goto fail; @@ -9365,6 +7969,43 @@ s390_negate_emit(UChar *buf, const s390_insn *insn) } +static UChar * +s390_popcnt_emit(UChar *buf, const s390_insn *insn) +{ + s390_opnd_RMI src; + UChar r1, r2, *p; + + vassert(insn->size == 8); + p = buf; + r1 = hregNumber(insn->variant.unop.dst); + src = insn->variant.unop.src; + + /* Get operand and move it to r2 */ + switch (src.tag) { + case S390_OPND_REG: + r2 = hregNumber(src.variant.reg); + break; + + case S390_OPND_AMODE: { + p = s390_emit_load_mem(p, 8, R0, src.variant.am); + r2 = R0; + break; + } + + case S390_OPND_IMMEDIATE: { + p = s390_emit_load_64imm(p, R0, src.variant.imm); + r2 = R0; + break; + } + + default: + vpanic("s390_popcnt_emit"); + } + + return s390_emit_POPCNT(p, r1, r2); +} + + static UChar * s390_vec_duplicate_emit(UChar *buf, const s390_insn *insn) { @@ -9427,7 +8068,25 @@ s390_insn_unop_emit(UChar *buf, const s390_insn *insn) case S390_SIGN_EXTEND_16: return s390_widen_emit(buf, insn, 2, 1); case S390_SIGN_EXTEND_32: return s390_widen_emit(buf, insn, 4, 1); - case S390_NEGATE: return s390_negate_emit(buf, insn); + case S390_LOAD_ADDRESS: { + vassert(insn->variant.unop.src.tag == S390_OPND_AMODE); + UChar dst = hregNumber(insn->variant.unop.dst); + s390_amode* am = insn->variant.unop.src.variant.am; + UChar x = hregNumber(am->x); + UChar b = hregNumber(am->b); + switch (am->tag) { + case S390_AMODE_B12: + case S390_AMODE_BX12: + return s390_emit_LA(buf, dst, x, b, am->d); + case S390_AMODE_B20: + case S390_AMODE_BX20: + return s390_emit_LAY(buf, dst, x, b, DISP20(am->d)); + } + vpanic("s390_insn_unop_emit -- load address"); + } + case S390_NEGATE: + return s390_negate_emit(buf, insn); + case S390_POPCNT: return s390_popcnt_emit(buf, insn); case S390_VEC_FILL: { vassert(insn->variant.unop.src.tag == S390_OPND_IMMEDIATE); UChar v1 = hregNumber(insn->variant.unop.dst); @@ -9571,10 +8230,10 @@ s390_insn_test_emit(UChar *buf, const s390_insn *insn) } case 4: - return s390_emit_LTw(buf, R0, x, b, DISP20(d)); + return s390_emit_LT(buf, R0, x, b, DISP20(d)); case 8: - return s390_emit_LTGw(buf, R0, x, b, DISP20(d)); + return s390_emit_LTG(buf, R0, x, b, DISP20(d)); default: goto fail; @@ -9813,19 +8472,17 @@ s390_insn_compare_emit(UChar *buf, const s390_insn *insn) switch (insn->size) { case 4: if (signed_comparison) - return s390_emit_CFIw(buf, r1, value); + return s390_emit_CFI(buf, r1, value); else - return s390_emit_CLFIw(buf, r1, value); + return s390_emit_CLFI(buf, r1, value); case 8: - if (s390_host_has_eimm) { - if (signed_comparison) { - if (ulong_fits_signed_32bit(value)) - return s390_emit_CGFI(buf, r1, value); - } else { - if (ulong_fits_unsigned_32bit(value)) - return s390_emit_CLGFI(buf, r1, value); - } + if (signed_comparison) { + if (ulong_fits_signed_32bit(value)) + return s390_emit_CGFI(buf, r1, value); + } else { + if (ulong_fits_unsigned_32bit(value)) + return s390_emit_CLGFI(buf, r1, value); } buf = s390_emit_load_64imm(buf, R0, value); if (signed_comparison) @@ -9912,7 +8569,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn) case S390_AMODE_B20: case S390_AMODE_BX20: if (signed_multiply) - return s390_emit_MFYw(buf, r1, x, b, DISP20(d)); + return s390_emit_MFY(buf, r1, x, b, DISP20(d)); else return s390_emit_ML(buf, r1, x, b, DISP20(d)); } @@ -10147,35 +8804,10 @@ s390_insn_clz_emit(UChar *buf, const s390_insn *insn) } default: - goto fail; - } - - /* Use FLOGR if you can */ - if (s390_host_has_eimm) { - return s390_emit_FLOGR(p, r1, r2); + vpanic("s390_insn_clz_emit"); } - /* - r0 = r2; - r1 = 64; - while (r0 != 0) { - r1 -= 1; - r0 >>= 1; - } - */ - p = s390_emit_LTGR(p, R0, r2); - p = s390_emit_LLILL(p, r1, 64); - - p = s390_emit_BRC(p, S390_CC_E, (4 + 4 + 6 + 4 + 4)/ 2); /* 4 bytes */ - p = s390_emit_AGHI(p, r1, (UShort)-1); /* r1 -= 1; 4 bytes */ - p = s390_emit_SRLG(p, R0, R0, R0, DISP20(1)); /* r0 >>= 1; 6 bytes */ - p = s390_emit_LTGR(p, R0, R0); /* set cc 4 bytes */ - p = s390_emit_BRC(p, S390_CC_NE, /* 4 bytes */ - (UShort)(-(4 + 6 + 4) / 2)); - return p; - - fail: - vpanic("s390_insn_clz_emit"); + return s390_emit_FLOGR(p, r1, r2); } @@ -10287,7 +8919,7 @@ s390_insn_cond_move_emit(UChar *buf, const s390_insn *insn) p = buf; - if (s390_host_has_lsc && hregClass(dst) == HRcInt64) { + if (hregClass(dst) == HRcInt64) { /* LOCx is not the preferred way to implement an unconditional load. */ if (cond == S390_CC_ALWAYS) goto use_branch_insn; @@ -10899,7 +9531,7 @@ s390_insn_mimm_emit(UChar *buf, const s390_insn *insn) return s390_emit_MVI(buf, value & 0xFF, b, d); } - if (s390_host_has_gie && ulong_fits_signed_16bit(value)) { + if (ulong_fits_signed_16bit(value)) { value &= 0xFFFF; switch (insn->size) { case 2: return s390_emit_MVHHI(buf, b, d, value); @@ -11004,19 +9636,9 @@ s390_tchain_load64(UChar *buf, UChar regno, ULong value) { UChar *begin = buf; - if (s390_host_has_eimm) { - /* Do it in two steps: upper half [0:31] and lower half [32:63] */ - buf = s390_emit_IIHF(buf, regno, value >> 32); - buf = s390_emit_IILF(buf, regno, value & 0xFFFFFFFF); - } else { - buf = s390_emit_IILL(buf, regno, value & 0xFFFF); - value >>= 16; - buf = s390_emit_IILH(buf, regno, value & 0xFFFF); - value >>= 16; - buf = s390_emit_IIHL(buf, regno, value & 0xFFFF); - value >>= 16; - buf = s390_emit_IIHH(buf, regno, value & 0xFFFF); - } + /* Do it in two steps: upper half [0:31] and lower half [32:63] */ + buf = s390_emit_IIHF(buf, regno, value >> 32); + buf = s390_emit_IILF(buf, regno, value & 0xFFFFFFFF); vassert(buf - begin == s390_tchain_load64_len()); @@ -11027,10 +9649,7 @@ s390_tchain_load64(UChar *buf, UChar regno, ULong value) static UInt s390_tchain_load64_len(void) { - if (s390_host_has_eimm) { - return 6 + 6; /* IIHF + IILF */ - } - return 4 + 4 + 4 + 4; /* IIHH + IIHL + IILH + IILL */ + return 6 + 6; /* IIHF + IILF */ } /* Verify that CODE is the code sequence generated by s390_tchain_load64 @@ -11040,46 +9659,15 @@ static const UChar * s390_tchain_verify_load64(const UChar *code, UChar regno, ULong value) { UInt regmask = regno << 4; - UInt hw; - - if (s390_host_has_eimm) { - /* Check for IIHF */ - vassert(code[0] == 0xC0); - vassert(code[1] == (0x08 | regmask)); - vassert(*(const UInt *)&code[2] == (value >> 32)); - /* Check for IILF */ - vassert(code[6] == 0xC0); - vassert(code[7] == (0x09 | regmask)); - vassert(*(const UInt *)&code[8] == (value & 0xFFFFFFFF)); - } else { - /* Check for IILL */ - hw = value & 0xFFFF; - vassert(code[0] == 0xA5); - vassert(code[1] == (0x03 | regmask)); - vassert(code[2] == (hw >> 8)); - vassert(code[3] == (hw & 0xFF)); - - /* Check for IILH */ - hw = (value >> 16) & 0xFFFF; - vassert(code[4] == 0xA5); - vassert(code[5] == (0x02 | regmask)); - vassert(code[6] == (hw >> 8)); - vassert(code[7] == (hw & 0xFF)); - - /* Check for IIHL */ - hw = (value >> 32) & 0xFFFF; - vassert(code[8] == 0xA5); - vassert(code[9] == (0x01 | regmask)); - vassert(code[10] == (hw >> 8)); - vassert(code[11] == (hw & 0xFF)); - - /* Check for IIHH */ - hw = (value >> 48) & 0xFFFF; - vassert(code[12] == 0xA5); - vassert(code[13] == (0x00 | regmask)); - vassert(code[14] == (hw >> 8)); - vassert(code[15] == (hw & 0xFF)); - } + + /* Check for IIHF */ + vassert(code[0] == 0xC0); + vassert(code[1] == (0x08 | regmask)); + vassert(*(const UInt *)&code[2] == (value >> 32)); + /* Check for IILF */ + vassert(code[6] == 0xC0); + vassert(code[7] == (0x09 | regmask)); + vassert(*(const UInt *)&code[8] == (value & 0xFFFFFFFF)); return code + s390_tchain_load64_len(); } @@ -11090,21 +9678,10 @@ s390_tchain_verify_load64(const UChar *code, UChar regno, ULong value) static UChar * s390_tchain_patch_load64(UChar *code, ULong imm64) { - if (s390_host_has_eimm) { - /* Patch IIHF */ - *(UInt *)&code[2] = imm64 >> 32; - /* Patch IILF */ - *(UInt *)&code[8] = imm64 & 0xFFFFFFFF; - } else { - code[3] = imm64 & 0xFF; imm64 >>= 8; - code[2] = imm64 & 0xFF; imm64 >>= 8; - code[7] = imm64 & 0xFF; imm64 >>= 8; - code[6] = imm64 & 0xFF; imm64 >>= 8; - code[11] = imm64 & 0xFF; imm64 >>= 8; - code[10] = imm64 & 0xFF; imm64 >>= 8; - code[15] = imm64 & 0xFF; imm64 >>= 8; - code[14] = imm64 & 0xFF; imm64 >>= 8; - } + /* Patch IIHF */ + *(UInt *)&code[2] = imm64 >> 32; + /* Patch IILF */ + *(UInt *)&code[8] = imm64 & 0xFFFFFFFF; return code + s390_tchain_load64_len(); } @@ -11344,8 +9921,7 @@ s390_insn_xassisted_emit(UChar *buf, const s390_insn *insn, The dispatch counter is a 32-bit value. */ static UChar * -s390_insn_evcheck_emit(UChar *buf, const s390_insn *insn, - VexEndness endness_host) +s390_insn_evcheck_emit(UChar *buf, const s390_insn *insn) { s390_amode *amode; UInt b, d; @@ -11359,13 +9935,7 @@ s390_insn_evcheck_emit(UChar *buf, const s390_insn *insn, d = amode->d; /* Decrement the dispatch counter in the guest state */ - if (s390_host_has_gie) { - buf = s390_emit_ASI(buf, -1, b, DISP20(d)); /* 6 bytes */ - } else { - buf = s390_emit_LHI(buf, R0, -1); /* 4 bytes */ - buf = s390_emit_A(buf, R0, 0, b, d); /* 4 bytes */ - buf = s390_emit_ST(buf, R0, 0, b, d); /* 4 bytes */ - } + buf = s390_emit_ASI(buf, -1, b, DISP20(d)); /* 6 bytes */ /* Jump over the next insn if >= 0 */ buf = s390_emit_BRC(buf, S390_CC_HE, (4 + 6 + 2) / 2); /* 4 bytes */ @@ -11396,13 +9966,7 @@ s390_insn_profinc_emit(UChar *buf, template will be patched once the memory location is known. For now we do this with address == 0. */ buf = s390_tchain_load64(buf, S390_REGNO_TCHAIN_SCRATCH, 0); - if (s390_host_has_gie) { - buf = s390_emit_AGSI(buf, 1, S390_REGNO_TCHAIN_SCRATCH, DISP20(0)); - } else { - buf = s390_emit_LGHI(buf, R0, 1); - buf = s390_emit_AG( buf, R0, 0, S390_REGNO_TCHAIN_SCRATCH, DISP20(0)); - buf = s390_emit_STG(buf, R0, 0, S390_REGNO_TCHAIN_SCRATCH, DISP20(0)); - } + buf = s390_emit_AGSI(buf, 1, S390_REGNO_TCHAIN_SCRATCH, DISP20(0)); return buf; } @@ -11527,6 +10091,14 @@ s390_insn_vec_binop_emit(UChar *buf, const s390_insn *insn) return s390_emit_VMO(buf, v1, v2, v3, s390_getM_from_size(size)); case S390_VEC_INT_MUL_ODDU: return s390_emit_VMLO(buf, v1, v2, v3, s390_getM_from_size(size)); + case S390_VEC_INT_DIVU: + return s390_emit_VDL(buf, v1, v2, v3, s390_getM_from_size(size), 0); + case S390_VEC_INT_DIVS: + return s390_emit_VD(buf, v1, v2, v3, s390_getM_from_size(size), 0); + case S390_VEC_INT_MODU: + return s390_emit_VRL(buf, v1, v2, v3, s390_getM_from_size(size), 0); + case S390_VEC_INT_MODS: + return s390_emit_VR(buf, v1, v2, v3, s390_getM_from_size(size), 0); case S390_VEC_ELEM_SHL_V: return s390_emit_VESLV(buf, v1, v2, v3, s390_getM_from_size(size)); case S390_VEC_ELEM_SHRA_V: @@ -11633,7 +10205,7 @@ s390_insn_vec_replicate_emit(UChar *buf, const s390_insn *insn) Int emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, const s390_insn *insn, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo *archinfo_host, const void *disp_cp_chain_me_to_slowEP, const void *disp_cp_chain_me_to_fastEP, const void *disp_cp_xindir, @@ -11673,6 +10245,10 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, const s390_insn *insn, end = s390_insn_alu_emit(buf, insn); break; + case S390_INSN_ALU3: + end = s390_insn_alu3_emit(buf, insn); + break; + case S390_INSN_SMUL: case S390_INSN_UMUL: end = s390_insn_mul_emit(buf, insn); @@ -11796,7 +10372,7 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, const s390_insn *insn, break; case S390_INSN_EVCHECK: - end = s390_insn_evcheck_emit(buf, insn, endness_host); + end = s390_insn_evcheck_emit(buf, insn); break; case S390_INSN_XDIRECT: @@ -11848,7 +10424,7 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, const s390_insn *insn, Int evCheckSzB_S390(void) { - return s390_host_has_gie ? 18 : 24; + return 18; } diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index 3de079e838..e4e83ccf6e 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2020 + Copyright IBM Corp. 2010-2026 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -122,7 +122,8 @@ typedef enum { S390_INSN_MEMCPY, /* from memory to memory */ S390_INSN_COND_MOVE, /* conditonal "move" to register */ S390_INSN_LOAD_IMMEDIATE, - S390_INSN_ALU, + S390_INSN_ALU, /* a = a b */ + S390_INSN_ALU3, /* a = b c -- distinct operands */ S390_INSN_SMUL, /* signed multiply; n-bit operands; 2n-bit result */ S390_INSN_UMUL, /* unsigned multiply; n-bit operands; 2n-bit result */ S390_INSN_SDIV, /* signed division; 2n-bit / n-bit -> n-bit quot/rem */ @@ -184,6 +185,14 @@ typedef enum { } s390_alu_t; +/* The kind of ALU3 instructions */ +typedef enum { + S390_ALU3_ANDC, /* and with complement */ + S390_ALU3_ORC, /* or with complement */ + S390_ALU3_NAND, + S390_ALU3_NOR, +} s390_alu3_t; + /* The kind of unary integer operations */ typedef enum { S390_ZERO_EXTEND_8, @@ -192,7 +201,9 @@ typedef enum { S390_SIGN_EXTEND_8, S390_SIGN_EXTEND_16, S390_SIGN_EXTEND_32, + S390_LOAD_ADDRESS, S390_NEGATE, + S390_POPCNT, S390_VEC_FILL, S390_VEC_DUPLICATE, S390_VEC_UNPACKLOWS, @@ -384,6 +395,10 @@ typedef enum { S390_VEC_INT_MUL_LOW, S390_VEC_INT_MUL_ODDS, S390_VEC_INT_MUL_ODDU, + S390_VEC_INT_DIVS, + S390_VEC_INT_DIVU, + S390_VEC_INT_MODS, + S390_VEC_INT_MODU, S390_VEC_ELEM_SHL_V, S390_VEC_ELEM_SHRA_V, S390_VEC_ELEM_SHRL_V, @@ -506,6 +521,12 @@ typedef struct { HReg dst; /* op1 */ s390_opnd_RMI op2; } alu; + struct { + s390_alu3_t tag; + HReg dst; + HReg op1; + HReg op2; + } alu3; struct { HReg dst_hi; /* r10 */ HReg dst_lo; /* also op1 r11 */ @@ -765,6 +786,8 @@ s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst, s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val); s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst, s390_opnd_RMI op2); +s390_insn *s390_insn_alu3(UChar size, s390_alu3_t tag, HReg dst, HReg op1, + HReg op2); s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo, s390_opnd_RMI op2, Bool signed_multiply); s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo, @@ -885,13 +908,13 @@ UInt ppHRegS390(HReg); void getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool ); void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool ); Int emit_S390Instr ( Bool *, UChar *, Int, const s390_insn *, Bool, - VexEndness, const void *, const void *, + const VexArchInfo *, const void *, const void *, const void *, const void *); const RRegUniverse *getRRegUniverse_S390( void ); void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool ); void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool ); -HInstr* directReload_S390 ( HInstr *, HReg, Short ); -extern s390_insn* genMove_S390(HReg from, HReg to, Bool mode64); +HInstr *directReload_S390 ( HInstr *, HReg, Short ); +s390_insn *genMove_S390 ( HReg from, HReg to, Bool mode64); HInstrArray *iselSB_S390 ( const IRSB *, VexArch, const VexArchInfo *, const VexAbiInfo *, Int, Int, Bool, Bool, Addr); @@ -918,30 +941,6 @@ VexInvalRange patchProfInc_S390(VexEndness endness_host, extern UInt s390_host_hwcaps; /* Convenience macros to test installed facilities */ -#define s390_host_has_ldisp \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP)) -#define s390_host_has_eimm \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM)) -#define s390_host_has_gie \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE)) -#define s390_host_has_dfp \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP)) -#define s390_host_has_fgx \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX)) -#define s390_host_has_etf2 \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2)) -#define s390_host_has_stfle \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE)) -#define s390_host_has_etf3 \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3)) -#define s390_host_has_stckf \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF)) -#define s390_host_has_fpext \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT)) -#define s390_host_has_lsc \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC)) -#define s390_host_has_pfpo \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO)) #define s390_host_has_vx \ (s390_host_hwcaps & (VEX_HWCAPS_S390X_VX)) #define s390_host_has_msa5 \ @@ -960,14 +959,16 @@ extern UInt s390_host_hwcaps; (s390_host_hwcaps & (VEX_HWCAPS_S390X_VXE2)) #define s390_host_has_vxd \ (s390_host_hwcaps & (VEX_HWCAPS_S390X_VXD)) -#define s390_host_has_msa \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA)) -#define s390_host_has_msa4 \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA4)) #define s390_host_has_msa8 \ (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA8)) #define s390_host_has_msa9 \ (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA9)) +#define s390_host_has_mi3 \ + (s390_host_hwcaps & (VEX_HWCAPS_S390X_MI3)) +#define s390_host_has_vxe3 \ + (s390_host_hwcaps & (VEX_HWCAPS_S390X_VXE3)) +#define s390_host_has_msa12 \ + (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA12)) #endif /* ndef __VEX_HOST_S390_DEFS_H */ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 8f87cc2394..abf026eb16 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -8,7 +8,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright IBM Corp. 2010-2020 + Copyright IBM Corp. 2010-2026 Copyright (C) 2012-2017 Florian Krohm (britzel@acm.org) This program is free software; you can redistribute it and/or @@ -169,6 +169,16 @@ get_guest_reg(Int offset) return GUEST_UNKNOWN; } + +static inline Bool +is_IRExpr_Not(const IRExpr* e) +{ + IROp op; + return e->tag == Iex_Unop && + ((op = e->Iex.Unop.op) == Iop_Not8 || op == Iop_Not16 || + op == Iop_Not32 || op == Iop_Not64); +} + /* Add an instruction */ static void addInstr(ISelEnv *env, s390_insn *insn) @@ -1277,13 +1287,21 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) goto do_multiply; do_multiply: { - HReg r10, r11; - UInt arg_size = is_single_multiply ? size : size / 2; - order_commutative_operands(arg1, arg2); h1 = s390_isel_int_expr(env, arg1); /* Process 1st operand */ op2 = s390_isel_int_expr_RMI(env, arg2); /* Process 2nd operand */ + res = newVRegI(env); + + if (is_single_multiply) { + /* No register pair needed */ + addInstr(env, s390_insn_move(size, res, h1)); + addInstr(env, s390_insn_alu(size, S390_ALU_MUL, res, op2)); + return res; + } + + HReg r10, r11; + UInt arg_size = size / 2; /* We use non-virtual registers r10 and r11 as pair */ r10 = make_gpr(10); @@ -1295,7 +1313,6 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) /* Multiply */ addInstr(env, s390_insn_mul(arg_size, r10, r11, op2, is_signed_multiply)); - res = newVRegI(env); if (arg_size == 1 || arg_size == 2) { /* For 8-bit and 16-bit multiplication the result is in r11[32:63] */ @@ -1303,12 +1320,6 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) return res; } - /* For Iop_Mul64 the result is in r11[0:63] */ - if (expr->Iex.Binop.op == Iop_Mul64) { - addInstr(env, s390_insn_move(size, res, r11)); - return res; - } - /* The result is in registers r10 and r11. Combine them into a SIZE-bit value into the destination register. */ addInstr(env, s390_insn_move(arg_size, res, r10)); @@ -1680,10 +1691,46 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) if (is_commutative) { order_commutative_operands(arg1, arg2); } + res = newVRegI(env); + + /* Pattern match: "arg1 and/or not(x)" --> and/or with complement */ + if ((env->hwcaps & VEX_HWCAPS_S390X_MI3) && + (opkind == S390_ALU_OR || opkind == S390_ALU_AND)) { + if (is_IRExpr_Not(arg1)) { // swap + IRExpr* tmp = arg2; + arg2 = arg1; + arg1 = tmp; + } + if (is_IRExpr_Not(arg2)) { + HReg h2; + h1 = s390_isel_int_expr(env, arg1); + h2 = s390_isel_int_expr(env, arg2->Iex.Unop.arg); + addInstr(env, s390_insn_alu3(size <= 4 ? 4 : 8, + opkind == S390_ALU_OR ? S390_ALU3_ORC + : S390_ALU3_ANDC, + res, h1, h2)); + return res; + } + } + + /* Is this a match for "load address"? */ + if (expr->Iex.Binop.op == Iop_Add64 && arg2->tag == Iex_Const) { + ULong disp = arg2->Iex.Const.con->Ico.U64; + if (ulong_fits_signed_20bit(disp)) { + h1 = s390_isel_int_expr(env, arg1); + opnd.tag = S390_OPND_AMODE; + if (ulong_fits_unsigned_12bit(disp)) { + opnd.variant.am = s390_amode_b12(disp, h1); + } else { + opnd.variant.am = s390_amode_b20((Int)disp, h1); + } + addInstr(env, s390_insn_unop(size, S390_LOAD_ADDRESS, res, opnd)); + return res; + } + } h1 = s390_isel_int_expr(env, arg1); /* Process 1st operand */ op2 = s390_isel_int_expr_RMI(env, arg2); /* Process 2nd operand */ - res = newVRegI(env); /* As right shifts of one/two byte opreands are implemented using a 4-byte shift op, we first need to zero/sign-extend the shiftee. */ @@ -1833,8 +1880,6 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) return dst; } - /* Regular processing */ - if (unop == Iop_128to64) { HReg dst_hi, dst_lo; @@ -1874,6 +1919,38 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) return dst; } + /* NAND or NOR */ + if ((env->hwcaps & VEX_HWCAPS_S390X_MI3) && is_IRExpr_Not(expr) && + arg->tag == Iex_Binop) { + s390_alu3_t bitop; + + switch (binop) { + case Iop_And8: + case Iop_And16: + case Iop_And32: + case Iop_And64: + bitop = S390_ALU3_NAND; + goto do_nand_nor; + case Iop_Or8: + case Iop_Or16: + case Iop_Or32: + case Iop_Or64: + bitop = S390_ALU3_NOR; + do_nand_nor: { + HReg h2; + dst = newVRegI(env); + h1 = s390_isel_int_expr(env, arg->Iex.Binop.arg1); + h2 = s390_isel_int_expr(env, arg->Iex.Binop.arg2); + addInstr(env, + s390_insn_alu3(size <= 4 ? 4 : 8, bitop, dst, h1, h2)); + return dst; + } + default:; + } + } + + /* Regular processing */ + dst = newVRegI(env); /* Result goes into a new register */ opnd = s390_isel_int_expr_RMI(env, arg); /* Process the operand */ @@ -1943,10 +2020,16 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) case Iop_Not16: case Iop_Not32: case Iop_Not64: - /* XOR with ffff... */ - mask.variant.imm = ~(ULong)0; - addInstr(env, s390_opnd_copy(size, dst, opnd)); - insn = s390_insn_alu(size, S390_ALU_XOR, dst, mask); + if ((env->hwcaps & VEX_HWCAPS_S390X_MI3) && + opnd.tag == S390_OPND_REG) { + insn = s390_insn_alu3(size <= 4 ? 4 : 8, S390_ALU3_NOR, dst, + opnd.variant.reg, opnd.variant.reg); + } else { + /* XOR with ffff... */ + addInstr(env, s390_opnd_copy(size, dst, opnd)); + mask.variant.imm = ~(ULong)0; + insn = s390_insn_alu(size, S390_ALU_XOR, dst, mask); + } break; case Iop_Left8: @@ -1983,6 +2066,11 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) return dst; } + case Iop_PopCount64: { + addInstr(env, s390_insn_unop(8, S390_POPCNT, dst, opnd)); + return dst; + } + default: goto irreducible; } @@ -2392,12 +2480,7 @@ s390_isel_float128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, irrm = expr->Iex.Binop.arg1; left = expr->Iex.Binop.arg2; - if (s390_host_has_fpext) { - rm = get_bfp_rounding_mode(env, irrm); - } else { - set_bfp_rounding_mode_in_fpc(env, irrm); - rm = S390_BFP_ROUND_PER_FPC; - } + rm = get_bfp_rounding_mode(env, irrm); s390_isel_float128_expr(&op_hi, &op_lo, env, left); /* operand --> (f4, f6) */ @@ -2677,12 +2760,7 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) /* convert-from-fixed and load-rounded have a rounding mode field when the floating point extension facility is installed. */ dst = newVRegF(env); - if (s390_host_has_fpext) { - rounding_mode = get_bfp_rounding_mode(env, irrm); - } else { - set_bfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_BFP_ROUND_PER_FPC; - } + rounding_mode = get_bfp_rounding_mode(env, irrm); addInstr(env, s390_insn_bfp_convert(size, conv, dst, h1, rounding_mode)); return dst; @@ -2753,14 +2831,7 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) /* result --> (f12, f14) */ - /* load-rounded has a rounding mode field when the floating point - extension facility is installed. */ - if (s390_host_has_fpext) { - rounding_mode = get_bfp_rounding_mode(env, irrm); - } else { - set_bfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_BFP_ROUND_PER_FPC; - } + rounding_mode = get_bfp_rounding_mode(env, irrm); addInstr(env, s390_insn_bfp128_convert_from(size, conv, f12, f14, f13, f15, rounding_mode)); @@ -2974,15 +3045,7 @@ s390_isel_dfp128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, addInstr(env, s390_insn_move(8, f12, op2_hi)); addInstr(env, s390_insn_move(8, f14, op2_lo)); - /* DFP arithmetic ops take rounding mode only when fpext is - installed. But, DFP quantize operation takes rm irrespective - of fpext facility . */ - if (s390_host_has_fpext || op == Iop_QuantizeD128) { - rounding_mode = get_dfp_rounding_mode(env, irrm); - } else { - set_dfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_DFP_ROUND_PER_FPC_0; - } + rounding_mode = get_dfp_rounding_mode(env, irrm); addInstr(env, s390_insn_dfp128_binop(16, dfpop, f13, f15, f9, f11, f12, f14, rounding_mode)); /* Move result to virtual destination register */ @@ -3294,15 +3357,9 @@ s390_isel_dfp_expr_wrk(ISelEnv *env, IRExpr *expr) convert: { s390_dfp_round_t rounding_mode; - /* convert-from-fixed and load-rounded have a rounding mode field - when the floating point extension facility is installed. */ + dst = newVRegF(env); - if (s390_host_has_fpext) { - rounding_mode = get_dfp_rounding_mode(env, irrm); - } else { - set_dfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_DFP_ROUND_PER_FPC_0; - } + rounding_mode = get_dfp_rounding_mode(env, irrm); addInstr(env, s390_insn_dfp_convert(size, conv, dst, h1, rounding_mode)); return dst; @@ -3368,14 +3425,7 @@ s390_isel_dfp_expr_wrk(ISelEnv *env, IRExpr *expr) /* result --> (f12, f14) */ - /* load-rounded has a rounding mode field when the floating point - extension facility is installed. */ - if (s390_host_has_fpext) { - rounding_mode = get_dfp_rounding_mode(env, irrm); - } else { - set_dfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_DFP_ROUND_PER_FPC_0; - } + rounding_mode = get_dfp_rounding_mode(env, irrm); addInstr(env, s390_insn_dfp128_convert_from(size, conv, f12, f14, f13, f15, rounding_mode)); dst = newVRegF(env); @@ -3495,15 +3545,7 @@ s390_isel_dfp_expr_wrk(ISelEnv *env, IRExpr *expr) op2 = s390_isel_dfp_expr(env, left); /* Process 1st operand */ op3 = s390_isel_dfp_expr(env, right); /* Process 2nd operand */ dst = newVRegF(env); - /* DFP arithmetic ops take rounding mode only when fpext is - installed. But, DFP quantize operation takes rm irrespective - of fpext facility . */ - if (s390_host_has_fpext || dfpop == S390_DFP_QUANTIZE) { - rounding_mode = get_dfp_rounding_mode(env, irrm); - } else { - set_dfp_rounding_mode_in_fpc(env, irrm); - rounding_mode = S390_DFP_ROUND_PER_FPC_0; - } + rounding_mode = get_dfp_rounding_mode(env, irrm); addInstr(env, s390_insn_dfp_binop(size, dfpop, dst, op2, op3, rounding_mode)); return dst; @@ -4116,6 +4158,15 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) return dst; } + case Iop_ReinterpI128asV128: { + HReg reg2 = INVALID_HREG; + dst = newVRegV(env); + s390_isel_int128_expr(®1, ®2, env, arg); + addInstr(env, s390_insn_vec_binop(size, S390_VEC_INIT_FROM_GPRS, + dst, reg1, reg2)); + return dst; + } + default: goto irreducible; } @@ -4526,6 +4577,23 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) vec_binop = S390_VEC_INT_MUL_ODDU; goto Iop_VV_wrk; + case Iop_DivU128: + size = 16; + vec_binop = S390_VEC_INT_DIVU; + goto Iop_VV_wrk; + case Iop_DivS128: + size = 16; + vec_binop = S390_VEC_INT_DIVS; + goto Iop_VV_wrk; + case Iop_ModU128: + size = 16; + vec_binop = S390_VEC_INT_MODU; + goto Iop_VV_wrk; + case Iop_ModS128: + size = 16; + vec_binop = S390_VEC_INT_MODS; + goto Iop_VV_wrk; + case Iop_Shl8x16: size = 1; vec_binop = S390_VEC_ELEM_SHL_V; @@ -5052,7 +5120,7 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) we can use a memory-to-memory insn */ difference = new_value - old_value; - if (s390_host_has_gie && ulong_fits_signed_8bit(difference)) { + if (ulong_fits_signed_8bit(difference)) { am = s390_amode_for_guest_state(offset); addInstr(env, s390_insn_madd(sizeofIRType(tyd), am, (difference & 0xFF), new_value)); @@ -5542,7 +5610,7 @@ iselSB_S390(const IRSB *bb, VexArch arch_host, const VexArchInfo *archinfo_host, { UInt i, j; HReg hreg, hregHI; - ISelEnv *env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; /* Do some sanity checks */ @@ -5552,7 +5620,7 @@ iselSB_S390(const IRSB *bb, VexArch arch_host, const VexArchInfo *archinfo_host, vassert(archinfo_host->endness == VexEndnessBE); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/host_x86_defs.c b/VEX/priv/host_x86_defs.c index 200c122fd8..5ef43eb95a 100644 --- a/VEX/priv/host_x86_defs.c +++ b/VEX/priv/host_x86_defs.c @@ -2102,7 +2102,6 @@ static UChar* push_word_from_tags ( UChar* p, UShort tags ) *p++ = 0x6A; *p++ = 0xFF; } else { - vassert(0); /* awaiting test case */ w = 0; if (tags & 1) w |= 0x000000FF; if (tags & 2) w |= 0x0000FF00; @@ -2122,7 +2121,7 @@ static UChar* push_word_from_tags ( UChar* p, UShort tags ) Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const X86Instr* i, - Bool mode64, VexEndness endness_host, + Bool mode64, const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_x86_defs.h b/VEX/priv/host_x86_defs.h index ecd74e6a53..65cca18f6f 100644 --- a/VEX/priv/host_x86_defs.h +++ b/VEX/priv/host_x86_defs.h @@ -717,7 +717,7 @@ extern void mapRegs_X86Instr ( HRegRemap*, X86Instr*, Bool ); extern Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc, UChar* buf, Int nbuf, const X86Instr* i, Bool mode64, - VexEndness endness_host, + const VexArchInfo* archinfo_host, const void* disp_cp_chain_me_to_slowEP, const void* disp_cp_chain_me_to_fastEP, const void* disp_cp_xindir, diff --git a/VEX/priv/host_x86_isel.c b/VEX/priv/host_x86_isel.c index 6559ad51de..dfff1cec98 100644 --- a/VEX/priv/host_x86_isel.c +++ b/VEX/priv/host_x86_isel.c @@ -3861,12 +3861,48 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, const IRExpr* e ) return dst; } + case Iop_CmpEQ64x2: + fn = (HWord)h_generic_calc_CmpEQ64x2; + goto do_SseAssistedBinary; case Iop_NarrowBin32to16x8: fn = (HWord)h_generic_calc_NarrowBin32to16x8; goto do_SseAssistedBinary; case Iop_NarrowBin16to8x16: fn = (HWord)h_generic_calc_NarrowBin16to8x16; goto do_SseAssistedBinary; + case Iop_Max8Sx16: + fn = (HWord)h_generic_calc_Max8Sx16; + goto do_SseAssistedBinary; + case Iop_Min8Sx16: + fn = (HWord)h_generic_calc_Min8Sx16; + goto do_SseAssistedBinary; + case Iop_Max16Ux8: + fn = (HWord)h_generic_calc_Max16Ux8; + goto do_SseAssistedBinary; + case Iop_Min16Ux8: + fn = (HWord)h_generic_calc_Min16Ux8; + goto do_SseAssistedBinary; + case Iop_Max32Sx4: + fn = (HWord)h_generic_calc_Max32Sx4; + goto do_SseAssistedBinary; + case Iop_Min32Sx4: + fn = (HWord)h_generic_calc_Min32Sx4; + goto do_SseAssistedBinary; + case Iop_Max32Ux4: + fn = (HWord)h_generic_calc_Max32Ux4; + goto do_SseAssistedBinary; + case Iop_Min32Ux4: + fn = (HWord)h_generic_calc_Min32Ux4; + goto do_SseAssistedBinary; + case Iop_Mul32x4: + fn = (HWord)h_generic_calc_Mul32x4; + goto do_SseAssistedBinary; + case Iop_SarN64x2: + fn = (HWord)h_generic_calc_SarN64x2; + goto do_SseAssistedVectorAndScalar; + case Iop_SarN8x16: + fn = (HWord)h_generic_calc_SarN8x16; + goto do_SseAssistedVectorAndScalar; do_SseAssistedBinary: { /* As with the amd64 case (where this is copied from) we generate pretty bad code. */ @@ -3915,6 +3951,51 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, const IRExpr* e ) return dst; } + do_SseAssistedVectorAndScalar: { + /* RRRufff! RRRufff code is what we're generating here. Oh + well. */ + vassert(fn != 0); + HReg dst = newVRegV(env); + HReg argL = iselVecExpr(env, e->Iex.Binop.arg1); + HReg argR = iselIntExpr_R(env, e->Iex.Binop.arg2); + HReg argp = newVRegI(env); + + /* Allocate stack space*/ + sub_from_esp(env, 112); + /* leal 48(%esp), %argp -- point into it */ + addInstr(env, X86Instr_Lea32(X86AMode_IR(48, hregX86_ESP()), + argp)); + /* andl $-16, %argp -- 16-align the pointer */ + addInstr(env, X86Instr_Alu32R(Xalu_AND, + X86RMI_Imm( ~(UInt)15 ), + argp)); + /* Prepare 2 vector arg regs: + leal 0(%argp), %eax result pointer + leal 16(%argp), %edx + */ + addInstr(env, X86Instr_Lea32(X86AMode_IR(0, argp), + hregX86_EAX())); + addInstr(env, X86Instr_Lea32(X86AMode_IR(16, argp), + hregX86_EDX())); + /* Store the vector arg, at (%edx): + movupd %argL, 0(%edx) + */ + addInstr(env, X86Instr_SseLdSt(False/*!isLoad*/, argL, + X86AMode_IR(0, hregX86_EDX()))); + /* And get the scalar value into ecx */ + addInstr(env, mk_iMOVsd_RR(argR, hregX86_ECX())); + + /* call the helper */ + addInstr(env, X86Instr_Call( Xcc_ALWAYS, (Addr32)fn, + 3, mk_RetLoc_simple(RLPri_None) )); + /* fetch the result from memory, using %argp */ + addInstr(env, X86Instr_SseLdSt(True/*isLoad*/, dst, + X86AMode_IR(0, argp))); + /* and finally, clear the space */ + add_to_esp(env, 112); + return dst; + } + default: break; } /* switch (e->Iex.Binop.op) */ @@ -4562,7 +4643,7 @@ HInstrArray* iselSB_X86 ( const IRSB* bb, { Int i, j; HReg hreg, hregHI; - ISelEnv* env; + ISelEnv *env, envmem; UInt hwcaps_host = archinfo_host->hwcaps; X86AMode *amCounter, *amFailAddr; @@ -4579,7 +4660,7 @@ HInstrArray* iselSB_X86 ( const IRSB* bb, vassert(archinfo_host->endness == VexEndnessLE); /* Make up an initial environment to use. */ - env = LibVEX_Alloc_inline(sizeof(ISelEnv)); + env = &envmem; env->vreg_ctr = 0; /* Set up output code array. */ diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 08e4587f1b..5e3cb7ad80 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -780,9 +780,9 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, const VexAbiInfo*, Int, Int, Bool, Bool, Addr ); Int (*emit) ( /*MB_MOD*/Bool*, - UChar*, Int, const HInstr*, Bool, VexEndness, - const void*, const void*, const void*, - const void* ); + UChar*, Int, const HInstr*, Bool, + const VexArchInfo*, const void*, + const void*, const void*, const void* ); Bool (*preciseMemExnsFn) ( Int, Int, VexRegisterUpdates ); const RRegUniverse* rRegUniv = NULL; @@ -1232,7 +1232,7 @@ static void libvex_BackEnd ( const VexTranslateArgs *vta, } j = emit( &hi_isProfInc, insn_bytes, sizeof insn_bytes, hi, - mode64, vta->archinfo_host.endness, + mode64, &vta->archinfo_host, vta->disp_cp_chain_me_to_slowEP, vta->disp_cp_chain_me_to_fastEP, vta->disp_cp_xindir, @@ -1536,11 +1536,6 @@ const HChar* LibVEX_EmNote_string ( VexEmNote ew ) return "PPC64 function redirection stack overflow"; case EmWarn_PPC64_redir_underflow: return "PPC64 function redirection stack underflow"; - case EmWarn_S390X_fpext_rounding: - return "The specified rounding mode cannot be supported. That\n" - " feature requires the floating point extension facility\n" - " which is not available on this host. Continuing using\n" - " the rounding mode from FPC. Results may differ!"; case EmWarn_S390X_XxC_not_zero: return "Encountered an insn with the IEEE-inexact-exception control\n" " (XxC) bit set to 1. This is not supported. Continuing anyway.\n" @@ -1549,20 +1544,6 @@ const HChar* LibVEX_EmNote_string ( VexEmNote ew ) return "Encountered an insn with the IEEE-invalid-operation-exception\n" " control (XiC) bit set to 1. This is not supported. Continuing anyway.\n" " IEEE-invalid-operation exceptions will not be suppressed."; - case EmFail_S390X_stfle: - return "Instruction stfle is not supported on this host"; - case EmFail_S390X_stckf: - return "Instruction stckf is not supported on this host"; - case EmFail_S390X_ecag: - return "Instruction ecag is not supported on this host"; - case EmFail_S390X_pfpo: - return "Instruction pfpo is not supported on this host"; - case EmFail_S390X_DFP_insn: - return "DFP instructions are not supported on this host"; - case EmFail_S390X_fpext: - return "Encountered an instruction that requires the floating " - "point extension facility.\n" - " That facility is not available on this host"; case EmFail_S390X_invalid_PFPO_rounding_mode: return "The rounding mode in GPR 0 for the PFPO instruction" " is invalid"; @@ -1594,14 +1575,6 @@ const HChar* LibVEX_EmNote_string ( VexEmNote ew ) return "Encountered an instruction that requires the vector-packed-decimal\n" " facility.\n" " That facility is not available on this host"; - case EmFail_S390X_msa: - return "Encountered an instruction that requires the message-security" - " assist.\n" - " That assist is not available on this host"; - case EmFail_S390X_msa4: - return "Encountered an instruction that requires the" - " message-security-assist extension 4.\n" - " That extension is not available on this host"; case EmFail_S390X_msa8: return "Encountered an instruction that requires the" " message-security-assist extension 8.\n" @@ -1610,6 +1583,10 @@ const HChar* LibVEX_EmNote_string ( VexEmNote ew ) return "Encountered an instruction that requires the" " message-security-assist extension 9.\n" " That extension is not available on this host"; + case EmFail_S390X_vxe3: + return "Encountered an instruction that requires the vector-enhancements\n" + " facility 3.\n" + " That facility is not available on this host"; default: vpanic("LibVEX_EmNote_string: unknown warning"); } @@ -1922,23 +1899,11 @@ static const HChar* show_hwcaps_arm64 ( UInt hwcaps ) static const HChar* show_hwcaps_s390x ( UInt hwcaps ) { - static const HChar prefix[] = "s390x"; static const struct { UInt hwcaps_bit; HChar name[6]; } hwcaps_list[] = { - { VEX_HWCAPS_S390X_LDISP, "ldisp" }, - { VEX_HWCAPS_S390X_EIMM, "eimm" }, - { VEX_HWCAPS_S390X_GIE, "gie" }, - { VEX_HWCAPS_S390X_DFP, "dfp" }, - { VEX_HWCAPS_S390X_FGX, "fgx" }, - { VEX_HWCAPS_S390X_STFLE, "stfle" }, - { VEX_HWCAPS_S390X_ETF2, "etf2" }, - { VEX_HWCAPS_S390X_ETF3, "etf3" }, - { VEX_HWCAPS_S390X_STCKF, "stckf" }, - { VEX_HWCAPS_S390X_FPEXT, "fpext" }, - { VEX_HWCAPS_S390X_LSC, "lsc" }, - { VEX_HWCAPS_S390X_PFPO, "pfpo" }, + { VEX_HWCAPS_S390X_MRMM, "z196" }, /* always first */ { VEX_HWCAPS_S390X_VX, "vx" }, { VEX_HWCAPS_S390X_MSA5, "msa5" }, { VEX_HWCAPS_S390X_MI2, "mi2" }, @@ -1948,14 +1913,14 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps ) { VEX_HWCAPS_S390X_DFLT, "dflt" }, { VEX_HWCAPS_S390X_VXE2, "vxe2" }, { VEX_HWCAPS_S390X_VXD, "vxd" }, - { VEX_HWCAPS_S390X_MSA, "msa" }, - { VEX_HWCAPS_S390X_MSA4, "msa4" }, { VEX_HWCAPS_S390X_MSA8, "msa8" }, { VEX_HWCAPS_S390X_MSA9, "msa9" }, + { VEX_HWCAPS_S390X_MI3, "mi3" }, + { VEX_HWCAPS_S390X_VXE3, "vxe3" }, + { VEX_HWCAPS_S390X_MSA12, "msa12" }, }; /* Allocate a large enough buffer */ - static HChar buf[sizeof prefix + - NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) + 1]; // '\0' + static HChar buf[NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) + 1]; // '\0' if (buf[0] != '\0') return buf; /* already constructed */ @@ -1964,8 +1929,8 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps ) hwcaps = VEX_HWCAPS_S390X(hwcaps); - p = buf + vex_sprintf(buf, "%s", prefix); - for (i = 0 ; i < NUM_HWCAPS; ++i) { + p = buf + vex_sprintf(buf, "%s", hwcaps_list[0].name); + for (i = 1 ; i < NUM_HWCAPS; ++i) { if (hwcaps & hwcaps_list[i].hwcaps_bit) p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name); } @@ -2303,9 +2268,6 @@ static void check_hwcaps ( VexArch arch, UInt hwcaps ) } case VexArchS390X: - if (! s390_host_has_ldisp) - invalid_hwcaps(arch, hwcaps, - "Host does not have long displacement facility.\n"); return; case VexArchMIPS32: diff --git a/VEX/priv/main_util.c b/VEX/priv/main_util.c index 8d99eab83f..5d40ca0f91 100644 --- a/VEX/priv/main_util.c +++ b/VEX/priv/main_util.c @@ -258,10 +258,6 @@ void vpanic ( const HChar* str ) /*--- vex_printf ---*/ /*---------------------------------------------------------*/ -/* This should be the only <...> include in the entire VEX library. - New code for vex_util.c should go above this point. */ -#include - SizeT vex_strlen ( const HChar* str ) { SizeT i = 0; @@ -466,6 +462,7 @@ UInt vprintf_wrk ( void(*sink)(HChar), PAD(len1); PUTSTR(str); PAD(len3); break; } + case 'i': case 'd': { Long l; vassert(is_sizet == False); // %zd is obscure; we don't allow it @@ -609,18 +606,25 @@ static void add_to_vg_sprintf_buf ( HChar c ) *vg_sprintf_ptr++ = c; } -UInt vex_sprintf ( HChar* buf, const HChar *format, ... ) +UInt vex_vsprintf ( HChar* buf, const HChar* format, va_list vargs ) { - Int ret; - va_list vargs; + UInt ret; vg_sprintf_ptr = buf; + ret = vprintf_wrk(add_to_vg_sprintf_buf, format, vargs); + add_to_vg_sprintf_buf('\0'); - va_start(vargs,format); + vassert(vex_strlen(buf) == ret); + return ret; +} - ret = vprintf_wrk ( add_to_vg_sprintf_buf, format, vargs ); - add_to_vg_sprintf_buf(0); +UInt vex_sprintf ( HChar* buf, const HChar *format, ... ) +{ + UInt ret; + va_list vargs; + va_start(vargs,format); + ret = vex_vsprintf(buf, format, vargs); va_end(vargs); vassert(vex_strlen(buf) == ret); diff --git a/VEX/priv/main_util.h b/VEX/priv/main_util.h index 4abae5440e..9d278305f8 100644 --- a/VEX/priv/main_util.h +++ b/VEX/priv/main_util.h @@ -34,6 +34,9 @@ #ifndef __VEX_MAIN_UTIL_H #define __VEX_MAIN_UTIL_H +/* This should be the only <...> include in the entire VEX library. */ +#include + #include "libvex_basictypes.h" #include "libvex_inner.h" @@ -92,6 +95,9 @@ extern UInt vex_printf ( const HChar *format, ... ); __attribute__ ((format (printf, 2, 3))) extern UInt vex_sprintf ( HChar* buf, const HChar *format, ... ); +__attribute__ ((format (printf, 2, 0))) +extern UInt vex_vsprintf ( HChar* buf, const HChar* format, va_list vargs ); + /* String ops */ diff --git a/VEX/priv/objdump/README b/VEX/priv/objdump/README new file mode 100644 index 0000000000..9ed56d2531 --- /dev/null +++ b/VEX/priv/objdump/README @@ -0,0 +1,16 @@ +Files imported from binutils distribution: 2.45 + +/include/dis-asm.h -> dis-asm.h modified +/include/opcode/s390.h -> s390.h unchanged +/opcodes/dis-init.c -> dis-init.c modified +/opcodes/s390-dis.c -> s390-dis.c modified +/opcodes/s390-opc.c -> s390-opc.c modified + +s390-opc.tab generated from +/opcodes/s390-opc.txt via +/opcodes/mkopc.c + +gcc mkopc.c +./a.out < s390-opc.txt > s390-opc.tab + +Might not be worth the trouble to write an update-objdump script. diff --git a/VEX/priv/objdump/dis-asm.h b/VEX/priv/objdump/dis-asm.h new file mode 100644 index 0000000000..4ca3320c12 --- /dev/null +++ b/VEX/priv/objdump/dis-asm.h @@ -0,0 +1,502 @@ +/* Interface between the opcode library and its callers. + + Copyright (C) 1999-2025 Free Software Foundation, Inc. + + 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 3, 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. + + Written by Cygnus Support, 1993. + + The opcode library (libopcodes.a) provides instruction decoders for + a large variety of instruction sets, callable with an identical + interface, for making instruction-processing programs more independent + of the instruction set being processed. */ + +#ifndef DIS_ASM_H +#define DIS_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stubs.h" + +enum dis_insn_type +{ + dis_noninsn, /* Not a valid instruction. */ + dis_nonbranch, /* Not a branch instruction. */ + dis_branch, /* Unconditional branch. */ + dis_condbranch, /* Conditional branch. */ + dis_jsr, /* Jump to subroutine. */ + dis_condjsr, /* Conditional jump to subroutine. */ + dis_dref, /* Data reference instruction. */ + dis_dref2 /* Two data references in instruction. */ +}; + +/* When printing styled disassembler output, this describes what style + should be used. */ + +enum disassembler_style +{ + /* This is the default style, use this for any additional syntax + (e.g. commas between operands, brackets, etc), or just as a default if + no other style seems appropriate. */ + dis_style_text, + + /* Use this for all instruction mnemonics, or aliases for mnemonics. + These should be things that correspond to real machine + instructions. */ + dis_style_mnemonic, + + /* Some architectures include additional mnemonic like fields within the + instruction operands, e.g. on aarch64 'add w16, w7, w1, lsl #2' where + the 'lsl' is an additional piece of text that describes how the + instruction should behave. This sub-mnemonic style can be used for + these pieces of text. */ + dis_style_sub_mnemonic, + + /* For things that aren't real machine instructions, but rather + assembler directives, e.g. .byte, etc. */ + dis_style_assembler_directive, + + /* Use this for any register names. This may or may-not include any + register prefix, e.g. '$', '%', at the discretion of the target, + though within each target the choice to include prefixes for not + should be kept consistent. If the prefix is not printed with this + style, then dis_style_text should be used. */ + dis_style_register, + + /* Use this for any constant values used within instructions or + directives, unless the value is an absolute address, or an offset + that will be added to an address (no matter where the address comes + from) before use. This style may, or may-not be used for any + prefix to the immediate value, e.g. '$', at the discretion of the + target, though within each target the choice to include these + prefixes should be kept consistent. */ + dis_style_immediate, + + /* The style for the numerical representation of an absolute address. + Anything that is an address offset should use the immediate style. + This style may, or may-not be used for any prefix to the immediate + value, e.g. '$', at the discretion of the target, though within + each target the choice to include these prefixes should be kept + consistent. */ + dis_style_address, + + /* The style for any constant value within an instruction or directive + that represents an offset that will be added to an address before + use. This style may, or may-not be used for any prefix to the + immediate value, e.g. '$', at the discretion of the target, though + within each target the choice to include these prefixes should be + kept consistent. */ + dis_style_address_offset, + + /* The style for a symbol's name. The numerical address of a symbol + should use the address style above, this style is reserved for the + name. */ + dis_style_symbol, + + /* The start of a comment that runs to the end of the line. Anything + printed after a comment start might be styled differently, + e.g. everything might be styled as a comment, regardless of the + actual style used. The disassembler itself should not try to adjust + the style emitted for comment content, e.g. an address emitted within + a comment should still be given dis_style_address, in this way it is + up to the user of the disassembler to decide how comments should be + styled. */ + dis_style_comment_start +}; + +typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2; +typedef int (*fprintf_styled_ftype) (void *, enum disassembler_style, const char*, ...) ATTRIBUTE_FPTR_PRINTF_3; + +/* This struct is passed into the instruction decoding routine, + and is passed back out into each callback. The various fields are used + for conveying information from your main routine into your callbacks, + for passing information into the instruction decoders (such as the + addresses of the callback functions), or for passing information + back from the instruction decoders to their callers. + + It must be initialized before it is first passed; this can be done + by hand, or using one of the initialization macros below. */ + +typedef struct disassemble_info +{ + fprintf_ftype fprintf_func; + fprintf_styled_ftype fprintf_styled_func; + void *stream; +#if 0 + void *application_data; + + /* Target description. We could replace this with a pointer to the bfd, + but that would require one. There currently isn't any such requirement + so to avoid introducing one we record these explicitly. */ + /* The bfd_flavour. This can be bfd_target_unknown_flavour. */ + enum bfd_flavour flavour; + /* The bfd_arch value. */ + enum bfd_architecture arch; + /* The bfd_mach value. */ + unsigned long mach; + /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ + enum bfd_endian endian; + /* Endianness of code, for mixed-endian situations such as ARM BE8. */ + enum bfd_endian endian_code; + + /* Some targets need information about the current section to accurately + display insns. If this is NULL, the target disassembler function + will have to make its best guess. */ + asection *section; + + /* An array of pointers to symbols either at the location being disassembled + or at the start of the function being disassembled. The array is sorted + so that the first symbol is intended to be the one used. The others are + present for any misc. purposes. This is not set reliably, but if it is + not NULL, it is correct. */ + asymbol **symbols; + /* Number of symbols in array. */ + int num_symbols; + + /* Symbol table provided for targets that want to look at it. This is + used on Arm to find mapping symbols and determine Arm/Thumb code. */ + asymbol **symtab; + int symtab_pos; + int symtab_size; + + /* For use by the disassembler. + The top 16 bits are reserved for public use (and are documented here). + The bottom 16 bits are for the internal use of the disassembler. */ + unsigned long flags; + /* Set if the disassembler has determined that there are one or more + relocations associated with the instruction being disassembled. */ +#define INSN_HAS_RELOC (1u << 31) + /* Set if the user has requested the disassembly of data as well as code. */ +#define DISASSEMBLE_DATA (1u << 30) + /* Set if the user has specifically set the machine type encoded in the + mach field of this structure. */ +#define USER_SPECIFIED_MACHINE_TYPE (1u << 29) + /* Set if the user has requested wide output. */ +#define WIDE_OUTPUT (1u << 28) + + /* Dynamic relocations, if they have been loaded. */ + arelent **dynrelbuf; + long dynrelcount; + + /* Use internally by the target specific disassembly code. */ + void *private_data; + + /* Function used to get bytes to disassemble. MEMADDR is the + address of the stuff to be disassembled, MYADDR is the address to + put the bytes in, and LENGTH is the number of bytes to read. + INFO is a pointer to this struct. + Returns an errno value or 0 for success. */ + int (*read_memory_func) + (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, + struct disassemble_info *dinfo); + + /* Function which should be called if we get an error that we can't + recover from. STATUS is the errno value from read_memory_func and + MEMADDR is the address that we were trying to read. INFO is a + pointer to this struct. */ + void (*memory_error_func) + (int status, bfd_vma memaddr, struct disassemble_info *dinfo); +#endif + + /* Function called to print ADDR. */ + void (*print_address_func) + (bfd_vma addr, struct disassemble_info *dinfo); + +#if 0 + /* Function called to determine if there is a symbol at the given ADDR. + If there is, the function returns 1, otherwise it returns 0. + This is used by ports which support an overlay manager where + the overlay number is held in the top part of an address. In + some circumstances we want to include the overlay number in the + address, (normally because there is a symbol associated with + that address), but sometimes we want to mask out the overlay bits. */ + asymbol * (*symbol_at_address_func) + (bfd_vma addr, struct disassemble_info *dinfo); + + /* Function called to check if a SYMBOL is can be displayed to the user. + This is used by some ports that want to hide special symbols when + displaying debugging outout. */ + bool (*symbol_is_valid) + (asymbol *, struct disassemble_info *dinfo); + + /* These are for buffer_read_memory. */ + bfd_byte *buffer; + bfd_vma buffer_vma; + size_t buffer_length; + + /* This variable may be set by the instruction decoder. It suggests + the number of bytes objdump should display on a single line. If + the instruction decoder sets this, it should always set it to + the same value in order to get reasonable looking output. */ + int bytes_per_line; + + /* The next two variables control the way objdump displays the raw data. */ + /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ + /* output will look like this: + 00: 00000000 00000000 + with the chunks displayed according to "display_endian". */ + int bytes_per_chunk; + enum bfd_endian display_endian; + + /* Number of octets per incremented target address + Normally one, but some DSPs have byte sizes of 16 or 32 bits. */ + unsigned int octets_per_byte; + + /* The number of zeroes we want to see at the end of a section before we + start skipping them. */ + unsigned int skip_zeroes; + + /* The number of zeroes to skip at the end of a section. If the number + of zeroes at the end is between SKIP_ZEROES_AT_END and SKIP_ZEROES, + they will be disassembled. If there are fewer than + SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic + attempt to avoid disassembling zeroes inserted by section + alignment. */ + unsigned int skip_zeroes_at_end; + + /* Whether the disassembler always needs the relocations. */ + bool disassembler_needs_relocs; +#endif + + /* Results from instruction decoders. Not all decoders yet support + this information. This info is set each time an instruction is + decoded, and is only valid for the last such instruction. + + To determine whether this decoder supports this information, set + insn_info_valid to 0, decode an instruction, then check it. */ + + char insn_info_valid; /* Branch info has been set. */ + char branch_delay_insns; /* How many sequential insn's will run before + a branch takes effect. (0 = normal) */ + char data_size; /* Size of data reference in insn, in bytes */ + enum dis_insn_type insn_type; /* Type of instruction */ + bfd_vma target; /* Target address of branch or dref, if known; + zero if unknown. */ + bfd_vma target2; /* Second target address for dref2 */ + + /* Command line options specific to the target disassembler. */ + const char *disassembler_options; + + /* If non-zero then try not disassemble beyond this address, even if + there are values left in the buffer. This address is the address + of the nearest symbol forwards from the start of the disassembly, + and it is assumed that it lies on the boundary between instructions. + If an instruction spans this address then this is an error in the + file being disassembled. */ + bfd_vma stop_vma; + + /* The end range of the current range being disassembled. This is required + in order to notify the disassembler when it's currently handling a + different range than it was before. This prevent unsafe optimizations when + disassembling such as the way mapping symbols are found on AArch64. */ + bfd_vma stop_offset; + + /* Set to true if the disassembler applied styling to the output, + otherwise, set to false. */ + bool created_styled_output; +} disassemble_info; + +#if 0 +/* This struct is used to pass information about valid disassembler + option arguments from the target to the generic GDB functions + that set and display them. */ + +typedef struct +{ + /* Option argument name to use in descriptions. */ + const char *name; + + /* Vector of acceptable option argument values, NULL-terminated. + NULL if any values are accepted. */ + const char **values; +} disasm_option_arg_t; + +/* This struct is used to pass information about valid disassembler + options, their descriptions and arguments from the target to the + generic GDB functions that set and display them. Options are + defined by tuples of vector entries at each index. */ + +typedef struct +{ + /* Vector of option names, NULL-terminated. */ + const char **name; + + /* Vector of option descriptions or NULL if none to be shown. */ + const char **description; + + /* Vector of option argument information pointers or NULL if no + option accepts an argument. NULL entries denote individual + options that accept no argument. */ + const disasm_option_arg_t **arg; +} disasm_options_t; + +/* This struct is used to pass information about valid disassembler + options and arguments from the target to the generic GDB functions + that set and display them. */ + +typedef struct +{ + /* Valid disassembler options. Individual options that support + an argument will refer to entries in the ARGS vector. */ + disasm_options_t options; + + /* Vector of acceptable option arguments, NULL-terminated. This + collects all possible option argument choices, some of which + may be shared by different options from the OPTIONS member. */ + disasm_option_arg_t *args; +} disasm_options_and_args_t; + +/* Standard disassemblers. Disassemble one instruction at the given + target address. Return number of octets processed. */ +typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); + +/* Disassemblers used out side of opcodes library. */ +extern int print_insn_m32c (bfd_vma, disassemble_info *); +extern int print_insn_mep (bfd_vma, disassemble_info *); +extern int print_insn_s12z (bfd_vma, disassemble_info *); +extern int print_insn_sh (bfd_vma, disassemble_info *); +extern int print_insn_sparc (bfd_vma, disassemble_info *); +extern int print_insn_rx (bfd_vma, disassemble_info *); +extern int print_insn_rl78 (bfd_vma, disassemble_info *); +extern int print_insn_rl78_g10 (bfd_vma, disassemble_info *); +extern int print_insn_rl78_g13 (bfd_vma, disassemble_info *); +extern int print_insn_rl78_g14 (bfd_vma, disassemble_info *); + +extern disassembler_ftype arc_get_disassembler (bfd *); +extern disassembler_ftype cris_get_disassembler (bfd *); + +extern void print_aarch64_disassembler_options (FILE *); +extern void print_i386_disassembler_options (FILE *); +extern void print_mips_disassembler_options (FILE *); +extern void print_nfp_disassembler_options (FILE *); +extern void print_ppc_disassembler_options (FILE *); +extern void print_riscv_disassembler_options (FILE *); +extern void print_arm_disassembler_options (FILE *); +extern void print_arc_disassembler_options (FILE *); +extern void print_kvx_disassembler_options(FILE *); +extern void print_s390_disassembler_options (FILE *); +extern void print_wasm32_disassembler_options (FILE *); +extern void print_loongarch_disassembler_options (FILE *); +extern void print_bpf_disassembler_options (FILE *); +extern bool aarch64_symbol_is_valid (asymbol *, struct disassemble_info *); +extern bool arm_symbol_is_valid (asymbol *, struct disassemble_info *); +extern bool csky_symbol_is_valid (asymbol *, struct disassemble_info *); +extern bool riscv_symbol_is_valid (asymbol *, struct disassemble_info *); +extern void disassemble_init_powerpc (struct disassemble_info *); +#endif +extern void disassemble_init_s390 (struct disassemble_info *); +#if 0 +extern void disassemble_init_wasm32 (struct disassemble_info *); +extern void disassemble_init_nds32 (struct disassemble_info *); +extern const disasm_options_and_args_t *disassembler_options_arc (void); +extern const disasm_options_and_args_t *disassembler_options_arm (void); +extern const disasm_options_and_args_t *disassembler_options_mips (void); +extern const disasm_options_and_args_t *disassembler_options_powerpc (void); +extern const disasm_options_and_args_t *disassembler_options_riscv (void); +extern const disasm_options_and_args_t *disassembler_options_s390 (void); + +/* Fetch the disassembler for a given architecture ARC, endianess (big + endian if BIG is true), bfd_mach value MACH, and ABFD, if that support + is available. ABFD may be NULL. */ +extern disassembler_ftype disassembler (enum bfd_architecture arc, + bool big, unsigned long mach, + bfd *abfd); + +/* Amend the disassemble_info structure as necessary for the target architecture. + Should only be called after initialising the info->arch field. */ +extern void disassemble_init_for_target (struct disassemble_info *); + +/* Tidy any memory allocated by targets, such as info->private_data. */ +extern void disassemble_free_target (struct disassemble_info *); + +/* Set the basic disassembler print functions. */ +extern void disassemble_set_printf (struct disassemble_info *, void *, + fprintf_ftype, fprintf_styled_ftype); + +/* Document any target specific options available from the disassembler. */ +extern void disassembler_usage (FILE *); + +/* Remove whitespace and consecutive commas. */ +extern char *remove_whitespace_and_extra_commas (char *); + +/* Like STRCMP, but treat ',' the same as '\0' so that we match + strings like "foobar" against "foobar,xxyyzz,...". */ +extern int disassembler_options_cmp (const char *, const char *); + +/* A helper function for FOR_EACH_DISASSEMBLER_OPTION. */ +static inline const char * +next_disassembler_option (const char *options) +{ + const char *opt = strchr (options, ','); + if (opt != NULL) + opt++; + return opt; +} + +/* A macro for iterating over each comma separated option in OPTIONS. */ +#define FOR_EACH_DISASSEMBLER_OPTION(OPT, OPTIONS) \ + for ((OPT) = (OPTIONS); \ + (OPT) != NULL; \ + (OPT) = next_disassembler_option (OPT)) + + +/* This block of definitions is for particular callers who read instructions + into a buffer before calling the instruction decoder. */ + +/* Here is a function which callers may wish to use for read_memory_func. + It gets bytes from a buffer. */ +extern int buffer_read_memory + (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *); + +/* This function goes with buffer_read_memory. + It prints a message using info->fprintf_func and info->stream. */ +extern void perror_memory (int, bfd_vma, struct disassemble_info *); + + +/* Just print the address in hex. This is included for completeness even + though both GDB and objdump provide their own (to print symbolic + addresses). */ +extern void generic_print_address + (bfd_vma, struct disassemble_info *); + +/* Always NULL. */ +extern asymbol *generic_symbol_at_address + (bfd_vma, struct disassemble_info *); + +/* Always true. */ +extern bool generic_symbol_is_valid + (asymbol *, struct disassemble_info *); + +#endif + +/* Method to initialize a disassemble_info struct. This should be + called by all applications creating such a struct. */ +extern void init_disassemble_info (struct disassemble_info *dinfo, void *stream, + fprintf_ftype fprintf_func, + fprintf_styled_ftype fprintf_styled_func); + +/* For compatibility with existing code. */ +#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC, FPRINTF_STYLED_FUNC) \ + init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC), \ + (fprintf_styled_ftype) (FPRINTF_STYLED_FUNC)) + +#ifdef __cplusplus +} +#endif + +#endif /* ! defined (DIS_ASM_H) */ diff --git a/VEX/priv/objdump/dis-init.c b/VEX/priv/objdump/dis-init.c new file mode 100644 index 0000000000..8a10ee31d0 --- /dev/null +++ b/VEX/priv/objdump/dis-init.c @@ -0,0 +1,56 @@ +/* Initialize "struct disassemble_info". + + Copyright (C) 2003-2025 Free Software Foundation, Inc. + + This file is part of the GNU opcodes library. + + This library 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 3, or (at your option) + any later version. + + It 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 "dis-asm.h" + +void +init_disassemble_info (struct disassemble_info *info, void *stream, + fprintf_ftype fprintf_func, + fprintf_styled_ftype fprintf_styled_func) +{ +#if 0 + memset(info, 0, sizeof (*info)); + + info->flavour = bfd_target_unknown_flavour; + info->arch = bfd_arch_unknown; + info->endian = BFD_ENDIAN_UNKNOWN; + info->endian_code = info->endian; + info->octets_per_byte = 1; + info->fprintf_func = fprintf_func; + info->fprintf_styled_func = fprintf_styled_func; + info->stream = stream; + info->read_memory_func = buffer_read_memory; + info->memory_error_func = perror_memory; + info->print_address_func = generic_print_address; + info->symbol_at_address_func = generic_symbol_at_address; + info->symbol_is_valid = generic_symbol_is_valid; + info->display_endian = BFD_ENDIAN_UNKNOWN; + info->created_styled_output = false; +#else + __builtin_memset(info, 0, sizeof (*info)); + + info->fprintf_func = fprintf_func; + info->fprintf_styled_func = fprintf_styled_func; + info->stream = stream; + info->print_address_func = 0; +#endif +} + diff --git a/VEX/priv/objdump/s390-dis.c b/VEX/priv/objdump/s390-dis.c new file mode 100644 index 0000000000..0343b211a2 --- /dev/null +++ b/VEX/priv/objdump/s390-dis.c @@ -0,0 +1,708 @@ +/* s390-dis.c -- Disassemble S390 instructions + Copyright (C) 2000-2025 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of the GNU opcodes library. + + This library 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 3, or (at your option) + any later version. + + It 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 file; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include +#include "s390.h" +#include "dis-asm.h" +#undef NULL +#include "main_util.h" // vex_strlen +#include "s390_defs.h" // S390_MAX_MNEMONIC_LEN +#include "s390_disasm.h" + +static int opc_index[256]; +static int current_arch_mask = 0; +static int option_use_insn_len_bits_p = 0; +static int option_print_insn_desc = 0; +static int pad_mnemonic; + +static const char * +padmnm(const char *mnm) +{ + static char buf[S390_MAX_MNEMONIC_LEN + 1]; + + if (pad_mnemonic) { + if (vex_strlen(mnm) > S390_MAX_MNEMONIC_LEN) + return "failed: buf too small"; + + vex_sprintf(buf, "%-*s", S390_MAX_MNEMONIC_LEN, mnm); + } else { + vex_sprintf(buf, "%s", mnm); + } + + return buf; +} + + +#if 0 +typedef struct +{ + const char *name; + const char *description; +} s390_options_t; + +static const s390_options_t options[] = +{ + { "esa" , N_("Disassemble in ESA architecture mode") }, + /* TRANSLATORS: Please do not translate 'z/Architecture' as this is a technical name. */ + { "zarch", N_("Disassemble in z/Architecture mode") }, + { "insnlength", N_("Print unknown instructions according to " + "length from first two bits") }, + { "insndesc", N_("Print instruction description as comment") }, +}; +#endif + +/* Set up index table for first opcode byte. */ + +void +disassemble_init_s390 (struct disassemble_info *info) +{ + int i; + + __builtin_memset (opc_index, 0, sizeof (opc_index)); + + /* Reverse order, such that each opc_index ends up pointing to the + first matching entry instead of the last. */ + for (i = s390_num_opcodes; i--; ) + opc_index[s390_opcodes[i].opcode[0]] = i; + + current_arch_mask = 1 << S390_OPCODE_ZARCH; + option_use_insn_len_bits_p = 0; + option_print_insn_desc = 0; +#if 0 + for (p = info->disassembler_options; p != NULL; ) + { + if (startswith (p, "esa")) + current_arch_mask = 1 << S390_OPCODE_ESA; + else if (startswith (p, "zarch")) + current_arch_mask = 1 << S390_OPCODE_ZARCH; + else if (startswith (p, "insnlength")) + option_use_insn_len_bits_p = 1; + else if (startswith (p, "insndesc")) + option_print_insn_desc = 1; + else + /* xgettext:c-format */ + opcodes_error_handler (_("unknown S/390 disassembler option: %s"), p); + + p = strchr (p, ','); + if (p != NULL) + p++; + } +#endif +} + +/* Derive the length of an instruction from its first byte. */ + +static inline int +s390_insn_length (const bfd_byte *buffer) +{ + /* 00xxxxxx -> 2, 01xxxxxx/10xxxxxx -> 4, 11xxxxxx -> 6. */ + return ((buffer[0] >> 6) + 3) & ~1U; +} + +/* Match the instruction in BUFFER against the given OPCODE, excluding + the first byte. */ + +static inline int +s390_insn_matches_opcode (const bfd_byte *buffer, + const struct s390_opcode *opcode) +{ + return (buffer[1] & opcode->mask[1]) == opcode->opcode[1] + && (buffer[2] & opcode->mask[2]) == opcode->opcode[2] + && (buffer[3] & opcode->mask[3]) == opcode->opcode[3] + && (buffer[4] & opcode->mask[4]) == opcode->opcode[4] + && (buffer[5] & opcode->mask[5]) == opcode->opcode[5]; +} + +union operand_value +{ + int i; + unsigned int u; +}; + +/* Extracts an operand value from an instruction. */ +/* We do not perform the shift operation for larl-type address + operands here since that would lead to an overflow of the 32 bit + integer value. Instead the shift operation is done when printing + the operand. */ + +static inline union operand_value +s390_extract_operand (const bfd_byte *insn, + const struct s390_operand *operand) +{ + union operand_value ret; + unsigned int val; + int bits; + const bfd_byte *orig_insn = insn; + + /* Extract fragments of the operand byte for byte. */ + insn += operand->shift / 8; + bits = (operand->shift & 7) + operand->bits; + val = 0; + do + { + val <<= 8; + val |= (unsigned int) *insn++; + bits -= 8; + } + while (bits > 0); + val >>= -bits; + val &= ((1U << (operand->bits - 1)) << 1) - 1; + + /* Check for special long displacement case. */ + if (operand->bits == 20 && operand->shift == 20) + val = (val & 0xff) << 12 | (val & 0xfff00) >> 8; + + /* Sign extend value if the operand is signed or pc relative. Avoid + integer overflows. */ + if (operand->flags & (S390_OPERAND_SIGNED | S390_OPERAND_PCREL)) + { + unsigned int m = 1U << (operand->bits - 1); + + if (val >= m) + ret.i = (int) (val - m) - 1 - (int) (m - 1U); + else + ret.i = (int) val; + } + else if (operand->flags & S390_OPERAND_LENGTH) + /* Length x in an instruction has real length x + 1. */ + ret.u = val + 1; + + else if (operand->flags & S390_OPERAND_VR) + { + /* Extract the extra bits for a vector register operand stored + in the RXB field. */ + unsigned vr = operand->shift == 32 ? 3 + : (unsigned) operand->shift / 4 - 2; + + ret.u = val | ((orig_insn[4] & (1 << (3 - vr))) << (vr + 1)); + } + else + ret.u = val; + + return ret; +} + +/* Return remaining operand count. */ + +static unsigned int +operand_count (const unsigned char *opindex_ptr) +{ + unsigned int count = 0; + + for (; *opindex_ptr != 0; opindex_ptr++) + { + /* Count D(X,B), D(B), and D(L,B) as one operand. Assuming correct + instruction operand definitions simply do not count D, X, and L. */ + if (!(s390_operands[*opindex_ptr].flags & (S390_OPERAND_DISP + | S390_OPERAND_INDEX + | S390_OPERAND_LENGTH))) + count++; + } + + return count; +} + +/* Return true if all remaining instruction operands are optional. */ + +static bool +skip_optargs_p (unsigned int opcode_flags, const unsigned char *opindex_ptr) +{ + if ((opcode_flags & (S390_INSTR_FLAG_OPTPARM | S390_INSTR_FLAG_OPTPARM2))) + { + unsigned int opcount = operand_count (opindex_ptr); + + if (opcount == 1) + return true; + + if ((opcode_flags & S390_INSTR_FLAG_OPTPARM2) && opcount == 2) + return true; + } + + return false; +} + +/* Return true if all remaining instruction operands are optional + and their values are zero. */ + +static bool +skip_optargs_zero_p (const bfd_byte *buffer, unsigned int opcode_flags, + const unsigned char *opindex_ptr) +{ + /* Test if remaining operands are optional. */ + if (!skip_optargs_p (opcode_flags, opindex_ptr)) + return false; + + /* Test if remaining operand values are zero. */ + for (; *opindex_ptr != 0; opindex_ptr++) + { + const struct s390_operand *operand = &s390_operands[*opindex_ptr]; + union operand_value value = s390_extract_operand (buffer, operand); + + if (value.u != 0) + return false; + } + + return true; +} + +/* Print the S390 instruction in BUFFER, assuming that it matches the + given OPCODE. */ + +static void +s390_print_insn_with_opcode (bfd_vma memaddr, + struct disassemble_info *info, + const bfd_byte *buffer, + const struct s390_opcode *opcode) +{ + const unsigned char *opindex; + char separator; + + /* Mnemonic. */ + info->fprintf_styled_func (info->stream, dis_style_mnemonic, + "%s", padmnm(opcode->name)); + + /* Operands. */ + separator = ' '; // mnemonics are padded to the right and have same width + for (opindex = opcode->operands; *opindex != 0; opindex++) + { + const struct s390_operand *operand = s390_operands + *opindex; + union operand_value val = s390_extract_operand (buffer, operand); + unsigned long flags = operand->flags; + + /* Omit index register 0, except for vector index register 0. */ + if ((flags & S390_OPERAND_INDEX) && !(flags & S390_OPERAND_VR) + && val.u == 0) + continue; + /* Omit base register 0, if no or omitted index register 0. */ + if ((flags & S390_OPERAND_BASE) && val.u == 0 && separator == '(') + { + separator = ','; + continue; + } + + /* Omit optional last operands with a value of zero, except if + within an addressing operand sequence D(X,B), D(B), and D(L,B). + Index and base register operands with a value of zero are + handled separately, as they may not be omitted unconditionally. */ + if (!(operand->flags & (S390_OPERAND_BASE + | S390_OPERAND_INDEX + | S390_OPERAND_LENGTH)) + && skip_optargs_zero_p (buffer, opcode->flags, opindex)) + break; + + if (flags & S390_OPERAND_GPR) + { + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + if ((flags & (S390_OPERAND_BASE | S390_OPERAND_INDEX)) + && val.u == 0) + info->fprintf_styled_func (info->stream, dis_style_register, + "%u", val.u); + else + info->fprintf_styled_func (info->stream, dis_style_register, + "%%r%u", val.u); + } + else if (flags & S390_OPERAND_FPR) + { + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + info->fprintf_styled_func (info->stream, dis_style_register, + "%%f%u", val.u); + } + else if (flags & S390_OPERAND_VR) + { + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + info->fprintf_styled_func (info->stream, dis_style_register, + "%%v%u", val.u); + } + else if (flags & S390_OPERAND_AR) + { + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + info->fprintf_styled_func (info->stream, dis_style_register, + "%%a%u", val.u); + } + else if (flags & S390_OPERAND_CR) + { + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + info->fprintf_styled_func (info->stream, dis_style_register, + "%%c%u", val.u); + } + else if (flags & S390_OPERAND_PCREL) + { + bfd_vma target = memaddr + val.i + val.i; + + /* Provide info for jump visualization. May be evaluated by p_a_f(). */ + info->target = target; + + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + info->print_address_func (target, info); + } + else if (flags & S390_OPERAND_SIGNED) + { + enum disassembler_style style; + + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + style = ((flags & S390_OPERAND_DISP) + ? dis_style_address_offset : dis_style_immediate); + info->fprintf_styled_func (info->stream, style, "%i", val.i); + } + else + { + enum disassembler_style style; + + if (!(flags & S390_OPERAND_LENGTH)) + { + union operand_value insn_opval; + + /* Mask any constant operand bits set in insn template. */ + insn_opval = s390_extract_operand (opcode->opcode, operand); + val.u &= ~insn_opval.u; + } + + if ((opcode->flags & S390_INSTR_FLAG_OPTPARM) + && val.u == 0 + && opindex[1] == 0) + break; + + info->fprintf_styled_func (info->stream, dis_style_text, + "%c", separator); + style = ((flags & S390_OPERAND_DISP) + ? dis_style_address_offset : dis_style_immediate); + info->fprintf_styled_func (info->stream, style, "%u", val.u); + } + + if (flags & S390_OPERAND_DISP) + separator = '('; + else if (flags & S390_OPERAND_BASE) + { + info->fprintf_styled_func (info->stream, dis_style_text, ")"); + separator = ','; + } + else + separator = ','; + } + + /* Optional: instruction name. */ + if (option_print_insn_desc && opcode->description + && opcode->description[0] != '\0') + info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# %s", + opcode->description); +} + +/* Check whether opcode A's mask is more specific than that of B. */ + +static int +opcode_mask_more_specific (const struct s390_opcode *a, + const struct s390_opcode *b) +{ + return (((int) a->mask[0] + a->mask[1] + a->mask[2] + + a->mask[3] + a->mask[4] + a->mask[5]) + > ((int) b->mask[0] + b->mask[1] + b->mask[2] + + b->mask[3] + b->mask[4] + b->mask[5])); +} + +/* Print a S390 instruction. */ + +static int +print_insn_s390 (bfd_vma memaddr, const bfd_byte *buffer, + struct disassemble_info *info) +{ + const struct s390_opcode *opcode = NULL; + + /* Set some defaults for the insn info. */ + info->insn_info_valid = 0; + info->branch_delay_insns = 0; + info->data_size = 0; + info->insn_type = dis_nonbranch; + info->target = 0; + info->target2 = 0; + +#if 0 + /* Every S390 instruction is max 6 bytes long. */ + memset (buffer, 0, 6); + status = info->read_memory_func (memaddr, buffer, 6, info); + if (status != 0) + { + for (bufsize = 0; bufsize < 6; bufsize++) + if (info->read_memory_func (memaddr, buffer, bufsize + 1, info) != 0) + break; + if (bufsize <= 0) + { + info->memory_error_func (status, memaddr, info); + return -1; + } + opsize = s390_insn_length (buffer); + status = opsize > bufsize; + } + else + { + bufsize = 6; + opsize = s390_insn_length (buffer); + } +#endif + int status = 0; + int opsize = s390_insn_length (buffer); + + if (status == 0) + { + const struct s390_opcode *op; + + /* Find the "best match" in the opcode table. */ + for (op = s390_opcodes + opc_index[buffer[0]]; + op != s390_opcodes + s390_num_opcodes + && op->opcode[0] == buffer[0]; + op++) + { + if ((op->modes & current_arch_mask) + && s390_insn_matches_opcode (buffer, op) + && (opcode == NULL + || opcode_mask_more_specific (op, opcode))) + opcode = op; + } + + if (opcode != NULL) + { + /* Provide info for jump visualization. Must be done before print. */ + switch (opcode->flags & S390_INSTR_FLAG_CLASS_MASK) + { + case S390_INSTR_FLAGS_CLASS_JUMP: + info->insn_type = dis_branch; + break; + case S390_INSTR_FLAGS_CLASS_CONDJUMP: + info->insn_type = dis_condbranch; + break; + case S390_INSTR_FLAGS_CLASS_JUMPSR: + info->insn_type = dis_jsr; + break; + default: + info->insn_type = dis_nonbranch; + } + info->insn_info_valid = 1; + + /* The instruction is valid. Print it and return its size. */ + s390_print_insn_with_opcode (memaddr, info, buffer, opcode); + return opsize; + } + } + return 0; // failed +} + +#if 0 + /* For code sections it makes sense to skip unknown instructions + according to their length bits. */ + if (status == 0 + && option_use_insn_len_bits_p + && info->section != NULL + && (info->section->flags & SEC_CODE)) + bytes_to_dump = opsize; + else + /* By default unknown instructions are printed as .long's/.short' + depending on how many bytes are available. */ + bytes_to_dump = bufsize >= 4 ? 4 : bufsize; + + if (bytes_to_dump == 0) + return 0; + + info->insn_type = dis_noninsn; + info->insn_info_valid = 1; + + /* Fall back to hex print. */ + switch (bytes_to_dump) + { + case 4: + value = (unsigned int) buffer[0]; + value = (value << 8) + (unsigned int) buffer[1]; + value = (value << 8) + (unsigned int) buffer[2]; + value = (value << 8) + (unsigned int) buffer[3]; + info->fprintf_styled_func (info->stream, dis_style_assembler_directive, + ".long"); + info->fprintf_styled_func (info->stream, dis_style_text, + "\t"); + info->fprintf_styled_func (info->stream, dis_style_immediate, + "0x%08x", value); + return 4; + case 2: + value = (unsigned int) buffer[0]; + value = (value << 8) + (unsigned int) buffer[1]; + info->fprintf_styled_func (info->stream, dis_style_assembler_directive, + ".short"); + info->fprintf_styled_func (info->stream, dis_style_text, + "\t"); + info->fprintf_styled_func (info->stream, dis_style_immediate, + "0x%04x", value); + return 2; + default: + info->fprintf_styled_func (info->stream, dis_style_assembler_directive, + ".byte"); + info->fprintf_styled_func (info->stream, dis_style_text, + "\t"); + info->fprintf_styled_func (info->stream, dis_style_immediate, + "0x%02x", (unsigned int) buffer[0]); + for (i = 1; i < bytes_to_dump; i++) + info->fprintf_styled_func (info->stream, dis_style_immediate, + "0x%02x", (unsigned int) buffer[i]); + return bytes_to_dump; + } + return 0; +} + +const disasm_options_and_args_t * +disassembler_options_s390 (void) +{ + static disasm_options_and_args_t *opts_and_args; + + if (opts_and_args == NULL) + { + size_t i, num_options = ARRAY_SIZE (options); + disasm_options_t *opts; + + opts_and_args = XNEW (disasm_options_and_args_t); + opts_and_args->args = NULL; + + opts = &opts_and_args->options; + opts->name = XNEWVEC (const char *, num_options + 1); + opts->description = XNEWVEC (const char *, num_options + 1); + opts->arg = NULL; + for (i = 0; i < num_options; i++) + { + opts->name[i] = options[i].name; + opts->description[i] = _(options[i].description); + } + /* The array we return must be NULL terminated. */ + opts->name[i] = NULL; + opts->description[i] = NULL; + } + + return opts_and_args; +} + +void +print_s390_disassembler_options (FILE *stream) +{ + unsigned int i, max_len = 0; + fprintf (stream, _("\n\ +The following S/390 specific disassembler options are supported for use\n\ +with the -M switch (multiple options should be separated by commas):\n")); + + for (i = 0; i < ARRAY_SIZE (options); i++) + { + unsigned int len = strlen (options[i].name); + if (max_len < len) + max_len = len; + } + + for (i = 0, max_len++; i < ARRAY_SIZE (options); i++) + fprintf (stream, " %s%*c %s\n", + options[i].name, + (int)(max_len - strlen (options[i].name)), ' ', + _(options[i].description)); +} +#endif + + +/* Pseudo FILE object for strings. */ +typedef struct { + char buf[128]; // holds the disassembled insn; large enough + size_t pos; + size_t alloc; + unsigned (*val_vsprintf)(char *, const char *, va_list); // == vex_vsprintf + struct disassemble_info *info; +} SFILE; + +static unsigned +sprintf_cb(SFILE *f, enum disassembler_style style, const char *fmt, ...) +{ + va_list args; + unsigned space = f->alloc - f->pos; + unsigned n; + + va_start(args, fmt); + n = f->val_vsprintf(f->buf + f->pos, fmt, args); + va_end(args); + + if (space <= n) + vassert(0); + + f->pos += n; + + return n; +} + +static void +objdump_print_pcrel(bfd_vma addr, struct disassemble_info *info) +{ + /* this really is a signed offset in bytes */ + long long offset = (long long)addr; + + (*info->fprintf_styled_func)(info->stream, dis_style_text, + (offset < 0) ? ".%lld" : ".+%lld", offset); +} + + +static void +s390_disasm_init(SFILE *dis, unsigned (*fp)(char *, const char *, va_list)) +{ + static struct disassemble_info info; + + init_disassemble_info(&info, dis, NULL, + (fprintf_styled_ftype) sprintf_cb); + disassemble_init_s390(&info); + info.print_address_func = objdump_print_pcrel; + + /* Initialise the SFILE object */ + dis->val_vsprintf = fp; + dis->pos = 0; + dis->alloc = sizeof dis->buf; + dis->buf[0] = '\0'; + dis->info = &info; +} + + +/* Watch out: returned string is allocated in a static buffer and will + be overwritten in the next invocation. */ +HChar * +s390_disasm(const unsigned char insn[], int pad_mnm) +{ + static int initialised = 0; + static SFILE disasm; + + if (! initialised) { + initialised = 1; + s390_disasm_init(&disasm, vex_vsprintf); + } + + pad_mnemonic = pad_mnm; + disasm.pos = 0; /* reset */ + disasm.buf[0] = '\0'; + + /* Passing 0 as an address which is only used for symbolically print + a PC-relative operand like so . That means: in + objdump_print_pcrel we get the offset and can write it out relative to + the current address: .+offset of .-offset */ + int rc = print_insn_s390(/* address */ 0, insn, disasm.info); + + return rc == 0 ? NULL : disasm.buf; +} diff --git a/VEX/priv/objdump/s390-opc.c b/VEX/priv/objdump/s390-opc.c new file mode 100644 index 0000000000..f351aadc47 --- /dev/null +++ b/VEX/priv/objdump/s390-opc.c @@ -0,0 +1,814 @@ +/* s390-opc.c -- S390 opcode list + Copyright (C) 2000-2025 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of the GNU opcodes library. + + This library 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 3, or (at your option) + any later version. + + It 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 file; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "stubs.h" +#include "s390.h" + +/* This file holds the S390 opcode table. The opcode table + includes almost all of the extended instruction mnemonics. This + permits the disassembler to use them, and simplifies the assembler + logic, at the cost of increasing the table size. The table is + strictly constant data, so the compiler should be able to put it in + the .text section. + + This file also holds the operand table. All knowledge about + inserting operands into instructions and vice-versa is kept in this + file. */ + +/* Build-time checks are preferrable over runtime ones. Use this construct + in preference where possible. */ +#ifndef static_assert +#define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); })) +#endif + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +/* The operands table. + The fields are bits, shift, insert, extract, flags. */ + +const struct s390_operand s390_operands[] = +{ +#define UNUSED 0 + { 0, 0, 0 }, /* Indicates the end of the operand list */ + +/* General purpose register operands. */ + +#define R_8 (UNUSED + 1) /* GPR starting at position 8 */ + { 4, 8, S390_OPERAND_GPR }, +#define R_12 (R_8 + 1) /* GPR starting at position 12 */ + { 4, 12, S390_OPERAND_GPR }, +#define R_16 (R_12 + 1) /* GPR starting at position 16 */ + { 4, 16, S390_OPERAND_GPR }, +#define R_20 (R_16 + 1) /* GPR starting at position 20 */ + { 4, 20, S390_OPERAND_GPR }, +#define R_24 (R_20 + 1) /* GPR starting at position 24 */ + { 4, 24, S390_OPERAND_GPR }, +#define R_28 (R_24 + 1) /* GPR starting at position 28 */ + { 4, 28, S390_OPERAND_GPR }, +#define R_CP16_28 (R_28 + 1) /* GPR starting at position 28 */ + { 4, 28, S390_OPERAND_GPR | S390_OPERAND_CP16 }, /* with a copy at pos 16 */ +#define R_32 (R_CP16_28+1) /* GPR starting at position 32 */ + { 4, 32, S390_OPERAND_GPR }, + +/* General purpose register pair operands. */ + +#define RE_8 (R_32 + 1) /* GPR starting at position 8 */ + { 4, 8, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_12 (RE_8 + 1) /* GPR starting at position 12 */ + { 4, 12, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_16 (RE_12 + 1) /* GPR starting at position 16 */ + { 4, 16, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_20 (RE_16 + 1) /* GPR starting at position 20 */ + { 4, 20, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_24 (RE_20 + 1) /* GPR starting at position 24 */ + { 4, 24, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_28 (RE_24 + 1) /* GPR starting at position 28 */ + { 4, 28, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, +#define RE_32 (RE_28 + 1) /* GPR starting at position 32 */ + { 4, 32, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, + +/* Floating point register operands. */ + +#define F_8 (RE_32 + 1) /* FPR starting at position 8 */ + { 4, 8, S390_OPERAND_FPR }, +#define F_12 (F_8 + 1) /* FPR starting at position 12 */ + { 4, 12, S390_OPERAND_FPR }, +#define F_16 (F_12 + 1) /* FPR starting at position 16 */ + { 4, 16, S390_OPERAND_FPR }, +#define F_24 (F_16 + 1) /* FPR starting at position 24 */ + { 4, 24, S390_OPERAND_FPR }, +#define F_28 (F_24 + 1) /* FPR starting at position 28 */ + { 4, 28, S390_OPERAND_FPR }, +#define F_32 (F_28 + 1) /* FPR starting at position 32 */ + { 4, 32, S390_OPERAND_FPR }, + +/* Floating point register pair operands. */ + +#define FE_8 (F_32 + 1) /* FPR starting at position 8 */ + { 4, 8, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, +#define FE_12 (FE_8 + 1) /* FPR starting at position 12 */ + { 4, 12, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, +#define FE_16 (FE_12 + 1) /* FPR starting at position 16 */ + { 4, 16, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, +#define FE_24 (FE_16 + 1) /* FPR starting at position 24 */ + { 4, 24, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, +#define FE_28 (FE_24 + 1) /* FPR starting at position 28 */ + { 4, 28, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, +#define FE_32 (FE_28 + 1) /* FPR starting at position 32 */ + { 4, 32, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, + +/* Vector register operands. */ + +/* For each of these operands and additional bit in the RXB operand is + needed. */ + +#define V_8 (FE_32 + 1) /* Vector reg. starting at position 8 */ + { 4, 8, S390_OPERAND_VR }, +#define V_12 (V_8 + 1) /* Vector reg. starting at position 12 */ + { 4, 12, S390_OPERAND_VR }, +#define V_CP16_12 (V_12 + 1) /* Vector reg. starting at position 12 */ + { 4, 12, S390_OPERAND_VR | S390_OPERAND_CP16 }, /* with a copy at pos 16 */ +#define V_16 (V_CP16_12+1) /* Vector reg. starting at position 16 */ + { 4, 16, S390_OPERAND_VR }, +#define V_32 (V_16 + 1) /* Vector reg. starting at position 32 */ + { 4, 32, S390_OPERAND_VR }, + +/* Access register operands. */ + +#define A_8 (V_32 + 1) /* Access reg. starting at position 8 */ + { 4, 8, S390_OPERAND_AR }, +#define A_12 (A_8 + 1) /* Access reg. starting at position 12 */ + { 4, 12, S390_OPERAND_AR }, +#define A_24 (A_12 + 1) /* Access reg. starting at position 24 */ + { 4, 24, S390_OPERAND_AR }, +#define A_28 (A_24 + 1) /* Access reg. starting at position 28 */ + { 4, 28, S390_OPERAND_AR }, + +/* Control register operands. */ + +#define C_8 (A_28 + 1) /* Control reg. starting at position 8 */ + { 4, 8, S390_OPERAND_CR }, +#define C_12 (C_8 + 1) /* Control reg. starting at position 12 */ + { 4, 12, S390_OPERAND_CR }, + +/* Base register operands. */ + +#define B_16 (C_12 + 1) /* Base register starting at position 16 */ + { 4, 16, S390_OPERAND_BASE | S390_OPERAND_GPR }, +#define B_32 (B_16 + 1) /* Base register starting at position 32 */ + { 4, 32, S390_OPERAND_BASE | S390_OPERAND_GPR }, + +#define X_12 (B_32 + 1) /* Index register starting at position 12 */ + { 4, 12, S390_OPERAND_INDEX | S390_OPERAND_GPR }, + +#define VX_12 (X_12+1) /* Vector index register starting at position 12 */ + { 4, 12, S390_OPERAND_INDEX | S390_OPERAND_VR }, + +/* Address displacement operands. */ + +#define D_20 (VX_12 + 1) /* Displacement starting at position 20 */ + { 12, 20, S390_OPERAND_DISP }, +#define D_36 (D_20 + 1) /* Displacement starting at position 36 */ + { 12, 36, S390_OPERAND_DISP }, +#define D20_20 (D_36 + 1) /* 20 bit displacement starting at 20 */ + { 20, 20, S390_OPERAND_DISP | S390_OPERAND_SIGNED }, + +/* Length operands. */ + +#define L4_8 (D20_20 + 1) /* 4 bit length starting at position 8 */ + { 4, 8, S390_OPERAND_LENGTH }, +#define L4_12 (L4_8 + 1) /* 4 bit length starting at position 12 */ + { 4, 12, S390_OPERAND_LENGTH }, +#define L8_8 (L4_12 + 1) /* 8 bit length starting at position 8 */ + { 8, 8, S390_OPERAND_LENGTH }, + +/* Signed immediate operands. */ + +#define I8_8 (L8_8 + 1) /* 8 bit signed value starting at 8 */ + { 8, 8, S390_OPERAND_SIGNED }, +#define I8_32 (I8_8 + 1) /* 8 bit signed value starting at 32 */ + { 8, 32, S390_OPERAND_SIGNED }, +#define I12_12 (I8_32 + 1) /* 12 bit signed value starting at 12 */ + { 12, 12, S390_OPERAND_SIGNED }, +#define I16_16 (I12_12 + 1) /* 16 bit signed value starting at 16 */ + { 16, 16, S390_OPERAND_SIGNED }, +#define I16_32 (I16_16 + 1) /* 16 bit signed value starting at 32 */ + { 16, 32, S390_OPERAND_SIGNED }, +#define I24_24 (I16_32 + 1) /* 24 bit signed value starting at 24 */ + { 24, 24, S390_OPERAND_SIGNED }, +#define I32_16 (I24_24 + 1) /* 32 bit signed value starting at 16 */ + { 32, 16, S390_OPERAND_SIGNED }, + +/* Unsigned immediate operands. */ + +#define U4_8 (I32_16 + 1) /* 4 bit unsigned value starting at 8 */ + { 4, 8, 0 }, +#define U4_12 (U4_8 + 1) /* 4 bit unsigned value starting at 12 */ + { 4, 12, 0 }, +#define U4_16 (U4_12 + 1) /* 4 bit unsigned value starting at 16 */ + { 4, 16, 0 }, +#define U4_20 (U4_16 + 1) /* 4 bit unsigned value starting at 20 */ + { 4, 20, 0 }, +#define U4_24 (U4_20 + 1) /* 4 bit unsigned value starting at 24 */ + { 4, 24, 0 }, +#define U4_28 (U4_24+1) /* 4 bit unsigned value starting at 28 */ + { 4, 28, 0 }, +#define U4_32 (U4_28+1) /* 4 bit unsigned value starting at 32 */ + { 4, 32, 0 }, +#define U4_36 (U4_32 + 1) /* 4 bit unsigned value starting at 36 */ + { 4, 36, 0 }, +#define U8_8 (U4_36 + 1) /* 8 bit unsigned value starting at 8 */ + { 8, 8, 0 }, +#define U8_16 (U8_8 + 1) /* 8 bit unsigned value starting at 16 */ + { 8, 16, 0 }, +#define U8_24 (U8_16 + 1) /* 8 bit unsigned value starting at 24 */ + { 8, 24, 0 }, +#define U8_28 (U8_24 + 1) /* 8 bit unsigned value starting at 28 */ + { 8, 28, 0 }, +#define U8_32 (U8_28 + 1) /* 8 bit unsigned value starting at 32 */ + { 8, 32, 0 }, +#define U12_16 (U8_32 + 1) /* 12 bit unsigned value starting at 16 */ + { 12, 16, 0 }, +#define U16_16 (U12_16 + 1) /* 16 bit unsigned value starting at 16 */ + { 16, 16, 0 }, +#define U16_20 (U16_16 + 1) /* 16 bit unsigned value starting at 20 */ + { 16, 20, 0 }, +#define U16_32 (U16_20 + 1) /* 16 bit unsigned value starting at 32 */ + { 16, 32, 0 }, +#define U32_16 (U16_32 + 1) /* 32 bit unsigned value starting at 16 */ + { 32, 16, 0 }, + +/* PC-relative address operands. */ + +#define J12_12 (U32_16 + 1) /* 12 bit PC relative offset at 12 */ + { 12, 12, S390_OPERAND_PCREL }, +#define J16_16 (J12_12 + 1) /* 16 bit PC relative offset at 16 */ + { 16, 16, S390_OPERAND_PCREL }, +#define J16_32 (J16_16 + 1) /* 16 bit PC relative offset at 32 */ + { 16, 32, S390_OPERAND_PCREL }, +#define J24_24 (J16_32 + 1) /* 24 bit PC relative offset at 24 */ + { 24, 24, S390_OPERAND_PCREL }, +#define J32_16 (J24_24 + 1) /* 32 bit PC relative offset at 16 */ + { 32, 16, S390_OPERAND_PCREL }, + +}; + +static inline void ATTRIBUTE_UNUSED +unused_s390_operands_static_asserts (void) +{ + static_assert (ARRAY_SIZE (s390_operands) - 1 == J32_16); +} + +/* Macros used to form opcodes. */ + +/* 8/16/48 bit opcodes. */ +#define OP8(x) { x, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define OP16(x) { x >> 8, x & 255, 0x00, 0x00, 0x00, 0x00 } +#define OP32(x) { x >> 24, (x >> 16) & 255, (x >> 8) & 255, x & 255, \ + 0x00, 0x00 } +#define OP48(x) { x >> 40, (x >> 32) & 255, (x >> 24) & 255, \ + (x >> 16) & 255, (x >> 8) & 255, x & 255} + +/* The new format of the INSTR_x_y and MASK_x_y defines is based + on the following rules: + 1) the middle part of the definition (x in INSTR_x_y) is the official + names of the instruction format that you can find in the principals + of operation. + 2) the last part of the definition (y in INSTR_x_y) gives you an idea + which operands the binary represenation of the instruction has. + The meanings of the letters in y are: + a - access register + c - control register + d - displacement, 12 bit + f - floating pointer register + fe - fpr extended operand, a valid floating pointer register pair + i - signed integer, 4, 8, 16 or 32 bit + l - length, 4 or 8 bit + p - pc relative + r - general purpose register + re - gpr extended operand, a valid general purpose register pair + u - unsigned integer, 4, 8, 16 or 32 bit + m - mode field, 4 bit + 0 - operand skipped. + The order of the letters reflects the layout of the format in + storage and not the order of the paramaters of the instructions. + The use of the letters is not a 100% match with the PoP but it is + quite close. + + For example the instruction "mvo" is defined in the PoP as follows: + + MVO D1(L1,B1),D2(L2,B2) [SS] + + -------------------------------------- + | 'F1' | L1 | L2 | B1 | D1 | B2 | D2 | + -------------------------------------- + 0 8 12 16 20 32 36 + + The instruction format is: INSTR_SS_LLRDRD / MASK_SS_LLRDRD. */ + +#define INSTR_E 2, { 0,0,0,0,0,0 } /* e.g. pr */ +#define INSTR_IE_UU 4, { U4_24,U4_28,0,0,0,0 } /* e.g. niai */ +#define INSTR_MII_UPP 6, { U4_8,J12_12,J24_24 } /* e.g. bprp */ +#define INSTR_RIE_RRP 6, { R_8,R_12,J16_16,0,0,0 } /* e.g. brxhg */ +#define INSTR_RIE_RRPU 6, { R_8,R_12,U4_32,J16_16,0,0 } /* e.g. crj */ +#define INSTR_RIE_RRP0 6, { R_8,R_12,J16_16,0,0,0 } /* e.g. cgrjne */ +#define INSTR_RIE_RRI0 6, { R_8,R_12,I16_16,0,0,0 } /* e.g. ahik */ +#define INSTR_RIE_RUPI 6, { R_8,I8_32,U4_12,J16_16,0,0 } /* e.g. cij */ +#define INSTR_RIE_R0PI 6, { R_8,I8_32,J16_16,0,0,0 } /* e.g. cijne */ +#define INSTR_RIE_RUPU 6, { R_8,U8_32,U4_12,J16_16,0,0 } /* e.g. clij */ +#define INSTR_RIE_R0PU 6, { R_8,U8_32,J16_16,0,0,0 } /* e.g. clijne */ +#define INSTR_RIE_R0IU 6, { R_8,I16_16,U4_32,0,0,0 } /* e.g. cit */ +#define INSTR_RIE_R0I0 6, { R_8,I16_16,0,0,0,0 } /* e.g. citne */ +#define INSTR_RIE_R0UU 6, { R_8,U16_16,U4_32,0,0,0 } /* e.g. clfit */ +#define INSTR_RIE_R0U0 6, { R_8,U16_16,0,0,0,0 } /* e.g. clfitne */ +#define INSTR_RIE_RUI0 6, { R_8,I16_16,U4_12,0,0,0 } /* e.g. lochi */ +#define INSTR_RIE_RRUUU 6, { R_8,R_12,U8_16,U8_24,U8_32,0 } /* e.g. rnsbg */ +#define INSTR_RIE_RRUUU2 INSTR_RIE_RRUUU /* e.g. risbgz */ +#define INSTR_RIE_RRUUU3 INSTR_RIE_RRUUU /* e.g. risbhg */ +#define INSTR_RIE_RRUUU4 INSTR_RIE_RRUUU /* e.g. rnsbgt */ +#define INSTR_RIL_0P 6, { J32_16,0,0,0,0 } /* e.g. jg */ +#define INSTR_RIL_RP 6, { R_8,J32_16,0,0,0,0 } /* e.g. brasl */ +#define INSTR_RIL_UP 6, { U4_8,J32_16,0,0,0,0 } /* e.g. brcl */ +#define INSTR_RIL_RI 6, { R_8,I32_16,0,0,0,0 } /* e.g. afi */ +#define INSTR_RIL_RU 6, { R_8,U32_16,0,0,0,0 } /* e.g. alfi */ +#define INSTR_RI_0P 4, { J16_16,0,0,0,0,0 } /* e.g. j */ +#define INSTR_RI_RI 4, { R_8,I16_16,0,0,0,0 } /* e.g. ahi */ +#define INSTR_RI_RP 4, { R_8,J16_16,0,0,0,0 } /* e.g. brct */ +#define INSTR_RI_RU 4, { R_8,U16_16,0,0,0,0 } /* e.g. tml */ +#define INSTR_RI_UP 4, { U4_8,J16_16,0,0,0,0 } /* e.g. brc */ +#define INSTR_RIS_RURDI 6, { R_8,I8_32,U4_12,D_20,B_16,0 } /* e.g. cib */ +#define INSTR_RIS_R0RDI 6, { R_8,I8_32,D_20,B_16,0,0 } /* e.g. cibne */ +#define INSTR_RIS_RURDU 6, { R_8,U8_32,U4_12,D_20,B_16,0 } /* e.g. clib */ +#define INSTR_RIS_R0RDU 6, { R_8,U8_32,D_20,B_16,0,0 } /* e.g. clibne*/ +#define INSTR_RRE_00 4, { 0,0,0,0,0,0 } /* e.g. palb */ +#define INSTR_RRE_0R 4, { R_28,0,0,0,0,0 } /* e.g. tb */ +#define INSTR_RRE_AA 4, { A_24,A_28,0,0,0,0 } /* e.g. cpya */ +#define INSTR_RRE_AR 4, { A_24,R_28,0,0,0,0 } /* e.g. sar */ +#define INSTR_RRE_F0 4, { F_24,0,0,0,0,0 } /* e.g. lzer */ +#define INSTR_RRE_FE0 4, { FE_24,0,0,0,0,0 } /* e.g. lzxr */ +#define INSTR_RRE_FF 4, { F_24,F_28,0,0,0,0 } /* e.g. debr */ +#define INSTR_RRE_FEF 4, { FE_24,F_28,0,0,0,0 } /* e.g. lxdbr */ +#define INSTR_RRE_FFE 4, { F_24,FE_28,0,0,0,0 } /* e.g. lexr */ +#define INSTR_RRE_FEFE 4, { FE_24,FE_28,0,0,0,0 } /* e.g. dxr */ +#define INSTR_RRE_R0 4, { R_24,0,0,0,0,0 } /* e.g. ipm */ +#define INSTR_RRE_RA 4, { R_24,A_28,0,0,0,0 } /* e.g. ear */ +#define INSTR_RRE_RF 4, { R_24,F_28,0,0,0,0 } /* e.g. lgdr */ +#define INSTR_RRE_RFE 4, { R_24,FE_28,0,0,0,0 } /* e.g. csxtr */ +#define INSTR_RRE_RR 4, { R_24,R_28,0,0,0,0 } /* e.g. lura */ +#define INSTR_RRE_RER 4, { RE_24,R_28,0,0,0,0 } /* e.g. tre */ +#define INSTR_RRE_RERE 4, { RE_24,RE_28,0,0,0,0 } /* e.g. cuse */ +#define INSTR_RRE_FR 4, { F_24,R_28,0,0,0,0 } /* e.g. ldgr */ +#define INSTR_RRE_FER 4, { FE_24,R_28,0,0,0,0 } /* e.g. cxfbr */ +#define INSTR_RRF_F0FF 4, { F_16,F_24,F_28,0,0,0 } /* e.g. madbr */ +#define INSTR_RRF_FE0FF 4, { F_16,F_24,F_28,0,0,0 } /* e.g. myr */ +#define INSTR_RRF_F0FF2 4, { F_24,F_16,F_28,0,0,0 } /* e.g. cpsdr */ +#define INSTR_RRF_F0FR 4, { F_24,F_16,R_28,0,0,0 } /* e.g. iedtr */ +#define INSTR_RRF_FE0FER 4, { FE_24,FE_16,R_28,0,0,0 } /* e.g. iextr */ +#define INSTR_RRF_FUFF 4, { F_24,F_16,F_28,U4_20,0,0 } /* e.g. didbr */ +#define INSTR_RRF_FEUFEFE 4, { FE_24,FE_16,FE_28,U4_20,0,0 } /* e.g. qaxtr */ +#define INSTR_RRF_FUFF2 4, { F_24,F_28,F_16,U4_20,0,0 } /* e.g. adtra */ +#define INSTR_RRF_FEUFEFE2 4, { FE_24,FE_28,FE_16,U4_20,0,0 } /* e.g. axtra */ +#define INSTR_RRF_RURR 4, { R_24,R_28,R_16,U4_20,0,0 } /* e.g. ipte */ +#define INSTR_RRF_RURR2 4, { R_24,R_16,R_28,U4_20,0,0 } /* e.g. lptea */ +#define INSTR_RRF_R0RR 4, { R_24,R_16,R_28,0,0,0 } /* e.g. idte */ +#define INSTR_RRF_R0RR2 4, { R_24,R_28,R_16,0,0,0 } /* e.g. ark */ +#define INSTR_RRF_R0RER 4, { RE_24,R_28,R_16,0,0,0 } /* e.g. mgrk */ +#define INSTR_RRF_R0RR3 4, { R_24,R_28,R_16,0,0,0 } /* e.g. selrz */ +#define INSTR_RRF_R0RR4 4, { R_24,R_CP16_28,0,0,0,0 } /* e.g. notr */ +#define INSTR_RRF_U0FF 4, { F_24,U4_16,F_28,0,0,0 } /* e.g. fidbr */ +#define INSTR_RRF_U0FEFE 4, { FE_24,U4_16,FE_28,0,0,0 } /* e.g. fixbr */ +#define INSTR_RRF_U0RF 4, { R_24,U4_16,F_28,0,0,0 } /* e.g. cfebr */ +#define INSTR_RRF_U0RFE 4, { R_24,U4_16,FE_28,0,0,0 } /* e.g. cfxbr */ +#define INSTR_RRF_UUFF 4, { F_24,U4_16,F_28,U4_20,0,0 } /* e.g. fidtr */ +#define INSTR_RRF_UUFFE 4, { F_24,U4_16,FE_28,U4_20,0,0 } /* e.g. ldxtr */ +#define INSTR_RRF_UUFEFE 4, { FE_24,U4_16,FE_28,U4_20,0,0 } /* e.g. fixtr */ +#define INSTR_RRF_0UFF 4, { F_24,F_28,U4_20,0,0,0 } /* e.g. ldetr */ +#define INSTR_RRF_0UFEF 4, { FE_24,F_28,U4_20,0,0,0 } /* e.g. lxdtr */ +#define INSTR_RRF_FFRU 4, { F_24,F_16,R_28,U4_20,0,0 } /* e.g. rrdtr */ +#define INSTR_RRF_FEFERU 4, { FE_24,FE_16,R_28,U4_20,0,0 } /* e.g. rrxtr */ +#define INSTR_RRF_U0RR 4, { R_24,R_28,U4_16,0,0,0 } /* e.g. sske */ +#define INSTR_RRF_U0RER 4, { RE_24,R_28,U4_16,0,0,0 } /* e.g. trte */ +#define INSTR_RRF_U0RERE 4, { RE_24,RE_28,U4_16,0,0,0 } /* e.g. cu24 */ +#define INSTR_RRF_00RR 4, { R_24,R_28,0,0,0,0 } /* e.g. clrtne */ +#define INSTR_RRF_0URF 4, { R_24,F_28,U4_20,0,0,0 } /* e.g. csdtr */ +#define INSTR_RRF_0UREFE 4, { RE_24,FE_28,U4_20,0,0,0 } /* e.g. csxtr */ +#define INSTR_RRF_UUFR 4, { F_24,U4_16,R_28,U4_20,0,0 } /* e.g. cdgtra */ +#define INSTR_RRF_UUFER 4, { FE_24,U4_16,R_28,U4_20,0,0 } /* e.g. cxfbra */ +#define INSTR_RRF_UURF 4, { R_24,U4_16,F_28,U4_20,0,0 } /* e.g. cgdtra */ +#define INSTR_RRF_UURFE 4, { R_24,U4_16,FE_28,U4_20,0,0 } /* e.g. cfxbra */ +#define INSTR_RR_0R 2, { R_12, 0,0,0,0,0 } /* e.g. br */ +#define INSTR_RR_FF 2, { F_8,F_12,0,0,0,0 } /* e.g. adr */ +#define INSTR_RR_FEF 2, { FE_8,F_12,0,0,0,0 } /* e.g. mxdr */ +#define INSTR_RR_FFE 2, { F_8,FE_12,0,0,0,0 } /* e.g. ldxr */ +#define INSTR_RR_FEFE 2, { FE_8,FE_12,0,0,0,0 } /* e.g. axr */ +#define INSTR_RR_R0 2, { R_8, 0,0,0,0,0 } /* e.g. spm */ +#define INSTR_RR_RR 2, { R_8,R_12,0,0,0,0 } /* e.g. lr */ +#define INSTR_RR_RER 2, { RE_8,R_12,0,0,0,0 } /* e.g. dr */ +#define INSTR_RR_U0 2, { U8_8, 0,0,0,0,0 } /* e.g. svc */ +#define INSTR_RR_UR 2, { U4_8,R_12,0,0,0,0 } /* e.g. bcr */ +#define INSTR_RRR_F0FF 4, { F_24,F_28,F_16,0,0,0 } /* e.g. ddtr */ +#define INSTR_RRR_FE0FEFE 4, { FE_24,FE_28,FE_16,0,0,0 } /* e.g. axtr */ +#define INSTR_RRS_RRRDU 6, { R_8,R_12,U4_32,D_20,B_16 } /* e.g. crb */ +#define INSTR_RRS_RRRD0 6, { R_8,R_12,D_20,B_16,0 } /* e.g. crbne */ +#define INSTR_RSE_RRRD 6, { R_8,R_12,D_20,B_16,0,0 } /* e.g. lmh */ +#define INSTR_RSE_RERERD 6, { RE_8,RE_12,D_20,B_16,0,0 } /* e.g. mvclu */ +#define INSTR_RSE_CCRD 6, { C_8,C_12,D_20,B_16,0,0 } /* e.g. stctg */ +#define INSTR_RSE_RURD 6, { R_8,U4_12,D_20,B_16,0,0 } /* e.g. icmh */ +#define INSTR_RSL_R0RD 6, { D_20,L4_8,B_16,0,0,0 } /* e.g. tp */ +#define INSTR_RSL_LRDFU 6, { F_32,D_20,L8_8,B_16,U4_36,0 } /* e.g. cdzt */ +#define INSTR_RSL_LRDFEU 6, { FE_32,D_20,L8_8,B_16,U4_36,0 } /* e.g. cxzt */ +#define INSTR_RSI_RRP 4, { R_8,R_12,J16_16,0,0,0 } /* e.g. brxh */ +#define INSTR_RSY_RRRD 6, { R_8,R_12,D20_20,B_16,0,0 } /* e.g. stmy */ +#define INSTR_RSY_RERERD 6, { RE_8,RE_12,D20_20,B_16,0,0 } /* e.g. cdsy */ +#define INSTR_RSY_RURD 6, { R_8,U4_12,D20_20,B_16,0,0 } /* e.g. icmh */ +#define INSTR_RSY_RURD2 6, { R_8,D20_20,B_16,U4_12,0,0 } /* e.g. loc */ +#define INSTR_RSY_R0RD 6, { R_8,D20_20,B_16,0,0,0 } /* e.g. locne */ +#define INSTR_RSY_AARD 6, { A_8,A_12,D20_20,B_16,0,0 } /* e.g. lamy */ +#define INSTR_RSY_CCRD 6, { C_8,C_12,D20_20,B_16,0,0 } /* e.g. stctg */ +#define INSTR_RS_AARD 4, { A_8,A_12,D_20,B_16,0,0 } /* e.g. lam */ +#define INSTR_RS_CCRD 4, { C_8,C_12,D_20,B_16,0,0 } /* e.g. lctl */ +#define INSTR_RS_R0RD 4, { R_8,D_20,B_16,0,0,0 } /* e.g. sll */ +#define INSTR_RS_RE0RD 4, { RE_8,D_20,B_16,0,0,0 } /* e.g. slda */ +#define INSTR_RS_RRRD 4, { R_8,R_12,D_20,B_16,0,0 } /* e.g. cs */ +#define INSTR_RS_RERERD 4, { RE_8,RE_12,D_20,B_16,0,0 } /* e.g. cds */ +#define INSTR_RS_RURD 4, { R_8,U4_12,D_20,B_16,0,0 } /* e.g. icm */ +#define INSTR_RXE_FRRD 6, { F_8,D_20,X_12,B_16,0,0 } /* e.g. adb */ +#define INSTR_RXE_FERRD 6, { FE_8,D_20,X_12,B_16,0,0 } /* e.g. lxdb */ +#define INSTR_RXE_RRRD 6, { R_8,D_20,X_12,B_16,0,0 } /* e.g. lg */ +#define INSTR_RXE_RRRDU 6, { R_8,D_20,X_12,B_16,U4_32,0 } /* e.g. lcbb */ +#define INSTR_RXE_RERRD 6, { RE_8,D_20,X_12,B_16,0,0 } /* e.g. dsg */ +#define INSTR_RXF_FRRDF 6, { F_32,F_8,D_20,X_12,B_16,0 } /* e.g. madb */ +#define INSTR_RXF_FRRDFE 6, { FE_32,F_8,D_20,X_12,B_16,0 } /* e.g. my */ +#define INSTR_RXF_FERRDFE 6, { FE_32,FE_8,D_20,X_12,B_16,0 } /* e.g. slxt */ +#define INSTR_RXF_RRRDR 6, { R_32,R_8,D_20,X_12,B_16,0 } /* e.g. .insn */ +#define INSTR_RXY_RRRD 6, { R_8,D20_20,X_12,B_16,0,0 } /* e.g. ly */ +#define INSTR_RXY_RERRD 6, { RE_8,D20_20,X_12,B_16,0,0 } /* e.g. dsg */ +#define INSTR_RXY_FRRD 6, { F_8,D20_20,X_12,B_16,0,0 } /* e.g. ley */ +#define INSTR_RXY_URRD 6, { U4_8,D20_20,X_12,B_16,0,0 } /* e.g. pfd */ +#define INSTR_RXY_0RRD 6, { D20_20,X_12,B_16,0,0 } /* e.g. bic */ +#define INSTR_RX_0RRD 4, { D_20,X_12,B_16,0,0,0 } /* e.g. be */ +#define INSTR_RX_FRRD 4, { F_8,D_20,X_12,B_16,0,0 } /* e.g. ae */ +#define INSTR_RX_FERRD 4, { FE_8,D_20,X_12,B_16,0,0 } /* e.g. mxd */ +#define INSTR_RX_RRRD 4, { R_8,D_20,X_12,B_16,0,0 } /* e.g. l */ +#define INSTR_RX_RERRD 4, { RE_8,D_20,X_12,B_16,0,0 } /* e.g. d */ +#define INSTR_RX_URRD 4, { U4_8,D_20,X_12,B_16,0,0 } /* e.g. bc */ +#define INSTR_SI_RD 4, { D_20,B_16,0,0,0,0 } /* e.g. lpsw */ +#define INSTR_SI_URD 4, { D_20,B_16,U8_8,0,0,0 } /* e.g. cli */ +#define INSTR_SIY_RD 6, { D20_20,B_16,0,0,0,0 } /* e.g. lpswey*/ +#define INSTR_SIY_URD 6, { D20_20,B_16,U8_8,0,0,0 } /* e.g. tmy */ +#define INSTR_SIY_IRD 6, { D20_20,B_16,I8_8,0,0,0 } /* e.g. asi */ +#define INSTR_SIL_RDI 6, { D_20,B_16,I16_32,0,0,0 } /* e.g. chhsi */ +#define INSTR_SIL_RDU 6, { D_20,B_16,U16_32,0,0,0 } /* e.g. clfhsi */ +#define INSTR_SMI_U0RDP 6, { U4_8,J16_32,D_20,B_16,0,0 } /* e.g. bpp */ +#define INSTR_SSE_RDRD 6, { D_20,B_16,D_36,B_32,0,0 } /* e.g. mvcdk */ +#define INSTR_SS_L0RDRD 6, { D_20,L8_8,B_16,D_36,B_32,0 } /* e.g. mvc */ +#define INSTR_SS_L2RDRD 6, { D_20,B_16,D_36,L8_8,B_32,0 } /* e.g. pka */ +#define INSTR_SS_LIRDRD 6, { D_20,L4_8,B_16,D_36,B_32,U4_12 } /* e.g. srp */ +#define INSTR_SS_LLRDRD 6, { D_20,L4_8,B_16,D_36,L4_12,B_32 } /* e.g. pack */ +#define INSTR_SS_RRRDRD 6, { D_20,R_8,B_16,D_36,B_32,R_12 } /* e.g. mvck */ +#define INSTR_SS_RRRDRD2 6, { R_8,D_20,B_16,R_12,D_36,B_32 } /* e.g. plo */ +#define INSTR_SS_RRRDRD3 6, { R_8,R_12,D_20,B_16,D_36,B_32 } /* e.g. lmd */ +#define INSTR_SSF_RRDRD 6, { D_20,B_16,D_36,B_32,R_8,0 } /* e.g. mvcos */ +#define INSTR_SSF_RRDRD2 6, { R_8,D_20,B_16,D_36,B_32,0 } /* e.g. cal */ +#define INSTR_SSF_RERDRD2 6, { RE_8,D_20,B_16,D_36,B_32,0 } /* e.g. lpd */ +#define INSTR_S_00 4, { 0,0,0,0,0,0 } /* e.g. hsch */ +#define INSTR_S_RD 4, { D_20,B_16,0,0,0,0 } /* e.g. stck */ +#define INSTR_VRV_VVXRDU 6, { V_8,D_20,VX_12,B_16,U4_32,0 } /* e.g. vgef */ +#define INSTR_VRI_V0U 6, { V_8,U16_16,0,0,0,0 } /* e.g. vgbm */ +#define INSTR_VRI_V 6, { V_8,0,0,0,0,0 } /* e.g. vzero */ +#define INSTR_VRI_V0UUU 6, { V_8,U8_16,U8_24,U4_32,0,0 } /* e.g. vgm */ +#define INSTR_VRI_V0UU 6, { V_8,U8_16,U8_24,0,0,0 } /* e.g. vgmb */ +#define INSTR_VRI_V0UU2 6, { V_8,U16_16,U4_32,0,0,0 } /* e.g. vlip */ +#define INSTR_VRI_VVUU 6, { V_8,V_12,U16_16,U4_32,0,0 } /* e.g. vrep */ +#define INSTR_VRI_VVU 6, { V_8,V_12,U16_16,0,0,0 } /* e.g. vrepb */ +#define INSTR_VRI_VVU2 6, { V_8,V_12,U12_16,0,0,0 } /* e.g. vftcidb */ +#define INSTR_VRI_V0IU 6, { V_8,I16_16,U4_32,0,0,0 } /* e.g. vrepi */ +#define INSTR_VRI_V0I 6, { V_8,I16_16,0,0,0,0 } /* e.g. vrepib */ +#define INSTR_VRI_VVV0UU 6, { V_8,V_12,V_16,U8_24,U4_32,0 } /* e.g. verim */ +#define INSTR_VRI_VVV0UU2 6, { V_8,V_12,V_16,U8_28,U4_24,0 } /* e.g. vap */ +#define INSTR_VRI_VVV0U 6, { V_8,V_12,V_16,U8_24,0,0 } /* e.g. verimb*/ +#define INSTR_VRI_VVUUU 6, { V_8,V_12,U12_16,U4_32,U4_28,0 } /* e.g. vftci */ +#define INSTR_VRI_VVUUU2 6, { V_8,V_12,U8_28,U8_16,U4_24,0 } /* e.g. vpsop */ +#define INSTR_VRI_VR0UU 6, { V_8,R_12,U8_28,U4_24,0,0 } /* e.g. vcvd */ +#define INSTR_VRI_VV0UU 6, { V_8,V_12,U8_28,U4_24,0,0 } /* e.g. vcvdq */ +#define INSTR_VRI_VVV0UV 6, { V_8,V_12,V_16,V_32,U8_24,0 } /* e.g. veval */ +#define INSTR_VRX_VRRD 6, { V_8,D_20,X_12,B_16,0,0 } /* e.g. vl */ +#define INSTR_VRX_VV 6, { V_8,V_12,0,0,0,0 } /* e.g. vlr */ +#define INSTR_VRX_VRRDU 6, { V_8,D_20,X_12,B_16,U4_32,0 } /* e.g. vlrep */ +#define INSTR_VRS_RVRDU 6, { R_8,V_12,D_20,B_16,U4_32,0 } /* e.g. vlgv */ +#define INSTR_VRS_RVRD 6, { R_8,V_12,D_20,B_16,0,0 } /* e.g. vlgvb */ +#define INSTR_VRS_VVRDU 6, { V_8,V_12,D_20,B_16,U4_32,0 } /* e.g. verll */ +#define INSTR_VRS_VVRD 6, { V_8,V_12,D_20,B_16,0,0 } /* e.g. vlm */ +#define INSTR_VRS_VRRDU 6, { V_8,R_12,D_20,B_16,U4_32,0 } /* e.g. vlvg */ +#define INSTR_VRS_VRRD 6, { V_8,R_12,D_20,B_16,0,0 } /* e.g. vlvgb */ +#define INSTR_VRS_RRDV 6, { V_32,R_12,D_20,B_16,0,0 } /* e.g. vlrlr */ +#define INSTR_VRR_VRR 6, { V_8,R_12,R_16,0,0,0 } /* e.g. vlvgp */ +#define INSTR_VRR_VVV0U 6, { V_8,V_12,V_16,U4_32,0,0 } /* e.g. vmrh */ +#define INSTR_VRR_VVV0U0 6, { V_8,V_12,V_16,U4_24,0,0 } /* e.g. vfaeb */ +#define INSTR_VRR_VVV0U02 6, { V_8,V_12,V_16,U4_28,0,0 } /* e.g. vd */ +#define INSTR_VRR_VVV0U1 INSTR_VRR_VVV0U0 /* e.g. vfaebs*/ +#define INSTR_VRR_VVV0U2 INSTR_VRR_VVV0U0 /* e.g. vfaezb*/ +#define INSTR_VRR_VVV0U3 INSTR_VRR_VVV0U0 /* e.g. vfaezbs*/ +#define INSTR_VRR_VVV 6, { V_8,V_12,V_16,0,0,0 } /* e.g. vmrhb */ +#define INSTR_VRR_VVV2 6, { V_8,V_CP16_12,0,0,0,0 } /* e.g. vnot */ +#define INSTR_VRR_VV0U 6, { V_8,V_12,U4_32,0,0,0 } /* e.g. vseg */ +#define INSTR_VRR_VV0U2 6, { V_8,V_12,U4_24,0,0,0 } /* e.g. vistrb*/ +#define INSTR_VRR_VV0UU 6, { V_8,V_12,U4_28,U4_24,0,0 } /* e.g. vcdgb */ +#define INSTR_VRR_VV0UU2 6, { V_8,V_12,U4_32,U4_28,0,0 } /* e.g. wfc */ +#define INSTR_VRR_VV0UU8 INSTR_VRR_VV0UU /* e.g. wcdgb */ +#define INSTR_VRR_VV 6, { V_8,V_12,0,0,0,0 } /* e.g. vsegb */ +#define INSTR_VRR_VVVUU0V 6, { V_8,V_12,V_16,V_32,U4_20,U4_24 } /* e.g. vstrc */ +#define INSTR_VRR_VVVU0V 6, { V_8,V_12,V_16,V_32,U4_20,0 } /* e.g. vac */ +#define INSTR_VRR_VVVU0VB 6, { V_8,V_12,V_16,V_32,U4_24,0 } /* e.g. vstrcb*/ +#define INSTR_VRR_VVVU0VB1 INSTR_VRR_VVVU0VB /* e.g. vstrcbs*/ +#define INSTR_VRR_VVVU0VB2 INSTR_VRR_VVVU0VB /* e.g. vstrczb*/ +#define INSTR_VRR_VVVU0VB3 INSTR_VRR_VVVU0VB /* e.g. vstrczbs*/ +#define INSTR_VRR_VVV0V 6, { V_8,V_12,V_16,V_32,0,0 } /* e.g. vacq */ +#define INSTR_VRR_VVV0U0U 6, { V_8,V_12,V_16,U4_32,U4_24,0 } /* e.g. vfae */ +#define INSTR_VRR_VVVV 6, { V_8,V_12,V_16,V_32,0,0 } /* e.g. vfmadb*/ +#define INSTR_VRR_VVV0UUU 6, { V_8,V_12,V_16,U4_32,U4_28,U4_24 }/* e.g. vfch */ +#define INSTR_VRR_VVV0UU 6, { V_8,V_12,V_16,U4_32,U4_28,0 } /* e.g. vfa */ +#define INSTR_VRR_VV0UUU 6, { V_8,V_12,U4_32,U4_28,U4_24,0 } /* e.g. vcdg */ +#define INSTR_VRR_VVVU0UV 6, { V_8,V_12,V_16,V_32,U4_28,U4_20 } /* e.g. vfma */ +#define INSTR_VRR_VV0U0U 6, { V_8,V_12,U4_32,U4_24,0,0 } /* e.g. vistr */ +#define INSTR_VRR_0V 6, { V_12,0,0,0,0,0 } /* e.g. vtp */ +#define INSTR_VRR_0V0U 6, { V_12,U16_20,0,0,0,0 } /* e.g. vtp */ +#define INSTR_VRR_0VVU 6, { V_12,V_16,U16_20,0,0,0 } /* e.g. vtz */ +#define INSTR_VRR_0VV0U 6, { V_12,V_16,U4_24,0,0,0 } /* e.g. vcp */ +#define INSTR_VRR_RV0U 6, { R_8,V_12,U4_24,0,0,0 } /* e.g. vcvb */ +#define INSTR_VRR_RV0UU 6, { R_8,V_12,U4_24,U4_28,0,0 } /* e.g. vcvb */ +#define INSTR_VSI_URDV 6, { V_32,D_20,B_16,U8_8,0,0 } /* e.g. vlrl */ + +#define MASK_E { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_IE_UU { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_MII_UPP { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIE_RRP { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_RRPU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_RRP0 { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_RIE_RRI0 { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_RIE_RUPI { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_R0PI { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_RUPU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_R0PU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_R0IU { 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RIE_R0I0 { 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff } +#define MASK_RIE_R0UU { 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RIE_R0U0 { 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff } +#define MASK_RIE_RUI0 { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RIE_RRUUU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIE_RRUUU2 { 0xff, 0x00, 0x00, 0x80, 0x00, 0xff } +#define MASK_RIE_RRUUU3 { 0xff, 0x00, 0x00, 0x80, 0x00, 0xff } +#define MASK_RIE_RRUUU4 { 0xff, 0x00, 0x80, 0x00, 0x00, 0xff } +#define MASK_RIL_0P { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_RP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_UP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_RI { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_RU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_0P { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RI { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_UP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIS_RURDI { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIS_R0RDI { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIS_RURDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIS_R0RDU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_RRE_00 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define MASK_RRE_0R { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } +#define MASK_RRE_AA { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_AR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_F0 { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 } +#define MASK_RRE_FE0 { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 } +#define MASK_RRE_FF { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_FEF { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_FFE { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_FEFE { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_R0 { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 } +#define MASK_RRE_RA { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RF { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RFE { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RER { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RERE { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_FR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_FER { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRF_F0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_FE0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_F0FF2 { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_F0FR { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_FE0FER { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_FUFF { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_FEUFEFE { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_FUFF2 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_FEUFEFE2 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_RURR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_RURR2 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_R0RR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_R0RR2 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_R0RER { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_R0RR3 { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_R0RR4 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0FEFE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0RF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0RFE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_UUFF { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_UUFFE { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_UUFEFE { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_0UFF { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } +#define MASK_RRF_0UFEF { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } +#define MASK_RRF_FFRU { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_FEFERU { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0RR { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0RER { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0RERE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_00RR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRF_0URF { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } +#define MASK_RRF_0UREFE { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } +#define MASK_RRF_UUFR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_UUFER { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_UURF { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_UURFE { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_0R { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_FF { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_FEF { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_FFE { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_FEFE { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_R0 { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_RR { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_RER { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_U0 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_UR { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRR_F0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRR_FE0FEFE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRS_RRRDU { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RRS_RRRD0 { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSE_RRRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSE_RERERD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSE_CCRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSE_RURD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSL_R0RD { 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff } +#define MASK_RSL_LRDFU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSL_LRDFEU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSI_RRP { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_AARD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_CCRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_R0RD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RE0RD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RERERD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RURD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RSY_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_RERERD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_RURD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_RURD2 { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_R0RD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_AARD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSY_CCRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXE_FRRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RXE_FERRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RXE_RRRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RXE_RRRDU { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RXE_RERRD { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } +#define MASK_RXF_FRRDF { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RXF_FRRDFE { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RXF_FERRDFE { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RXF_RRRDR { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff } +#define MASK_RXY_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXY_RERRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXY_FRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXY_URRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXY_0RRD { 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff } +#define MASK_RX_0RRD { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_FRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_FERRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_RERRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_URRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SI_RD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SI_URD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SIY_RD { 0xff, 0xff, 0x00, 0x00, 0x00, 0xff } +#define MASK_SIY_URD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_SIY_IRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_SIL_RDI { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SIL_RDU { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SMI_U0RDP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SSE_RDRD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_L0RDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_L2RDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_LIRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_LLRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD2 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD3 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SSF_RRDRD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SSF_RRDRD2 { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SSF_RERDRD2 { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_S_00 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define MASK_S_RD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_VRV_VVXRDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_V0U { 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRI_V { 0xff, 0x0f, 0xff, 0xff, 0xf0, 0xff } +#define MASK_VRI_V0UUU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_V0UU { 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRI_V0UU2 { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_VVUU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_VVU { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRI_VVU2 { 0xff, 0x00, 0x00, 0x0f, 0xf0, 0xff } +#define MASK_VRI_V0IU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_V0I { 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRI_VVV0UU { 0xff, 0x00, 0x0f, 0x00, 0x00, 0xff } +#define MASK_VRI_VVV0UU2 { 0xff, 0x00, 0x0f, 0x00, 0x00, 0xff } +#define MASK_VRI_VVV0U { 0xff, 0x00, 0x0f, 0x00, 0xf0, 0xff } +#define MASK_VRI_VVUUU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_VVUUU2 { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRI_VR0UU { 0xff, 0x00, 0xff, 0x00, 0x00, 0xff } +#define MASK_VRI_VV0UU { 0xff, 0x00, 0xff, 0x00, 0x00, 0xff } +#define MASK_VRI_VVV0UV { 0xff, 0x00, 0x0f, 0x00, 0x00, 0xff } +#define MASK_VRX_VRRD { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRX_VV { 0xff, 0x00, 0xff, 0xff, 0xf0, 0xff } +#define MASK_VRX_VRRDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRS_RVRDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRS_RVRD { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRS_VVRDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRS_VVRD { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRS_VRRDU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRS_VRRD { 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff } +#define MASK_VRS_RRDV { 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRR_VRR { 0xff, 0x00, 0x0f, 0xff, 0xf0, 0xff } +#define MASK_VRR_VVV0U { 0xff, 0x00, 0x0f, 0xff, 0x00, 0xff } +#define MASK_VRR_VVV0U0 { 0xff, 0x00, 0x0f, 0x0f, 0xf0, 0xff } +#define MASK_VRR_VVV0U02 { 0xff, 0x00, 0x0f, 0xf0, 0xf0, 0xff } +#define MASK_VRR_VVV0U1 { 0xff, 0x00, 0x0f, 0x1f, 0xf0, 0xff } +#define MASK_VRR_VVV0U2 { 0xff, 0x00, 0x0f, 0x2f, 0xf0, 0xff } +#define MASK_VRR_VVV0U3 { 0xff, 0x00, 0x0f, 0x3f, 0xf0, 0xff } +#define MASK_VRR_VVV { 0xff, 0x00, 0x0f, 0xff, 0xf0, 0xff } +#define MASK_VRR_VVV2 { 0xff, 0x00, 0x0f, 0xff, 0xf0, 0xff } +#define MASK_VRR_VVV0V { 0xff, 0x00, 0x0f, 0xff, 0x00, 0xff } +#define MASK_VRR_VV0U { 0xff, 0x00, 0xff, 0xff, 0x00, 0xff } +#define MASK_VRR_VV0U2 { 0xff, 0x00, 0xff, 0x0f, 0xf0, 0xff } +#define MASK_VRR_VV0UU { 0xff, 0x00, 0xff, 0x00, 0xf0, 0xff } +#define MASK_VRR_VV0UU2 { 0xff, 0x00, 0xff, 0xf0, 0x00, 0xff } +#define MASK_VRR_VV0UU8 { 0xff, 0x00, 0xff, 0x08, 0xf0, 0xff } +#define MASK_VRR_VV { 0xff, 0x00, 0xff, 0xff, 0xf0, 0xff } +#define MASK_VRR_VVVUU0V { 0xff, 0x00, 0x00, 0x0f, 0x00, 0xff } +#define MASK_VRR_VVVU0V { 0xff, 0x00, 0x00, 0xff, 0x00, 0xff } +#define MASK_VRR_VVVU0VB { 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff } +#define MASK_VRR_VVVU0VB1 { 0xff, 0x00, 0x0f, 0x1f, 0x00, 0xff } +#define MASK_VRR_VVVU0VB2 { 0xff, 0x00, 0x0f, 0x2f, 0x00, 0xff } +#define MASK_VRR_VVVU0VB3 { 0xff, 0x00, 0x0f, 0x3f, 0x00, 0xff } +#define MASK_VRR_VVV0U0U { 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff } +#define MASK_VRR_VVVV { 0xff, 0x00, 0x0f, 0xff, 0x00, 0xff } +#define MASK_VRR_VVV0UUU { 0xff, 0x00, 0x0f, 0x00, 0x00, 0xff } +#define MASK_VRR_VVV0UU { 0xff, 0x00, 0x0f, 0xf0, 0x00, 0xff } +#define MASK_VRR_VV0UUU { 0xff, 0x00, 0xff, 0x00, 0x00, 0xff } +#define MASK_VRR_VVVU0UV { 0xff, 0x00, 0x00, 0xf0, 0x00, 0xff } +#define MASK_VRR_VV0U0U { 0xff, 0x00, 0xff, 0x0f, 0x00, 0xff } +#define MASK_VRR_0V { 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff } +#define MASK_VRR_0V0U { 0xff, 0xf0, 0xf0, 0x00, 0x00, 0xff } +#define MASK_VRR_0VVU { 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff } +#define MASK_VRR_0VV0U { 0xff, 0xf0, 0x0f, 0x0f, 0xf0, 0xff } +#define MASK_VRR_RV0U { 0xff, 0x00, 0xff, 0x0f, 0xf0, 0xff } +#define MASK_VRR_RV0UU { 0xff, 0x00, 0xff, 0x00, 0xf0, 0xff } +#define MASK_VSI_URDV { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } + + +/* The opcode formats table (blueprints for .insn pseudo mnemonic). */ + +const struct s390_opcode s390_opformats[] = + { + { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0, 256, NULL }, + { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 256, NULL }, + { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0, 256, NULL }, + { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0, 256, NULL }, + { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0, 256, NULL }, + { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6, 256, NULL }, + { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 256, NULL }, + { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 256, NULL }, + { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 256, NULL }, + { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6, 256, NULL }, + { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 256, NULL }, + { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0, 256, NULL }, + { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 256, NULL }, + { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 256, NULL }, + { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 256, NULL }, + { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0, 256, NULL }, + { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0, 256, NULL }, + { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 256, NULL }, + { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0, 256, NULL }, + { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 256, NULL }, + { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3, 256, NULL }, + { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6, 256, NULL }, + { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 256, NULL }, + { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 256, NULL }, + { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0, 256, NULL }, + { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9, 256, NULL }, + { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9, 256, NULL }, + { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9, 256, NULL }, + { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9, 256, NULL }, + { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9, 256, NULL }, + { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10, 256, NULL }, +}; + +const int s390_num_opformats = + sizeof (s390_opformats) / sizeof (s390_opformats[0]); + +#include "s390-opc.tab" diff --git a/VEX/priv/objdump/s390-opc.tab b/VEX/priv/objdump/s390-opc.tab new file mode 100644 index 0000000000..f15035feac --- /dev/null +++ b/VEX/priv/objdump/s390-opc.tab @@ -0,0 +1,2793 @@ +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ + +/* The opcode table. This file was generated by s390-mkopc. + + The format of the opcode table is: + + NAME OPCODE MASK OPERANDS + + Name is the name of the instruction. + OPCODE is the instruction opcode. + MASK is the opcode mask; this is used to tell the disassembler + which bits in the actual opcode must match OPCODE. + OPERANDS is the list of operands. + + The disassembler reads the table in order and prints the first + instruction which matches. + MODE_BITS - zarch or esa + MIN_CPU - number of the min cpu level required + FLAGS - instruction flags. + DESCRIPTION - description of the instruction. */ + +const struct s390_opcode s390_opcodes[] = + { + { "dp", OP8(0xfdLL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "divide decimal" }, + { "mp", OP8(0xfcLL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "multiply decimal" }, + { "sp", OP8(0xfbLL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "subtract decimal" }, + { "ap", OP8(0xfaLL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "add decimal" }, + { "cp", OP8(0xf9LL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "compare decimal" }, + { "zap", OP8(0xf8LL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "zero and add" }, + { "unpk", OP8(0xf3LL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "unpack" }, + { "pack", OP8(0xf2LL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "pack" }, + { "mvo", OP8(0xf1LL), MASK_SS_LLRDRD, INSTR_SS_LLRDRD, 3, 0, 0, "move with offset" }, + { "srp", OP8(0xf0LL), MASK_SS_LIRDRD, INSTR_SS_LIRDRD, 3, 0, 0, "shift and round decimal" }, + { "lmd", OP8(0xefLL), MASK_SS_RRRDRD3, INSTR_SS_RRRDRD3, 2, 2, 0, "load multiple disjoint" }, + { "plo", OP8(0xeeLL), MASK_SS_RRRDRD2, INSTR_SS_RRRDRD2, 3, 0, 0, "perform locked operation" }, + { "cxpt", OP48(0xed00000000afLL), MASK_RSL_LRDFEU, INSTR_RSL_LRDFEU, 2, 9, 0, "convert from packed to extended dfp" }, + { "cdpt", OP48(0xed00000000aeLL), MASK_RSL_LRDFU, INSTR_RSL_LRDFU, 2, 9, 0, "convert from packed to long dfp" }, + { "cpxt", OP48(0xed00000000adLL), MASK_RSL_LRDFEU, INSTR_RSL_LRDFEU, 2, 9, 0, "convert from extended dfp to packed" }, + { "cpdt", OP48(0xed00000000acLL), MASK_RSL_LRDFU, INSTR_RSL_LRDFU, 2, 9, 0, "convert from long dfp to packed" }, + { "cxzt", OP48(0xed00000000abLL), MASK_RSL_LRDFEU, INSTR_RSL_LRDFEU, 2, 8, 0, "convert from zoned extended" }, + { "cdzt", OP48(0xed00000000aaLL), MASK_RSL_LRDFU, INSTR_RSL_LRDFU, 2, 8, 0, "convert from zoned long" }, + { "czxt", OP48(0xed00000000a9LL), MASK_RSL_LRDFEU, INSTR_RSL_LRDFEU, 2, 8, 0, "convert to zoned extended" }, + { "czdt", OP48(0xed00000000a8LL), MASK_RSL_LRDFU, INSTR_RSL_LRDFU, 2, 8, 0, "convert to zoned long" }, + { "stdy", OP48(0xed0000000067LL), MASK_RXY_FRRD, INSTR_RXY_FRRD, 2, 3, 0, "store (long) with long offset" }, + { "stey", OP48(0xed0000000066LL), MASK_RXY_FRRD, INSTR_RXY_FRRD, 2, 3, 0, "store (short) with long offset" }, + { "ldy", OP48(0xed0000000065LL), MASK_RXY_FRRD, INSTR_RXY_FRRD, 2, 3, 0, "load (long) with long offset" }, + { "ley", OP48(0xed0000000064LL), MASK_RXY_FRRD, INSTR_RXY_FRRD, 2, 3, 0, "load (short) with long offset" }, + { "tdgxt", OP48(0xed0000000059LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 2, 5, 0, "test data group extended dfp" }, + { "tdcxt", OP48(0xed0000000058LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 2, 5, 0, "test data class extended dfp" }, + { "tdgdt", OP48(0xed0000000055LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 2, 5, 0, "test data group long dfp" }, + { "tdcdt", OP48(0xed0000000054LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 2, 5, 0, "test data class long dfp" }, + { "tdget", OP48(0xed0000000051LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 2, 5, 0, "test data group short dfp" }, + { "tdcet", OP48(0xed0000000050LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 2, 5, 0, "test data class short dfp" }, + { "srxt", OP48(0xed0000000049LL), MASK_RXF_FERRDFE, INSTR_RXF_FERRDFE, 2, 5, 0, "shift coefficient right extended dfp" }, + { "slxt", OP48(0xed0000000048LL), MASK_RXF_FERRDFE, INSTR_RXF_FERRDFE, 2, 5, 0, "shift coefficient left extended dfp" }, + { "srdt", OP48(0xed0000000041LL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 5, 0, "shift coefficient right long dfp" }, + { "sldt", OP48(0xed0000000040LL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 5, 0, "shift coefficient left long dfp" }, + { "msd", OP48(0xed000000003fLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 3, 0, "multiply and subtract long hfp" }, + { "mad", OP48(0xed000000003eLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 3, 0, "multiply and add long hfp" }, + { "myh", OP48(0xed000000003dLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 4, 0, "multiply unnormalized long hfp high" }, + { "mayh", OP48(0xed000000003cLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 4, 0, "multiply and add unnormalized long hfp high" }, + { "my", OP48(0xed000000003bLL), MASK_RXF_FRRDFE, INSTR_RXF_FRRDFE, 2, 4, 0, "multiply unnormalized long hfp" }, + { "may", OP48(0xed000000003aLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 4, 0, "multiply and add unnormalized long hfp" }, + { "myl", OP48(0xed0000000039LL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 4, 0, "multiply unnormalized long hfp low" }, + { "mayl", OP48(0xed0000000038LL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 2, 4, 0, "multiply and add unnormalized long hfp low" }, + { "mee", OP48(0xed0000000037LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "multiply short hfp" }, + { "sqd", OP48(0xed0000000035LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "square root long hfp" }, + { "sqe", OP48(0xed0000000034LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "square root short hfp" }, + { "mse", OP48(0xed000000002fLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 3, 0, "multiply and subttract short hfp" }, + { "mae", OP48(0xed000000002eLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 3, 0, "multiply and add short hfp" }, + { "lxe", OP48(0xed0000000026LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "load lengthened short to extended hfp" }, + { "lxd", OP48(0xed0000000025LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "load lengthened long to extended hfp" }, + { "lde", OP48(0xed0000000024LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "load lengthened short to long hfp" }, + { "msdb", OP48(0xed000000001fLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 0, 0, "multiply and subtract long bfp" }, + { "madb", OP48(0xed000000001eLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 0, 0, "multiply and add long bfp" }, + { "ddb", OP48(0xed000000001dLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "divide long bfp" }, + { "mdb", OP48(0xed000000001cLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "multiply long bfp" }, + { "sdb", OP48(0xed000000001bLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "subtract long bfp" }, + { "adb", OP48(0xed000000001aLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "add long bfp" }, + { "cdb", OP48(0xed0000000019LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "compare long bfp" }, + { "kdb", OP48(0xed0000000018LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "compare and signal long bfp" }, + { "meeb", OP48(0xed0000000017LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "multiply short bfp" }, + { "sqdb", OP48(0xed0000000015LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "square root long bfp" }, + { "sqeb", OP48(0xed0000000014LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "square root short bfp" }, + { "tcxb", OP48(0xed0000000012LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "test data class extended bfp" }, + { "tcdb", OP48(0xed0000000011LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "test data class long bfp" }, + { "tceb", OP48(0xed0000000010LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "test data class short bfp" }, + { "mseb", OP48(0xed000000000fLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 0, 0, "multiply and subtract short bfp" }, + { "maeb", OP48(0xed000000000eLL), MASK_RXF_FRRDF, INSTR_RXF_FRRDF, 3, 0, 0, "multiply and add short bfp" }, + { "deb", OP48(0xed000000000dLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "divide short bfp" }, + { "mdeb", OP48(0xed000000000cLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "multiply short to long bfp" }, + { "seb", OP48(0xed000000000bLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "subtract short bfp" }, + { "aeb", OP48(0xed000000000aLL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "add short bfp" }, + { "ceb", OP48(0xed0000000009LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "compare short bfp" }, + { "keb", OP48(0xed0000000008LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "compare and signal short bfp" }, + { "mxdb", OP48(0xed0000000007LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "multiply long to extended bfp" }, + { "lxeb", OP48(0xed0000000006LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "load lengthened short to extended bfp" }, + { "lxdb", OP48(0xed0000000005LL), MASK_RXE_FERRD, INSTR_RXE_FERRD, 3, 0, 0, "load lengthened long to extended bfp" }, + { "ldeb", OP48(0xed0000000004LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0, 0, "load lengthened short to long bfp" }, + { "lochhino", OP48(0xec0e0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not overflow / if not ones" }, + { "locghino", OP48(0xec0e00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not overflow / if not ones" }, + { "lochino", OP48(0xec0e00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not overflow / if not ones" }, + { "lochhinh", OP48(0xec0d0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A not high" }, + { "lochhinp", OP48(0xec0d0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not plus" }, + { "locghinh", OP48(0xec0d00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A not high" }, + { "locghinp", OP48(0xec0d00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not plus" }, + { "lochinh", OP48(0xec0d00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A not high" }, + { "lochinp", OP48(0xec0d00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not plus" }, + { "clibnh", OP48(0xec0c000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A not high" }, + { "clible", OP48(0xec0c000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on low or equal" }, + { "cibnh", OP48(0xec0c000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A not high" }, + { "cible", OP48(0xec0c000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on low or equal" }, + { "clgibnh", OP48(0xec0c000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A not high" }, + { "clgible", OP48(0xec0c000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on low or equal" }, + { "cgibnh", OP48(0xec0c000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A not high" }, + { "cgible", OP48(0xec0c000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on low or equal" }, + { "clijnh", OP48(0xec0c0000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A not high" }, + { "clijle", OP48(0xec0c0000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on low or equal" }, + { "cijnh", OP48(0xec0c0000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A not high" }, + { "cijle", OP48(0xec0c0000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on low or equal" }, + { "clgijnh", OP48(0xec0c0000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A not high" }, + { "clgijle", OP48(0xec0c0000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on low or equal" }, + { "cgijnh", OP48(0xec0c0000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A not high" }, + { "cgijle", OP48(0xec0c0000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on low or equal" }, + { "lochhile", OP48(0xec0c0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on low or equal" }, + { "locghile", OP48(0xec0c00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on low or equal" }, + { "lochile", OP48(0xec0c00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on low or equal" }, + { "lochhinl", OP48(0xec0b0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A not low" }, + { "lochhinm", OP48(0xec0b0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not minus / if not mixed" }, + { "locghinl", OP48(0xec0b00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A not low" }, + { "locghinm", OP48(0xec0b00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not minus / if not mixed" }, + { "lochinl", OP48(0xec0b00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A not low" }, + { "lochinm", OP48(0xec0b00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not minus / if not mixed" }, + { "clibnl", OP48(0xec0a000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A not low" }, + { "clibhe", OP48(0xec0a000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on high or equal" }, + { "cibnl", OP48(0xec0a000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A not low" }, + { "cibhe", OP48(0xec0a000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on high or equal" }, + { "clgibnl", OP48(0xec0a000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A not low" }, + { "clgibhe", OP48(0xec0a000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on high or equal" }, + { "cgibnl", OP48(0xec0a000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A not low" }, + { "cgibhe", OP48(0xec0a000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on high or equal" }, + { "clijnl", OP48(0xec0a0000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A not low" }, + { "clijhe", OP48(0xec0a0000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on high or equal" }, + { "cijnl", OP48(0xec0a0000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A not low" }, + { "cijhe", OP48(0xec0a0000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on high or equal" }, + { "clgijnl", OP48(0xec0a0000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A not low" }, + { "clgijhe", OP48(0xec0a0000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on high or equal" }, + { "cgijnl", OP48(0xec0a0000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A not low" }, + { "cgijhe", OP48(0xec0a0000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on high or equal" }, + { "lochhihe", OP48(0xec0a0000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on high or equal" }, + { "locghihe", OP48(0xec0a00000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on high or equal" }, + { "lochihe", OP48(0xec0a00000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on high or equal" }, + { "lochhinlh", OP48(0xec090000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not low or high" }, + { "locghinlh", OP48(0xec0900000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not low or high" }, + { "lochinlh", OP48(0xec0900000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not low or high" }, + { "clibe", OP48(0xec08000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A equal B" }, + { "clibnlh", OP48(0xec08000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on not low or high" }, + { "cibe", OP48(0xec08000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A equal B" }, + { "cibnlh", OP48(0xec08000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on not low or high" }, + { "clgibe", OP48(0xec08000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A equal B" }, + { "clgibnlh", OP48(0xec08000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on not low or high" }, + { "cgibe", OP48(0xec08000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A equal B" }, + { "cgibnlh", OP48(0xec08000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on not low or high" }, + { "clije", OP48(0xec080000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A equal B" }, + { "clijnlh", OP48(0xec080000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on not low or high" }, + { "cije", OP48(0xec080000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A equal B" }, + { "cijnlh", OP48(0xec080000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on not low or high" }, + { "clgije", OP48(0xec080000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A equal B" }, + { "clgijnlh", OP48(0xec080000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on not low or high" }, + { "cgije", OP48(0xec080000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A equal B" }, + { "cgijnlh", OP48(0xec080000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on not low or high" }, + { "lochhie", OP48(0xec080000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A equal B" }, + { "lochhiz", OP48(0xec080000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on zero / if zeros" }, + { "locghie", OP48(0xec0800000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A equal B" }, + { "locghiz", OP48(0xec0800000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on zero / if zeros" }, + { "lochie", OP48(0xec0800000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A equal B" }, + { "lochiz", OP48(0xec0800000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on zero / if zeros" }, + { "lochhine", OP48(0xec070000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A not equal B" }, + { "lochhinz", OP48(0xec070000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not zero / if not zeros" }, + { "locghine", OP48(0xec0700000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A not equal B" }, + { "locghinz", OP48(0xec0700000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not zero / if not zeros" }, + { "lochine", OP48(0xec0700000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A not equal B" }, + { "lochinz", OP48(0xec0700000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not zero / if not zeros" }, + { "clibne", OP48(0xec06000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A not equal B" }, + { "cliblh", OP48(0xec06000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on low or high" }, + { "cibne", OP48(0xec06000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A not equal B" }, + { "ciblh", OP48(0xec06000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on low or high" }, + { "clgibne", OP48(0xec06000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A not equal B" }, + { "clgiblh", OP48(0xec06000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on low or high" }, + { "cgibne", OP48(0xec06000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A not equal B" }, + { "cgiblh", OP48(0xec06000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on low or high" }, + { "clijne", OP48(0xec060000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A not equal B" }, + { "clijlh", OP48(0xec060000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on low or high" }, + { "cijne", OP48(0xec060000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A not equal B" }, + { "cijlh", OP48(0xec060000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on low or high" }, + { "clgijne", OP48(0xec060000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A not equal B" }, + { "clgijlh", OP48(0xec060000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on low or high" }, + { "cgijne", OP48(0xec060000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A not equal B" }, + { "cgijlh", OP48(0xec060000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on low or high" }, + { "lochhilh", OP48(0xec060000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on low or high" }, + { "locghilh", OP48(0xec0600000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on low or high" }, + { "lochilh", OP48(0xec0600000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on low or high" }, + { "lochhinhe", OP48(0xec050000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not high or equal" }, + { "locghinhe", OP48(0xec0500000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not high or equal" }, + { "lochinhe", OP48(0xec0500000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not high or equal" }, + { "clibl", OP48(0xec04000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A low" }, + { "clibnhe", OP48(0xec04000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on not high or equal" }, + { "cibl", OP48(0xec04000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A low" }, + { "cibnhe", OP48(0xec04000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on not high or equal" }, + { "clgibl", OP48(0xec04000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A low" }, + { "clgibnhe", OP48(0xec04000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on not high or equal" }, + { "cgibl", OP48(0xec04000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A low" }, + { "cgibnhe", OP48(0xec04000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on not high or equal" }, + { "clijl", OP48(0xec040000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A low" }, + { "clijnhe", OP48(0xec040000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on not high or equal" }, + { "cijl", OP48(0xec040000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A low" }, + { "cijnhe", OP48(0xec040000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on not high or equal" }, + { "clgijl", OP48(0xec040000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A low" }, + { "clgijnhe", OP48(0xec040000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on not high or equal" }, + { "cgijl", OP48(0xec040000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A low" }, + { "cgijnhe", OP48(0xec040000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on not high or equal" }, + { "lochhil", OP48(0xec040000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A low" }, + { "lochhim", OP48(0xec040000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on minus / if mixed" }, + { "locghil", OP48(0xec0400000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A low" }, + { "locghim", OP48(0xec0400000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on minus / if mixed" }, + { "lochil", OP48(0xec0400000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A low" }, + { "lochim", OP48(0xec0400000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on minus / if mixed" }, + { "lochhinle", OP48(0xec030000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on not low or equal" }, + { "locghinle", OP48(0xec0300000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on not low or equal" }, + { "lochinle", OP48(0xec0300000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on not low or equal" }, + { "clibh", OP48(0xec02000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on A high" }, + { "clibnle", OP48(0xec02000000ffLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (32<8) on not low or equal" }, + { "cibh", OP48(0xec02000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on A high" }, + { "cibnle", OP48(0xec02000000feLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (32<8) on not low or equal" }, + { "clgibh", OP48(0xec02000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on A high" }, + { "clgibnle", OP48(0xec02000000fdLL), MASK_RIS_R0RDU, INSTR_RIS_R0RDU, 2, 6, 0, "compare logical immediate and branch (64<8) on not low or equal" }, + { "cgibh", OP48(0xec02000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on A high" }, + { "cgibnle", OP48(0xec02000000fcLL), MASK_RIS_R0RDI, INSTR_RIS_R0RDI, 2, 6, 0, "compare immediate and branch (64<8) on not low or equal" }, + { "clijh", OP48(0xec020000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on A high" }, + { "clijnle", OP48(0xec020000007fLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (32<8) on not low or equal" }, + { "cijh", OP48(0xec020000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on A high" }, + { "cijnle", OP48(0xec020000007eLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (32<8) on not low or equal" }, + { "clgijh", OP48(0xec020000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on A high" }, + { "clgijnle", OP48(0xec020000007dLL), MASK_RIE_R0PU, INSTR_RIE_R0PU, 2, 6, 112, "compare logical immediate and branch relative (64<8) on not low or equal" }, + { "cgijh", OP48(0xec020000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on A high" }, + { "cgijnle", OP48(0xec020000007cLL), MASK_RIE_R0PI, INSTR_RIE_R0PI, 2, 6, 112, "compare immediate and branch relative (64<8) on not low or equal" }, + { "lochhih", OP48(0xec020000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on A high" }, + { "lochhip", OP48(0xec020000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on plus" }, + { "locghih", OP48(0xec0200000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on A high" }, + { "locghip", OP48(0xec0200000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on plus" }, + { "lochih", OP48(0xec0200000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on A high" }, + { "lochip", OP48(0xec0200000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on plus" }, + { "lochhio", OP48(0xec010000004eLL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword high immediate on condition on overflow / if ones" }, + { "locghio", OP48(0xec0100000046LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr on overflow / if ones" }, + { "lochio", OP48(0xec0100000042LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr on overflow / if ones" }, + { "rxsbgt", OP48(0xec0080000057LL), MASK_RIE_RRUUU4, INSTR_RIE_RRUUU4, 2, 6, 1, "rotate then exclusive or selected bits and test results" }, + { "rosbgt", OP48(0xec0080000056LL), MASK_RIE_RRUUU4, INSTR_RIE_RRUUU4, 2, 6, 1, "rotate then or selected bits and test results" }, + { "rnsbgt", OP48(0xec0080000054LL), MASK_RIE_RRUUU4, INSTR_RIE_RRUUU4, 2, 6, 1, "rotate then and selected bits and test results" }, + { "risbhgz", OP48(0xec000080005dLL), MASK_RIE_RRUUU3, INSTR_RIE_RRUUU3, 2, 7, 1, "rotate then insert selected bits high and zero remaining bits" }, + { "risbgnz", OP48(0xec0000800059LL), MASK_RIE_RRUUU2, INSTR_RIE_RRUUU2, 2, 8, 1, "rotate then insert selected bits and zero remaining bits nocc" }, + { "risbgz", OP48(0xec0000800055LL), MASK_RIE_RRUUU2, INSTR_RIE_RRUUU2, 2, 6, 1, "rotate then insert selected bits and zero remaining bits" }, + { "risblgz", OP48(0xec0000800051LL), MASK_RIE_RRUUU3, INSTR_RIE_RRUUU3, 2, 7, 1, "rotate then insert selected bits low and zero remaining bits" }, + { "clrbnh", OP48(0xec000000c0f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A not high" }, + { "clrble", OP48(0xec000000c0f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on low or equal" }, + { "crbnh", OP48(0xec000000c0f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A not high" }, + { "crble", OP48(0xec000000c0f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on low or equal" }, + { "clgrbnh", OP48(0xec000000c0e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A not high" }, + { "clgrble", OP48(0xec000000c0e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on low or equal" }, + { "cgrbnh", OP48(0xec000000c0e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A not high" }, + { "cgrble", OP48(0xec000000c0e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on low or equal" }, + { "clrjnh", OP48(0xec000000c077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A not high" }, + { "clrjle", OP48(0xec000000c077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on low or equal" }, + { "crjnh", OP48(0xec000000c076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A not high" }, + { "crjle", OP48(0xec000000c076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on low or equal" }, + { "clfitnh", OP48(0xec000000c073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A not high" }, + { "clfitle", OP48(0xec000000c073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on low or equal" }, + { "citnh", OP48(0xec000000c072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A not high" }, + { "citle", OP48(0xec000000c072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on low or equal" }, + { "clgitnh", OP48(0xec000000c071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A not high" }, + { "clgitle", OP48(0xec000000c071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on low or equal" }, + { "cgitnh", OP48(0xec000000c070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A not high" }, + { "cgitle", OP48(0xec000000c070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on low or equal" }, + { "clgrjnh", OP48(0xec000000c065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A not high" }, + { "clgrjle", OP48(0xec000000c065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on low or equal" }, + { "cgrjnh", OP48(0xec000000c064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A not high" }, + { "cgrjle", OP48(0xec000000c064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on low or equal" }, + { "clrbnl", OP48(0xec000000a0f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A not low" }, + { "clrbhe", OP48(0xec000000a0f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on high or equal" }, + { "crbnl", OP48(0xec000000a0f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A not low" }, + { "crbhe", OP48(0xec000000a0f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on high or equal" }, + { "clgrbnl", OP48(0xec000000a0e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A not low" }, + { "clgrbhe", OP48(0xec000000a0e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on high or equal" }, + { "cgrbnl", OP48(0xec000000a0e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A not low" }, + { "cgrbhe", OP48(0xec000000a0e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on high or equal" }, + { "clrjnl", OP48(0xec000000a077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A not low" }, + { "clrjhe", OP48(0xec000000a077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on high or equal" }, + { "crjnl", OP48(0xec000000a076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A not low" }, + { "crjhe", OP48(0xec000000a076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on high or equal" }, + { "clfitnl", OP48(0xec000000a073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A not low" }, + { "clfithe", OP48(0xec000000a073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on high or equal" }, + { "citnl", OP48(0xec000000a072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A not low" }, + { "cithe", OP48(0xec000000a072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on high or equal" }, + { "clgitnl", OP48(0xec000000a071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A not low" }, + { "clgithe", OP48(0xec000000a071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on high or equal" }, + { "cgitnl", OP48(0xec000000a070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A not low" }, + { "cgithe", OP48(0xec000000a070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on high or equal" }, + { "clgrjnl", OP48(0xec000000a065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A not low" }, + { "clgrjhe", OP48(0xec000000a065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on high or equal" }, + { "cgrjnl", OP48(0xec000000a064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A not low" }, + { "cgrjhe", OP48(0xec000000a064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on high or equal" }, + { "clrbe", OP48(0xec00000080f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A equal B" }, + { "clrbnlh", OP48(0xec00000080f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on not low or high" }, + { "crbe", OP48(0xec00000080f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A equal B" }, + { "crbnlh", OP48(0xec00000080f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on not low or high" }, + { "clgrbe", OP48(0xec00000080e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A equal B" }, + { "clgrbnlh", OP48(0xec00000080e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on not low or high" }, + { "cgrbe", OP48(0xec00000080e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A equal B" }, + { "cgrbnlh", OP48(0xec00000080e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on not low or high" }, + { "clrje", OP48(0xec0000008077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A equal B" }, + { "clrjnlh", OP48(0xec0000008077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on not low or high" }, + { "crje", OP48(0xec0000008076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A equal B" }, + { "crjnlh", OP48(0xec0000008076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on not low or high" }, + { "clfite", OP48(0xec0000008073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A equal B" }, + { "clfitnlh", OP48(0xec0000008073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on not low or high" }, + { "cite", OP48(0xec0000008072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A equal B" }, + { "citnlh", OP48(0xec0000008072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on not low or high" }, + { "clgite", OP48(0xec0000008071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A equal B" }, + { "clgitnlh", OP48(0xec0000008071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on not low or high" }, + { "cgite", OP48(0xec0000008070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A equal B" }, + { "cgitnlh", OP48(0xec0000008070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on not low or high" }, + { "clgrje", OP48(0xec0000008065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A equal B" }, + { "clgrjnlh", OP48(0xec0000008065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on not low or high" }, + { "cgrje", OP48(0xec0000008064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A equal B" }, + { "cgrjnlh", OP48(0xec0000008064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on not low or high" }, + { "clrbne", OP48(0xec00000060f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A not equal B" }, + { "clrblh", OP48(0xec00000060f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on low or high" }, + { "crbne", OP48(0xec00000060f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A not equal B" }, + { "crblh", OP48(0xec00000060f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on low or high" }, + { "clgrbne", OP48(0xec00000060e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A not equal B" }, + { "clgrblh", OP48(0xec00000060e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on low or high" }, + { "cgrbne", OP48(0xec00000060e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A not equal B" }, + { "cgrblh", OP48(0xec00000060e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on low or high" }, + { "clrjne", OP48(0xec0000006077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A not equal B" }, + { "clrjlh", OP48(0xec0000006077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on low or high" }, + { "crjne", OP48(0xec0000006076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A not equal B" }, + { "crjlh", OP48(0xec0000006076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on low or high" }, + { "clfitne", OP48(0xec0000006073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A not equal B" }, + { "clfitlh", OP48(0xec0000006073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on low or high" }, + { "citne", OP48(0xec0000006072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A not equal B" }, + { "citlh", OP48(0xec0000006072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on low or high" }, + { "clgitne", OP48(0xec0000006071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A not equal B" }, + { "clgitlh", OP48(0xec0000006071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on low or high" }, + { "cgitne", OP48(0xec0000006070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A not equal B" }, + { "cgitlh", OP48(0xec0000006070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on low or high" }, + { "clgrjne", OP48(0xec0000006065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A not equal B" }, + { "clgrjlh", OP48(0xec0000006065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on low or high" }, + { "cgrjne", OP48(0xec0000006064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A not equal B" }, + { "cgrjlh", OP48(0xec0000006064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on low or high" }, + { "clrbl", OP48(0xec00000040f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A low" }, + { "clrbnhe", OP48(0xec00000040f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on not high or equal" }, + { "crbl", OP48(0xec00000040f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A low" }, + { "crbnhe", OP48(0xec00000040f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on not high or equal" }, + { "clgrbl", OP48(0xec00000040e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A low" }, + { "clgrbnhe", OP48(0xec00000040e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on not high or equal" }, + { "cgrbl", OP48(0xec00000040e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A low" }, + { "cgrbnhe", OP48(0xec00000040e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on not high or equal" }, + { "clrjl", OP48(0xec0000004077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A low" }, + { "clrjnhe", OP48(0xec0000004077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on not high or equal" }, + { "crjl", OP48(0xec0000004076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A low" }, + { "crjnhe", OP48(0xec0000004076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on not high or equal" }, + { "clfitl", OP48(0xec0000004073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A low" }, + { "clfitnhe", OP48(0xec0000004073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on not high or equal" }, + { "citl", OP48(0xec0000004072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A low" }, + { "citnhe", OP48(0xec0000004072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on not high or equal" }, + { "clgitl", OP48(0xec0000004071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A low" }, + { "clgitnhe", OP48(0xec0000004071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on not high or equal" }, + { "cgitl", OP48(0xec0000004070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A low" }, + { "cgitnhe", OP48(0xec0000004070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on not high or equal" }, + { "clgrjl", OP48(0xec0000004065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A low" }, + { "clgrjnhe", OP48(0xec0000004065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on not high or equal" }, + { "cgrjl", OP48(0xec0000004064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A low" }, + { "cgrjnhe", OP48(0xec0000004064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on not high or equal" }, + { "clrbh", OP48(0xec00000020f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on A high" }, + { "clrbnle", OP48(0xec00000020f7LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (32) on not low or equal" }, + { "crbh", OP48(0xec00000020f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on A high" }, + { "crbnle", OP48(0xec00000020f6LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (32) on not low or equal" }, + { "clgrbh", OP48(0xec00000020e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on A high" }, + { "clgrbnle", OP48(0xec00000020e5LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare logical and branch (64) on not low or equal" }, + { "cgrbh", OP48(0xec00000020e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on A high" }, + { "cgrbnle", OP48(0xec00000020e4LL), MASK_RRS_RRRD0, INSTR_RRS_RRRD0, 2, 6, 0, "compare and branch (64) on not low or equal" }, + { "clrjh", OP48(0xec0000002077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on A high" }, + { "clrjnle", OP48(0xec0000002077LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (32) on not low or equal" }, + { "crjh", OP48(0xec0000002076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on A high" }, + { "crjnle", OP48(0xec0000002076LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (32) on not low or equal" }, + { "clfith", OP48(0xec0000002073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on A high" }, + { "clfitnle", OP48(0xec0000002073LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (32<16) on not low or equal" }, + { "cith", OP48(0xec0000002072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on A high" }, + { "citnle", OP48(0xec0000002072LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (32<16) on not low or equal" }, + { "clgith", OP48(0xec0000002071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on A high" }, + { "clgitnle", OP48(0xec0000002071LL), MASK_RIE_R0U0, INSTR_RIE_R0U0, 2, 6, 0, "compare logical and trap (64<16) on not low or equal" }, + { "cgith", OP48(0xec0000002070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on A high" }, + { "cgitnle", OP48(0xec0000002070LL), MASK_RIE_R0I0, INSTR_RIE_R0I0, 2, 6, 0, "compare immediate and trap (64<16) on not low or equal" }, + { "clgrjh", OP48(0xec0000002065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on A high" }, + { "clgrjnle", OP48(0xec0000002065LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare logical and branch relative (64) on not low or equal" }, + { "cgrjh", OP48(0xec0000002064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on A high" }, + { "cgrjnle", OP48(0xec0000002064LL), MASK_RIE_RRP0, INSTR_RIE_RRP0, 2, 6, 112, "compare and branch relative (64) on not low or equal" }, + { "clib", OP48(0xec00000000ffLL), MASK_RIS_RURDU, INSTR_RIS_RURDU, 2, 6, 0, "compare logical immediate and branch (32<8)" }, + { "cib", OP48(0xec00000000feLL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 2, 6, 0, "compare immediate and branch (32<8)" }, + { "clgib", OP48(0xec00000000fdLL), MASK_RIS_RURDU, INSTR_RIS_RURDU, 2, 6, 0, "compare logical immediate and branch (64<8)" }, + { "cgib", OP48(0xec00000000fcLL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 2, 6, 0, "compare immediate and branch (64<8)" }, + { "clrb", OP48(0xec00000000f7LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 2, 6, 0, "compare logical and branch (32)" }, + { "crb", OP48(0xec00000000f6LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 2, 6, 0, "compare and branch (32)" }, + { "clgrb", OP48(0xec00000000e5LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 2, 6, 0, "compare logical and branch (64)" }, + { "cgrb", OP48(0xec00000000e4LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 2, 6, 0, "compare and branch (64)" }, + { "alghsik", OP48(0xec00000000dbLL), MASK_RIE_RRI0, INSTR_RIE_RRI0, 2, 7, 0, "add logical immediate 3 operands 64 bit" }, + { "alhsik", OP48(0xec00000000daLL), MASK_RIE_RRI0, INSTR_RIE_RRI0, 2, 7, 0, "add logical immediate 3 operands 32 bit" }, + { "aghik", OP48(0xec00000000d9LL), MASK_RIE_RRI0, INSTR_RIE_RRI0, 2, 7, 0, "add immediate 3 operands 64 bit" }, + { "ahik", OP48(0xec00000000d8LL), MASK_RIE_RRI0, INSTR_RIE_RRI0, 2, 7, 0, "add immediate 3 operands 32 bit" }, + { "clij", OP48(0xec000000007fLL), MASK_RIE_RUPU, INSTR_RIE_RUPU, 2, 6, 112, "compare logical immediate and branch relative (32<8)" }, + { "cij", OP48(0xec000000007eLL), MASK_RIE_RUPI, INSTR_RIE_RUPI, 2, 6, 112, "compare immediate and branch relative (32<8)" }, + { "clgij", OP48(0xec000000007dLL), MASK_RIE_RUPU, INSTR_RIE_RUPU, 2, 6, 112, "compare logical immediate and branch relative (64<8)" }, + { "cgij", OP48(0xec000000007cLL), MASK_RIE_RUPI, INSTR_RIE_RUPI, 2, 6, 112, "compare immediate and branch relative (64<8)" }, + { "clrj", OP48(0xec0000000077LL), MASK_RIE_RRPU, INSTR_RIE_RRPU, 2, 6, 112, "compare logical and branch relative (32)" }, + { "crj", OP48(0xec0000000076LL), MASK_RIE_RRPU, INSTR_RIE_RRPU, 2, 6, 112, "compare and branch relative (32)" }, + { "clfit", OP48(0xec0000000073LL), MASK_RIE_R0UU, INSTR_RIE_R0UU, 2, 6, 0, "compare logical and trap (32<16)" }, + { "cit", OP48(0xec0000000072LL), MASK_RIE_R0IU, INSTR_RIE_R0IU, 2, 6, 0, "compare immediate and trap (32<16)" }, + { "clgit", OP48(0xec0000000071LL), MASK_RIE_R0UU, INSTR_RIE_R0UU, 2, 6, 0, "compare logical and trap (64<16)" }, + { "cgit", OP48(0xec0000000070LL), MASK_RIE_R0IU, INSTR_RIE_R0IU, 2, 6, 0, "compare immediate and trap (64<16)" }, + { "clgrj", OP48(0xec0000000065LL), MASK_RIE_RRPU, INSTR_RIE_RRPU, 2, 6, 112, "compare logical and branch relative (64)" }, + { "cgrj", OP48(0xec0000000064LL), MASK_RIE_RRPU, INSTR_RIE_RRPU, 2, 6, 112, "compare and branch relative (64)" }, + { "risbhg", OP48(0xec000000005dLL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 7, 1, "rotate then insert selected bits high" }, + { "risbgn", OP48(0xec0000000059LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 8, 1, "rotate then insert selected bits nocc" }, + { "rxsbg", OP48(0xec0000000057LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 6, 1, "rotate then exclusive or selected bits" }, + { "rosbg", OP48(0xec0000000056LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 6, 1, "rotate then or selected bits" }, + { "risbg", OP48(0xec0000000055LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 6, 1, "rotate then insert selected bits" }, + { "rnsbg", OP48(0xec0000000054LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 6, 1, "rotate then and selected bits" }, + { "risblg", OP48(0xec0000000051LL), MASK_RIE_RRUUU, INSTR_RIE_RRUUU, 2, 7, 1, "rotate then insert selected bits low" }, + { "lochhi", OP48(0xec000000004eLL), MASK_RIE_RUI0, INSTR_RIE_RUI0, 2, 9, 0, "load halfword high immediate on condition" }, + { "locghi", OP48(0xec0000000046LL), MASK_RIE_RUI0, INSTR_RIE_RUI0, 2, 9, 0, "load halfword immediate on condition into 64 bit gpr" }, + { "brxlg", OP48(0xec0000000045LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2, 112, "branch relative on index low or equal 64" }, + { "jxleg", OP48(0xec0000000045LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2, 112, "branch relative on index low or equal 64" }, + { "brxhg", OP48(0xec0000000044LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2, 112, "branch relative on index high 64" }, + { "jxhg", OP48(0xec0000000044LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2, 112, "branch relative on index high 64" }, + { "lochi", OP48(0xec0000000042LL), MASK_RIE_RUI0, INSTR_RIE_RUI0, 2, 9, 0, "load halfword immediate on condition into 32 bit gpr" }, + { "stocno", OP48(0xeb0e000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not overflow / if not ones" }, + { "locno", OP48(0xeb0e000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not overflow / if not ones" }, + { "stocgno", OP48(0xeb0e000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not overflow / if not ones" }, + { "locgno", OP48(0xeb0e000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not overflow / if not ones" }, + { "stocfhno", OP48(0xeb0e000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not overflow / if not ones" }, + { "locfhno", OP48(0xeb0e000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not overflow / if not ones" }, + { "stocnh", OP48(0xeb0d000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A not high" }, + { "stocnp", OP48(0xeb0d000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not plus" }, + { "locnh", OP48(0xeb0d000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A not high" }, + { "locnp", OP48(0xeb0d000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not plus" }, + { "stocgnh", OP48(0xeb0d000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A not high" }, + { "stocgnp", OP48(0xeb0d000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not plus" }, + { "locgnh", OP48(0xeb0d000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A not high" }, + { "locgnp", OP48(0xeb0d000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not plus" }, + { "stocfhnh", OP48(0xeb0d000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A not high" }, + { "stocfhnp", OP48(0xeb0d000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not plus" }, + { "locfhnh", OP48(0xeb0d000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A not high" }, + { "locfhnp", OP48(0xeb0d000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not plus" }, + { "stocle", OP48(0xeb0c000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on low or equal" }, + { "locle", OP48(0xeb0c000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on low or equal" }, + { "stocgle", OP48(0xeb0c000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on low or equal" }, + { "locgle", OP48(0xeb0c000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on low or equal" }, + { "stocfhle", OP48(0xeb0c000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on low or equal" }, + { "locfhle", OP48(0xeb0c000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on low or equal" }, + { "clgtnh", OP48(0xeb0c0000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A not high" }, + { "clgtle", OP48(0xeb0c0000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on low or equal" }, + { "cltnh", OP48(0xeb0c00000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A not high" }, + { "cltle", OP48(0xeb0c00000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on low or equal" }, + { "stocnl", OP48(0xeb0b000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A not low" }, + { "stocnm", OP48(0xeb0b000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not minus / if not mixed" }, + { "locnl", OP48(0xeb0b000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A not low" }, + { "locnm", OP48(0xeb0b000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not minus / if not mixed" }, + { "stocgnl", OP48(0xeb0b000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A not low" }, + { "stocgnm", OP48(0xeb0b000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not minus / if not mixed" }, + { "locgnl", OP48(0xeb0b000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A not low" }, + { "locgnm", OP48(0xeb0b000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not minus / if not mixed" }, + { "stocfhnl", OP48(0xeb0b000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A not low" }, + { "stocfhnm", OP48(0xeb0b000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not minus / if not mixed" }, + { "locfhnl", OP48(0xeb0b000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A not low" }, + { "locfhnm", OP48(0xeb0b000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not minus / if not mixed" }, + { "stoche", OP48(0xeb0a000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on high or equal" }, + { "loche", OP48(0xeb0a000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on high or equal" }, + { "stocghe", OP48(0xeb0a000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on high or equal" }, + { "locghe", OP48(0xeb0a000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on high or equal" }, + { "stocfhhe", OP48(0xeb0a000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on high or equal" }, + { "locfhhe", OP48(0xeb0a000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on high or equal" }, + { "clgtnl", OP48(0xeb0a0000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A not low" }, + { "clgthe", OP48(0xeb0a0000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on high or equal" }, + { "cltnl", OP48(0xeb0a00000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A not low" }, + { "clthe", OP48(0xeb0a00000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on high or equal" }, + { "stocnlh", OP48(0xeb09000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not low or high" }, + { "locnlh", OP48(0xeb09000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not low or high" }, + { "stocgnlh", OP48(0xeb09000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not low or high" }, + { "locgnlh", OP48(0xeb09000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not low or high" }, + { "stocfhnlh", OP48(0xeb09000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not low or high" }, + { "locfhnlh", OP48(0xeb09000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not low or high" }, + { "stoce", OP48(0xeb08000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A equal B" }, + { "stocz", OP48(0xeb08000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on zero / if zeros" }, + { "loce", OP48(0xeb08000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A equal B" }, + { "locz", OP48(0xeb08000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on zero / if zeros" }, + { "stocge", OP48(0xeb08000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A equal B" }, + { "stocgz", OP48(0xeb08000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on zero / if zeros" }, + { "locge", OP48(0xeb08000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A equal B" }, + { "locgz", OP48(0xeb08000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on zero / if zeros" }, + { "stocfhe", OP48(0xeb08000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A equal B" }, + { "stocfhz", OP48(0xeb08000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on zero / if zeros" }, + { "locfhe", OP48(0xeb08000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A equal B" }, + { "locfhz", OP48(0xeb08000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on zero / if zeros" }, + { "clgte", OP48(0xeb080000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A equal B" }, + { "clgtnlh", OP48(0xeb080000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on not low or high" }, + { "clte", OP48(0xeb0800000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A equal B" }, + { "cltnlh", OP48(0xeb0800000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on not low or high" }, + { "stocne", OP48(0xeb07000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A not equal B" }, + { "stocnz", OP48(0xeb07000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not zero / if not zeros" }, + { "locne", OP48(0xeb07000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A not equal B" }, + { "locnz", OP48(0xeb07000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not zero / if not zeros" }, + { "stocgne", OP48(0xeb07000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A not equal B" }, + { "stocgnz", OP48(0xeb07000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not zero / if not zeros" }, + { "locgne", OP48(0xeb07000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A not equal B" }, + { "locgnz", OP48(0xeb07000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not zero / if not zeros" }, + { "stocfhne", OP48(0xeb07000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A not equal B" }, + { "stocfhnz", OP48(0xeb07000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not zero / if not zeros" }, + { "locfhne", OP48(0xeb07000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A not equal B" }, + { "locfhnz", OP48(0xeb07000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not zero / if not zeros" }, + { "stoclh", OP48(0xeb06000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on low or high" }, + { "loclh", OP48(0xeb06000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on low or high" }, + { "stocglh", OP48(0xeb06000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on low or high" }, + { "locglh", OP48(0xeb06000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on low or high" }, + { "stocfhlh", OP48(0xeb06000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on low or high" }, + { "locfhlh", OP48(0xeb06000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on low or high" }, + { "clgtne", OP48(0xeb060000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A not equal B" }, + { "clgtlh", OP48(0xeb060000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on low or high" }, + { "cltne", OP48(0xeb0600000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A not equal B" }, + { "cltlh", OP48(0xeb0600000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on low or high" }, + { "stocnhe", OP48(0xeb05000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not high or equal" }, + { "locnhe", OP48(0xeb05000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not high or equal" }, + { "stocgnhe", OP48(0xeb05000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not high or equal" }, + { "locgnhe", OP48(0xeb05000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not high or equal" }, + { "stocfhnhe", OP48(0xeb05000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not high or equal" }, + { "locfhnhe", OP48(0xeb05000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not high or equal" }, + { "stocl", OP48(0xeb04000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A low" }, + { "stocm", OP48(0xeb04000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on minus / if mixed" }, + { "locl", OP48(0xeb04000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A low" }, + { "locm", OP48(0xeb04000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on minus / if mixed" }, + { "stocgl", OP48(0xeb04000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A low" }, + { "stocgm", OP48(0xeb04000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on minus / if mixed" }, + { "locgl", OP48(0xeb04000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A low" }, + { "locgm", OP48(0xeb04000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on minus / if mixed" }, + { "stocfhl", OP48(0xeb04000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A low" }, + { "stocfhm", OP48(0xeb04000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on minus / if mixed" }, + { "locfhl", OP48(0xeb04000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A low" }, + { "locfhm", OP48(0xeb04000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on minus / if mixed" }, + { "clgtl", OP48(0xeb040000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A low" }, + { "clgtnhe", OP48(0xeb040000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on not high or equal" }, + { "cltl", OP48(0xeb0400000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A low" }, + { "cltnhe", OP48(0xeb0400000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on not high or equal" }, + { "stocnle", OP48(0xeb03000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on not low or equal" }, + { "locnle", OP48(0xeb03000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on not low or equal" }, + { "stocgnle", OP48(0xeb03000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on not low or equal" }, + { "locgnle", OP48(0xeb03000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on not low or equal" }, + { "stocfhnle", OP48(0xeb03000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on not low or equal" }, + { "locfhnle", OP48(0xeb03000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on not low or equal" }, + { "stoch", OP48(0xeb02000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on A high" }, + { "stocp", OP48(0xeb02000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on plus" }, + { "loch", OP48(0xeb02000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on A high" }, + { "locp", OP48(0xeb02000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on plus" }, + { "stocgh", OP48(0xeb02000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on A high" }, + { "stocgp", OP48(0xeb02000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on plus" }, + { "locgh", OP48(0xeb02000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on A high" }, + { "locgp", OP48(0xeb02000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on plus" }, + { "stocfhh", OP48(0xeb02000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on A high" }, + { "stocfhp", OP48(0xeb02000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on plus" }, + { "locfhh", OP48(0xeb02000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on A high" }, + { "locfhp", OP48(0xeb02000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on plus" }, + { "clgth", OP48(0xeb020000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on A high" }, + { "clgtnle", OP48(0xeb020000002bLL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 64 bit reg-mem on not low or equal" }, + { "clth", OP48(0xeb0200000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on A high" }, + { "cltnle", OP48(0xeb0200000023LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 8, 0, "compare logical and trap 32 bit reg-mem on not low or equal" }, + { "stoco", OP48(0xeb01000000f3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 32 bit on overflow / if ones" }, + { "loco", OP48(0xeb01000000f2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 32 bit on overflow / if ones" }, + { "stocgo", OP48(0xeb01000000e3LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "store on condition 64 bit on overflow / if ones" }, + { "locgo", OP48(0xeb01000000e2LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 7, 0, "load on condition 64 bit on overflow / if ones" }, + { "stocfho", OP48(0xeb01000000e1LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "store high on condition on overflow / if ones" }, + { "locfho", OP48(0xeb01000000e0LL), MASK_RSY_R0RD, INSTR_RSY_R0RD, 2, 9, 0, "load high on condition from memory on overflow / if ones" }, + { "laal", OP48(0xeb00000000faLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and add logical 32 bit" }, + { "laa", OP48(0xeb00000000f8LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and add 32 bit" }, + { "lax", OP48(0xeb00000000f7LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and exclusive or 32 bit" }, + { "lao", OP48(0xeb00000000f6LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and or 32 bit" }, + { "lan", OP48(0xeb00000000f4LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and and 32 bit" }, + { "stoc", OP48(0xeb00000000f3LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 7, 0, "store on condition 32 bit" }, + { "loc", OP48(0xeb00000000f2LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 7, 0, "load on condition 32 bit" }, + { "laalg", OP48(0xeb00000000eaLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and add logical 64 bit" }, + { "laag", OP48(0xeb00000000e8LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and add 64 bit" }, + { "laxg", OP48(0xeb00000000e7LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and exclusive or 64 bit" }, + { "laog", OP48(0xeb00000000e6LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and or 64 bit" }, + { "lang", OP48(0xeb00000000e4LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "load and and 64 bit" }, + { "stocg", OP48(0xeb00000000e3LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 7, 0, "store on condition 64 bit" }, + { "locg", OP48(0xeb00000000e2LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 7, 0, "load on condition 64 bit" }, + { "stocfh", OP48(0xeb00000000e1LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 9, 0, "store high on condition" }, + { "locfh", OP48(0xeb00000000e0LL), MASK_RSY_RURD2, INSTR_RSY_RURD2, 2, 9, 0, "load high on condition from memory" }, + { "sllk", OP48(0xeb00000000dfLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "shift left single logical 3 operands 32 bit" }, + { "srlk", OP48(0xeb00000000deLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "shift right single logical 3 operands 32 bit" }, + { "slak", OP48(0xeb00000000ddLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "shift left single 3 operands 32 bit" }, + { "srak", OP48(0xeb00000000dcLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 7, 0, "shift right single 3 operands 32 bit" }, + { "tp", OP48(0xeb00000000c0LL), MASK_RSL_R0RD, INSTR_RSL_R0RD, 3, 0, 0, "test decimal" }, + { "stamy", OP48(0xeb000000009bLL), MASK_RSY_AARD, INSTR_RSY_AARD, 2, 3, 0, "store access multiple with long offset" }, + { "lamy", OP48(0xeb000000009aLL), MASK_RSY_AARD, INSTR_RSY_AARD, 2, 3, 0, "load access multiple" }, + { "lmy", OP48(0xeb0000000098LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "load multiple with long offset" }, + { "lmh", OP48(0xeb0000000096LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "load multiple high" }, + { "lmh", OP48(0xeb0000000096LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "load multiple high" }, + { "stmy", OP48(0xeb0000000090LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "store multiple with long offset" }, + { "clclu", OP48(0xeb000000008fLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 0, "compare logical long unicode with long offset" }, + { "mvclu", OP48(0xeb000000008eLL), MASK_RSY_RERERD, INSTR_RSY_RERERD, 3, 3, 0, "move long unicode" }, + { "mvclu", OP48(0xeb000000008eLL), MASK_RSE_RERERD, INSTR_RSE_RERERD, 3, 0, 0, "move long unicode" }, + { "icmy", OP48(0xeb0000000081LL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "insert characters with long offset" }, + { "icmh", OP48(0xeb0000000080LL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "insert characters under mask high with long offset" }, + { "icmh", OP48(0xeb0000000080LL), MASK_RSE_RURD, INSTR_RSE_RURD, 2, 2, 0, "insert characters under mask high" }, + { "algsi", OP48(0xeb000000007eLL), MASK_SIY_IRD, INSTR_SIY_IRD, 2, 6, 0, "add logical with signed immediate (64<8)" }, + { "agsi", OP48(0xeb000000007aLL), MASK_SIY_IRD, INSTR_SIY_IRD, 2, 6, 0, "add immediate (64<8)" }, + { "lpswey", OP48(0xeb0000000071LL), MASK_SIY_RD, INSTR_SIY_RD, 2, 12, 0, "load PSW extended" }, + { "alsi", OP48(0xeb000000006eLL), MASK_SIY_IRD, INSTR_SIY_IRD, 2, 6, 0, "add logical with signed immediate (32<8)" }, + { "asi", OP48(0xeb000000006aLL), MASK_SIY_IRD, INSTR_SIY_IRD, 2, 6, 0, "add immediate (32<8)" }, + { "xiy", OP48(0xeb0000000057LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "exclusive or immediate with long offset" }, + { "oiy", OP48(0xeb0000000056LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "or immediate with long offset" }, + { "cliy", OP48(0xeb0000000055LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "compare logical immediate with long offset" }, + { "niy", OP48(0xeb0000000054LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "and immediate with long offset" }, + { "mviy", OP48(0xeb0000000052LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "move immediate with long offset" }, + { "tmy", OP48(0xeb0000000051LL), MASK_SIY_URD, INSTR_SIY_URD, 2, 3, 0, "test under mask with long offset" }, + { "ecag", OP48(0xeb000000004cLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 6, 0, "extract cache attribute" }, + { "bxleg", OP48(0xeb0000000045LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "branch on index low or equal 64" }, + { "bxleg", OP48(0xeb0000000045LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "branch on index low or equal 64" }, + { "bxhg", OP48(0xeb0000000044LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "branch on index high 64" }, + { "bxhg", OP48(0xeb0000000044LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "branch on index high 64" }, + { "cdsg", OP48(0xeb000000003eLL), MASK_RSY_RERERD, INSTR_RSY_RERERD, 2, 3, 0, "compare double and swap with long offset 64" }, + { "cdsg", OP48(0xeb000000003eLL), MASK_RSE_RERERD, INSTR_RSE_RERERD, 2, 2, 0, "compare double and swap 64" }, + { "cdsy", OP48(0xeb0000000031LL), MASK_RSY_RERERD, INSTR_RSY_RERERD, 2, 3, 0, "compare double and swap with long offset" }, + { "csg", OP48(0xeb0000000030LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "compare and swap with long offset 64" }, + { "csg", OP48(0xeb0000000030LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "compare and swap 64" }, + { "lctlg", OP48(0xeb000000002fLL), MASK_RSY_CCRD, INSTR_RSY_CCRD, 2, 3, 0, "load control 64" }, + { "lctlg", OP48(0xeb000000002fLL), MASK_RSE_CCRD, INSTR_RSE_CCRD, 2, 2, 0, "load control 64" }, + { "stcmy", OP48(0xeb000000002dLL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "store characters under mask with long offset" }, + { "stcmh", OP48(0xeb000000002cLL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "store characters under mask high with long offset" }, + { "stcmh", OP48(0xeb000000002cLL), MASK_RSE_RURD, INSTR_RSE_RURD, 2, 2, 0, "store characters under mask high" }, + { "clgt", OP48(0xeb000000002bLL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 8, 0, "compare logical and trap 64 bit reg-mem" }, + { "stmh", OP48(0xeb0000000026LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "store multiple high" }, + { "stmh", OP48(0xeb0000000026LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "store multiple high" }, + { "stctg", OP48(0xeb0000000025LL), MASK_RSY_CCRD, INSTR_RSY_CCRD, 2, 3, 0, "store control 64" }, + { "stctg", OP48(0xeb0000000025LL), MASK_RSE_CCRD, INSTR_RSE_CCRD, 2, 2, 0, "store control 64" }, + { "stmg", OP48(0xeb0000000024LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "store multiple with long offset 64" }, + { "stmg", OP48(0xeb0000000024LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "store multiple 64" }, + { "clt", OP48(0xeb0000000023LL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 8, 0, "compare logical and trap 32 bit reg-mem" }, + { "clmy", OP48(0xeb0000000021LL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "compare logical characters under mask with long offset" }, + { "clmh", OP48(0xeb0000000020LL), MASK_RSY_RURD, INSTR_RSY_RURD, 2, 3, 0, "compare logical characters under mask high with long offset" }, + { "clmh", OP48(0xeb0000000020LL), MASK_RSE_RURD, INSTR_RSE_RURD, 2, 2, 0, "compare logical characters under mask high" }, + { "rll", OP48(0xeb000000001dLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 0, "rotate left single logical 32" }, + { "rll", OP48(0xeb000000001dLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 2, 0, "rotate left single logical 32" }, + { "rllg", OP48(0xeb000000001cLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "rotate left single logical 64" }, + { "rllg", OP48(0xeb000000001cLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "rotate left single logical 64" }, + { "pfcr", OP48(0xeb0000000016LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 13, 0, "perform functions with concurrent results" }, + { "csy", OP48(0xeb0000000014LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "compare and swap with long offset" }, + { "tracg", OP48(0xeb000000000fLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "trace 64" }, + { "tracg", OP48(0xeb000000000fLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "trace 64" }, + { "sllg", OP48(0xeb000000000dLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "shift left single logical 64" }, + { "sllg", OP48(0xeb000000000dLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "shift left single logical 64" }, + { "srlg", OP48(0xeb000000000cLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "shift right single logical 64" }, + { "srlg", OP48(0xeb000000000cLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "shift right single logical 64" }, + { "slag", OP48(0xeb000000000bLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "shift left single 64" }, + { "slag", OP48(0xeb000000000bLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "shift left single 64" }, + { "srag", OP48(0xeb000000000aLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "shift right single 64" }, + { "srag", OP48(0xeb000000000aLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "shift right single 64" }, + { "lmg", OP48(0xeb0000000004LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3, 0, "load multiple with long offset 64" }, + { "lmg", OP48(0xeb0000000004LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2, 0, "load multiple 64" }, + { "unpka", OP8(0xeaLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "unpack ascii" }, + { "pka", OP8(0xe9LL), MASK_SS_L2RDRD, INSTR_SS_L2RDRD, 3, 0, 0, "pack ascii" }, + { "mvcin", OP8(0xe8LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "move inverse" }, + { "vone", OP48(0xe700ffff0044LL), MASK_VRI_V, INSTR_VRI_V, 2, 9, 8, "vector set to ones" }, + { "wfnmaxb", OP48(0xe7000408009fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and add scalar extended" }, + { "wfnmsxb", OP48(0xe7000408009eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and subtract scalar extended" }, + { "wfmaxb", OP48(0xe7000408008fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp multiply and add scalar extended" }, + { "wfmsxb", OP48(0xe7000408008eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp multiply and subtract scalar extended" }, + { "vsbiq", OP48(0xe700040000bfLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector subtract with borrow indication quadword" }, + { "vsbcbiq", OP48(0xe700040000bdLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector subtract with borrow compute borrow indication quadword" }, + { "vacq", OP48(0xe700040000bbLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector add with carry quadword" }, + { "vacccq", OP48(0xe700040000b9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector add with carry compute carry quadword" }, + { "vmahq", OP48(0xe700040000abLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add high quadword" }, + { "vmalq", OP48(0xe700040000aaLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add low quadword" }, + { "vmalhq", OP48(0xe700040000a9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add logical high quadword" }, + { "vblendq", OP48(0xe70004000089LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector blend quadword" }, + { "wfnmadb", OP48(0xe7000308009fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and add scalar long" }, + { "wfnmsdb", OP48(0xe7000308009eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and subtract scalar long" }, + { "wfmadb", OP48(0xe7000308008fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 9, 8, "vector fp multiply and add long" }, + { "wfmsdb", OP48(0xe7000308008eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 9, 8, "vector fp multiply and subtract long" }, + { "vgfmag", OP48(0xe700030000bcLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector galois field multiply sum and accumulate doubleword" }, + { "vmslg", OP48(0xe700030000b8LL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 10, 0, "vector multiply sum logical double word" }, + { "vmaog", OP48(0xe700030000afLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add odd doubleword" }, + { "vmaeg", OP48(0xe700030000aeLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add even doubleword" }, + { "vmalog", OP48(0xe700030000adLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add logical odd doubleword" }, + { "vmaleg", OP48(0xe700030000acLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add logical even doubleword" }, + { "vmahg", OP48(0xe700030000abLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add high doubleword" }, + { "vmalg", OP48(0xe700030000aaLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add low doubleword" }, + { "vmalhg", OP48(0xe700030000a9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector multiply and add logical high doubleword" }, + { "vfnmadb", OP48(0xe7000300009fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp negative multiply and add long" }, + { "vfnmsdb", OP48(0xe7000300009eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp negative multiply and subtract long" }, + { "vfmadb", OP48(0xe7000300008fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 9, 8, "vector fp multiply and add long" }, + { "vfmsdb", OP48(0xe7000300008eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 9, 8, "vector fp multiply and subtract long" }, + { "vblendg", OP48(0xe70003000089LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector blend doubleword" }, + { "vstrczfs", OP48(0xe7000230008aLL), MASK_VRR_VVVU0VB3, INSTR_VRR_VVVU0VB3, 2, 9, 9, "vector string range compare word" }, + { "vstrszf", OP48(0xe7000220008bLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 11, 0, "vector string search word zero" }, + { "vstrczf", OP48(0xe7000220008aLL), MASK_VRR_VVVU0VB2, INSTR_VRR_VVVU0VB2, 2, 9, 9, "vector string range compare word" }, + { "vstrcfs", OP48(0xe7000210008aLL), MASK_VRR_VVVU0VB1, INSTR_VRR_VVVU0VB1, 2, 9, 9, "vector string range compare word" }, + { "wfnmasb", OP48(0xe7000208009fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and add scalar short" }, + { "wfnmssb", OP48(0xe7000208009eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp negative multiply and subtract scalar short" }, + { "wfmasb", OP48(0xe7000208008fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp multiply and add scalar short" }, + { "wfmssb", OP48(0xe7000208008eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "scalar vector fp multiply and subtract scalar short" }, + { "vgfmaf", OP48(0xe700020000bcLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector galois field multiply sum and accumulate word" }, + { "vmaof", OP48(0xe700020000afLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add odd word" }, + { "vmaef", OP48(0xe700020000aeLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add even word" }, + { "vmalof", OP48(0xe700020000adLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical odd word" }, + { "vmalef", OP48(0xe700020000acLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical even word" }, + { "vmahf", OP48(0xe700020000abLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add high word" }, + { "vmalf", OP48(0xe700020000aaLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add low word" }, + { "vmalhf", OP48(0xe700020000a9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical high word" }, + { "vfnmasb", OP48(0xe7000200009fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp negative multiply and add short" }, + { "vfnmssb", OP48(0xe7000200009eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp negative multiply and subtract short" }, + { "vfmasb", OP48(0xe7000200008fLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp multiply and add short" }, + { "vfmssb", OP48(0xe7000200008eLL), MASK_VRR_VVVV, INSTR_VRR_VVVV, 2, 10, 0, "vector fp multiply and subtract short" }, + { "vstrsf", OP48(0xe7000200008bLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 11, 1, "vector string search word" }, + { "vstrcf", OP48(0xe7000200008aLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 9, 9, "vector string range compare word" }, + { "vblendf", OP48(0xe70002000089LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector blend word" }, + { "vstrczhs", OP48(0xe7000130008aLL), MASK_VRR_VVVU0VB3, INSTR_VRR_VVVU0VB3, 2, 9, 9, "vector string range compare halfword" }, + { "vstrszh", OP48(0xe7000120008bLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 11, 0, "vector string search halfword zero" }, + { "vstrczh", OP48(0xe7000120008aLL), MASK_VRR_VVVU0VB2, INSTR_VRR_VVVU0VB2, 2, 9, 9, "vector string range compare halfword" }, + { "vstrchs", OP48(0xe7000110008aLL), MASK_VRR_VVVU0VB1, INSTR_VRR_VVVU0VB1, 2, 9, 9, "vector string range compare halfword" }, + { "vgfmah", OP48(0xe700010000bcLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector galois field multiply sum and accumulate halfword" }, + { "vmaoh", OP48(0xe700010000afLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add odd halfword" }, + { "vmaeh", OP48(0xe700010000aeLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add even halfword" }, + { "vmaloh", OP48(0xe700010000adLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical odd halfword" }, + { "vmaleh", OP48(0xe700010000acLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical even halfword" }, + { "vmahh", OP48(0xe700010000abLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add high halfword" }, + { "vmalhw", OP48(0xe700010000aaLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add low halfword" }, + { "vmalhh", OP48(0xe700010000a9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical high halfword" }, + { "vstrsh", OP48(0xe7000100008bLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 11, 1, "vector string search halfword" }, + { "vstrch", OP48(0xe7000100008aLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 9, 9, "vector string range compare halfword" }, + { "vblendh", OP48(0xe70001000089LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector blend halfword" }, + { "vfaezfs", OP48(0xe70000302082LL), MASK_VRR_VVV0U3, INSTR_VRR_VVV0U3, 2, 9, 9, "vector find any element equal" }, + { "vfenezfs", OP48(0xe70000302081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal word" }, + { "vfeezfs", OP48(0xe70000302080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal word" }, + { "vfaezhs", OP48(0xe70000301082LL), MASK_VRR_VVV0U3, INSTR_VRR_VVV0U3, 2, 9, 9, "vector find any element equal" }, + { "vfenezhs", OP48(0xe70000301081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal halfword" }, + { "vfeezhs", OP48(0xe70000301080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal halfword" }, + { "vstrczbs", OP48(0xe7000030008aLL), MASK_VRR_VVVU0VB3, INSTR_VRR_VVVU0VB3, 2, 9, 9, "vector string range compare byte" }, + { "vfaezbs", OP48(0xe70000300082LL), MASK_VRR_VVV0U3, INSTR_VRR_VVV0U3, 2, 9, 9, "vector find any element equal" }, + { "vfenezbs", OP48(0xe70000300081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal byte" }, + { "vfeezbs", OP48(0xe70000300080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal byte" }, + { "wflpxb", OP48(0xe700002840ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar extended" }, + { "wflpdb", OP48(0xe700002830ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "wflpsb", OP48(0xe700002820ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar short" }, + { "vflpdb", OP48(0xe700002030ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "vflpsb", OP48(0xe700002020ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector fp perform sign operation short" }, + { "vfaezf", OP48(0xe70000202082LL), MASK_VRR_VVV0U2, INSTR_VRR_VVV0U2, 2, 9, 9, "vector find any element equal" }, + { "vfenezf", OP48(0xe70000202081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal word" }, + { "vfeezf", OP48(0xe70000202080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal word" }, + { "vfaezh", OP48(0xe70000201082LL), MASK_VRR_VVV0U2, INSTR_VRR_VVV0U2, 2, 9, 9, "vector find any element equal" }, + { "vfenezh", OP48(0xe70000201081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal halfword" }, + { "vfeezh", OP48(0xe70000201080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal halfword" }, + { "vstrszb", OP48(0xe7000020008bLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 11, 0, "vector string search byte zero" }, + { "vstrczb", OP48(0xe7000020008aLL), MASK_VRR_VVVU0VB2, INSTR_VRR_VVVU0VB2, 2, 9, 9, "vector string range compare byte" }, + { "vfaezb", OP48(0xe70000200082LL), MASK_VRR_VVV0U2, INSTR_VRR_VVV0U2, 2, 9, 9, "vector find any element equal" }, + { "vfenezb", OP48(0xe70000200081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal byte" }, + { "vfeezb", OP48(0xe70000200080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal byte" }, + { "wfkhxbs", OP48(0xe700001c40ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high scalar extended" }, + { "wfkhexbs", OP48(0xe700001c40eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high or equal scalar extended" }, + { "wfkexbs", OP48(0xe700001c40e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal equal scalar extended" }, + { "wfkhdbs", OP48(0xe700001c30ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high long" }, + { "wfkhedbs", OP48(0xe700001c30eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high or equal long" }, + { "wfkedbs", OP48(0xe700001c30e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal equal long" }, + { "wfkhsbs", OP48(0xe700001c20ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high scalar short" }, + { "wfkhesbs", OP48(0xe700001c20eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high or equal scalar short" }, + { "wfkesbs", OP48(0xe700001c20e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar fp compare and signal equal scalar short" }, + { "wfchxbs", OP48(0xe700001840ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high scalar extended" }, + { "wfchexbs", OP48(0xe700001840eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high or equal scalar extended" }, + { "wfcexbs", OP48(0xe700001840e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare equal scalar extended" }, + { "wflnxb", OP48(0xe700001840ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar extended" }, + { "wfchdbs", OP48(0xe700001830ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high long" }, + { "wfchedbs", OP48(0xe700001830eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high or equal long" }, + { "wfcedbs", OP48(0xe700001830e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare equal long" }, + { "wflndb", OP48(0xe700001830ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "wfchsbs", OP48(0xe700001820ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high scalar short" }, + { "wfchesbs", OP48(0xe700001820eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high or equal scalar short" }, + { "wfcesbs", OP48(0xe700001820e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar fp compare equal scalar short" }, + { "wflnsb", OP48(0xe700001820ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar short" }, + { "vfkhdbs", OP48(0xe700001430ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high long" }, + { "vfkhedbs", OP48(0xe700001430eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high or equal long" }, + { "vfkedbs", OP48(0xe700001430e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal equal long" }, + { "vfkhsbs", OP48(0xe700001420ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal high short" }, + { "vfkhesbs", OP48(0xe700001420eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal high or equal short" }, + { "vfkesbs", OP48(0xe700001420e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal equal short" }, + { "vchqs", OP48(0xe700001040fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare high quadword" }, + { "vchlqs", OP48(0xe700001040f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare high logical quadword" }, + { "vceqqs", OP48(0xe700001040f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare equal quadword" }, + { "vchgs", OP48(0xe700001030fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high double word" }, + { "vchlgs", OP48(0xe700001030f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical double word" }, + { "vceqgs", OP48(0xe700001030f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal double word" }, + { "vfchdbs", OP48(0xe700001030ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high long" }, + { "vfchedbs", OP48(0xe700001030eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high or equal long" }, + { "vfcedbs", OP48(0xe700001030e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare equal long" }, + { "vflndb", OP48(0xe700001030ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "vpksgs", OP48(0xe70000103097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate double word" }, + { "vpklsgs", OP48(0xe70000103095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate double word" }, + { "vchfs", OP48(0xe700001020fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high word" }, + { "vchlfs", OP48(0xe700001020f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical word" }, + { "vceqfs", OP48(0xe700001020f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal word" }, + { "vfchsbs", OP48(0xe700001020ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare high short" }, + { "vfchesbs", OP48(0xe700001020eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare high or equal short" }, + { "vfcesbs", OP48(0xe700001020e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare equal short" }, + { "vflnsb", OP48(0xe700001020ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector fp perform sign operation short" }, + { "vpksfs", OP48(0xe70000102097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate word" }, + { "vpklsfs", OP48(0xe70000102095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate word" }, + { "vfaefs", OP48(0xe70000102082LL), MASK_VRR_VVV0U1, INSTR_VRR_VVV0U1, 2, 9, 9, "vector find any element equal" }, + { "vfenefs", OP48(0xe70000102081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal word" }, + { "vfeefs", OP48(0xe70000102080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal word" }, + { "vistrfs", OP48(0xe7000010205cLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector isolate string word" }, + { "vchhs", OP48(0xe700001010fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high half word" }, + { "vchlhs", OP48(0xe700001010f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical half word" }, + { "vceqhs", OP48(0xe700001010f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal half word" }, + { "vpkshs", OP48(0xe70000101097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate halfword" }, + { "vpklshs", OP48(0xe70000101095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate halfword" }, + { "vfaehs", OP48(0xe70000101082LL), MASK_VRR_VVV0U1, INSTR_VRR_VVV0U1, 2, 9, 9, "vector find any element equal" }, + { "vfenehs", OP48(0xe70000101081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal halfword" }, + { "vfeehs", OP48(0xe70000101080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal halfword" }, + { "vistrhs", OP48(0xe7000010105cLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector isolate string halfword" }, + { "vchbs", OP48(0xe700001000fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high byte" }, + { "vchlbs", OP48(0xe700001000f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical byte" }, + { "vceqbs", OP48(0xe700001000f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal byte" }, + { "vstrcbs", OP48(0xe7000010008aLL), MASK_VRR_VVVU0VB1, INSTR_VRR_VVVU0VB1, 2, 9, 9, "vector string range compare byte" }, + { "vfaebs", OP48(0xe70000100082LL), MASK_VRR_VVV0U1, INSTR_VRR_VVV0U1, 2, 9, 9, "vector find any element equal" }, + { "vfenebs", OP48(0xe70000100081LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element not equal byte" }, + { "vfeebs", OP48(0xe70000100080LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector find element equal byte" }, + { "vistrbs", OP48(0xe7000010005cLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector isolate string byte" }, + { "wfkhxb", OP48(0xe700000c40ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high scalar extended" }, + { "wfkhexb", OP48(0xe700000c40eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high or equal scalar extended" }, + { "wfkexb", OP48(0xe700000c40e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal equal scalar extended" }, + { "wfkhdb", OP48(0xe700000c30ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high long" }, + { "wfkhedb", OP48(0xe700000c30eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high or equal long" }, + { "wfkedb", OP48(0xe700000c30e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal equal long" }, + { "wfkhsb", OP48(0xe700000c20ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high scalar short" }, + { "wfkhesb", OP48(0xe700000c20eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal high or equal scalar short" }, + { "wfkesb", OP48(0xe700000c20e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare and signal equal scalar short" }, + { "wfmaxxb", OP48(0xe700000840efLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp maximum scalar extended" }, + { "wfminxb", OP48(0xe700000840eeLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp minimum scalar extended" }, + { "wfchxb", OP48(0xe700000840ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high scalar extended" }, + { "wfchexb", OP48(0xe700000840eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high or equal scalar extended" }, + { "wfcexb", OP48(0xe700000840e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare equal scalar extended" }, + { "wfmxb", OP48(0xe700000840e7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp multiply scalar extended" }, + { "wfdxb", OP48(0xe700000840e5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp divide scalar extended" }, + { "wfaxb", OP48(0xe700000840e3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp add scalar extended" }, + { "wfsxb", OP48(0xe700000840e2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp subtract scalar extended" }, + { "wfsqxb", OP48(0xe700000840ceLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp square root scalar extended" }, + { "wfpsoxb", OP48(0xe700000840ccLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 10, 0, "scalar vector fp perform sign operation scalar extended" }, + { "wflcxb", OP48(0xe700000840ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar extended" }, + { "wfixb", OP48(0xe700000840c7LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 10, 0, "scalar vector load fp integer scalar extended" }, + { "wflrx", OP48(0xe700000840c5LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 10, 0, "scalar vector fp load rounded extended" }, + { "wftcixb", OP48(0xe7000008404aLL), MASK_VRI_VVU2, INSTR_VRI_VVU2, 2, 10, 0, "scalar vector fp test data class immediate scalar extended" }, + { "wfmaxdb", OP48(0xe700000830efLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp maximum scalar long" }, + { "wfmindb", OP48(0xe700000830eeLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp minimum scalar long" }, + { "wfchdb", OP48(0xe700000830ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high long" }, + { "wfchedb", OP48(0xe700000830eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high or equal long" }, + { "wfcedb", OP48(0xe700000830e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare equal long" }, + { "wfmdb", OP48(0xe700000830e7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp multiply long" }, + { "wfddb", OP48(0xe700000830e5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp divide long" }, + { "wfadb", OP48(0xe700000830e3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp add long" }, + { "wfsdb", OP48(0xe700000830e2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp subtract long" }, + { "wfsqdb", OP48(0xe700000830ceLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp square root long" }, + { "wfpsodb", OP48(0xe700000830ccLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 9, 8, "vector fp perform sign operation long" }, + { "wflcdb", OP48(0xe700000830ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "wfidb", OP48(0xe700000830c7LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector load fp integer long" }, + { "wflrd", OP48(0xe700000830c5LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 10, 0, "scalar vector fp load rounded long" }, + { "wledb", OP48(0xe700000830c5LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector fp load rounded long to short" }, + { "wflld", OP48(0xe700000830c4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp load lengthened long" }, + { "wcdgb", OP48(0xe700000830c3LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector fp convert from fixed 64 bit" }, + { "wcgdb", OP48(0xe700000830c2LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector fp convert to fixed 64 bit" }, + { "wcdlgb", OP48(0xe700000830c1LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector fp convert from logical 64 bit" }, + { "wclgdb", OP48(0xe700000830c0LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 9, 8, "vector fp convert to logical 64 bit" }, + { "wftcidb", OP48(0xe7000008304aLL), MASK_VRI_VVU2, INSTR_VRI_VVU2, 2, 9, 8, "vector fp test data class immediate" }, + { "wfmaxsb", OP48(0xe700000820efLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp maximum scalar short" }, + { "wfminsb", OP48(0xe700000820eeLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "scalar fp minimum scalar short" }, + { "wfchsb", OP48(0xe700000820ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high scalar short" }, + { "wfchesb", OP48(0xe700000820eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare high or equal scalar short" }, + { "wfcesb", OP48(0xe700000820e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp compare equal scalar short" }, + { "wfmsb", OP48(0xe700000820e7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp multiply scalar short" }, + { "wfdsb", OP48(0xe700000820e5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp divide scalar short" }, + { "wfasb", OP48(0xe700000820e3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp add scalar short" }, + { "wfssb", OP48(0xe700000820e2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "scalar vector fp subtract scalar short" }, + { "wfsqsb", OP48(0xe700000820ceLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp square root scalar short" }, + { "wfpsosb", OP48(0xe700000820ccLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 10, 0, "scalar vector fp perform sign operation scalar short" }, + { "wflcsb", OP48(0xe700000820ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp perform sign operation scalar short" }, + { "wfisb", OP48(0xe700000820c7LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 10, 0, "scalar vector load fp integer scalar short" }, + { "wflls", OP48(0xe700000820c4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp load lengthened short" }, + { "wldeb", OP48(0xe700000820c4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp load lengthened short to long" }, + { "wcefb", OP48(0xe700000820c3LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 11, 0, "vector fp convert from fixed 32 bit" }, + { "wcfeb", OP48(0xe700000820c2LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 11, 0, "vector fp convert to fixed 32 bit" }, + { "wcelfb", OP48(0xe700000820c1LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 11, 0, "vector fp convert from logical 32 bit" }, + { "wclfeb", OP48(0xe700000820c0LL), MASK_VRR_VV0UU8, INSTR_VRR_VV0UU8, 2, 11, 0, "vector fp convert to logical 32 bit" }, + { "wftcisb", OP48(0xe7000008204aLL), MASK_VRI_VVU2, INSTR_VRI_VVU2, 2, 10, 0, "scalar vector fp test data class immediate scalar short" }, + { "vfkhdb", OP48(0xe700000430ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high long" }, + { "vfkhedb", OP48(0xe700000430eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal high or equal long" }, + { "vfkedb", OP48(0xe700000430e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 8, "vector fp compare and signal equal long" }, + { "vfkhsb", OP48(0xe700000420ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal high short" }, + { "vfkhesb", OP48(0xe700000420eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal high or equal short" }, + { "vfkesb", OP48(0xe700000420e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare and signal equal short" }, + { "vllezlf", OP48(0xe70000006004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 10, 0, "vector load logical word element and zero - left aligned" }, + { "vmxq", OP48(0xe700000040ffLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector maximum quadword" }, + { "vmnq", OP48(0xe700000040feLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector minimum quadword" }, + { "vmxlq", OP48(0xe700000040fdLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector maximum logical quadword" }, + { "vmnlq", OP48(0xe700000040fcLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector minimum logical quadword" }, + { "vchq", OP48(0xe700000040fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare high quadword" }, + { "vchlq", OP48(0xe700000040f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare high logical quadword" }, + { "vceqq", OP48(0xe700000040f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector compare equal quadword" }, + { "vsq", OP48(0xe700000040f7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract quadword" }, + { "vscbiq", OP48(0xe700000040f5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract compute borrow indication quadword" }, + { "vaq", OP48(0xe700000040f3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add quad word" }, + { "vavgq", OP48(0xe700000040f2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector average quadword" }, + { "vaccq", OP48(0xe700000040f1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add compute carry quadword" }, + { "vavglq", OP48(0xe700000040f0LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector average logical quadword" }, + { "vlpq", OP48(0xe700000040dfLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector load positive quadword" }, + { "vlcq", OP48(0xe700000040deLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector load complement quadword" }, + { "vecq", OP48(0xe700000040dbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector element compare quadword" }, + { "veclq", OP48(0xe700000040d9LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector element compare logical quadword" }, + { "wfcxb", OP48(0xe700000040cbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp compare scalar extended" }, + { "wfkxb", OP48(0xe700000040caLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp compare and signal scalar extended" }, + { "vrq", OP48(0xe700000040b3LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder quadword" }, + { "vdq", OP48(0xe700000040b2LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide quadword" }, + { "vrlq", OP48(0xe700000040b1LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder logical quadword" }, + { "vdlq", OP48(0xe700000040b0LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide logical quadword" }, + { "vmhq", OP48(0xe700000040a3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply high quadword" }, + { "vmlq", OP48(0xe700000040a2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply low quadword" }, + { "vmlhq", OP48(0xe700000040a1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply logical high quadword" }, + { "vgemq", OP48(0xe70000004054LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector generate element masks quadword" }, + { "vclzq", OP48(0xe70000004053LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector count leading zeros quadword" }, + { "vctzq", OP48(0xe70000004052LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector count trailing zeros quadword" }, + { "vmxg", OP48(0xe700000030ffLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum doubleword" }, + { "vmng", OP48(0xe700000030feLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum doubleword" }, + { "vmxlg", OP48(0xe700000030fdLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum logical doubleword" }, + { "vmnlg", OP48(0xe700000030fcLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum logical doubleword" }, + { "vchg", OP48(0xe700000030fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high double word" }, + { "vchlg", OP48(0xe700000030f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical double word" }, + { "vceqg", OP48(0xe700000030f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal double word" }, + { "vsg", OP48(0xe700000030f7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract doubleword" }, + { "vscbig", OP48(0xe700000030f5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract compute borrow indication doubleword" }, + { "vag", OP48(0xe700000030f3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add double word" }, + { "vavgg", OP48(0xe700000030f2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average double word" }, + { "vaccg", OP48(0xe700000030f1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add compute carry doubleword" }, + { "vavglg", OP48(0xe700000030f0LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average logical double word" }, + { "vfmaxdb", OP48(0xe700000030efLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "vector fp maximum long" }, + { "vfmindb", OP48(0xe700000030eeLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "vector fp minimum long" }, + { "vfchdb", OP48(0xe700000030ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high long" }, + { "vfchedb", OP48(0xe700000030eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare high or equal long" }, + { "vfcedb", OP48(0xe700000030e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp compare equal long" }, + { "vfmdb", OP48(0xe700000030e7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp multiply long" }, + { "vfddb", OP48(0xe700000030e5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp divide long" }, + { "vfadb", OP48(0xe700000030e3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp add long" }, + { "vfsdb", OP48(0xe700000030e2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector fp subtract long" }, + { "vlpg", OP48(0xe700000030dfLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load positive doubleword" }, + { "vlcg", OP48(0xe700000030deLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load complement doubleword" }, + { "vecg", OP48(0xe700000030dbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare double word" }, + { "veclg", OP48(0xe700000030d9LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare logical double word" }, + { "vuphg", OP48(0xe700000030d7LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector unpack high doubleword" }, + { "vuplg", OP48(0xe700000030d6LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector unpack low doubleword" }, + { "vuplhg", OP48(0xe700000030d5LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector unpack logical high doubleword" }, + { "vupllg", OP48(0xe700000030d4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector unpack logical low doubleword" }, + { "vfsqdb", OP48(0xe700000030ceLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp square root long" }, + { "vfpsodb", OP48(0xe700000030ccLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 9, 8, "vector fp perform sign operation long" }, + { "vflcdb", OP48(0xe700000030ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp perform sign operation long" }, + { "wfcdb", OP48(0xe700000030cbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp compare scalar long" }, + { "wfkdb", OP48(0xe700000030caLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp compare and signal scalar long" }, + { "vfidb", OP48(0xe700000030c7LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector load fp integer long" }, + { "vflrd", OP48(0xe700000030c5LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 10, 0, "vector fp load rounded long" }, + { "vledb", OP48(0xe700000030c5LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector fp load rounded long to short" }, + { "vcdgb", OP48(0xe700000030c3LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector fp convert from fixed 64 bit" }, + { "vcgdb", OP48(0xe700000030c2LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector fp convert to fixed 64 bit" }, + { "vcdlgb", OP48(0xe700000030c1LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector fp convert from logical 64 bit" }, + { "vclgdb", OP48(0xe700000030c0LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 9, 8, "vector fp convert to logical 64 bit" }, + { "vgfmg", OP48(0xe700000030b4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector galois field multiply sum doubleword" }, + { "vrg", OP48(0xe700000030b3LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder doubleword" }, + { "vdg", OP48(0xe700000030b2LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide doubleword" }, + { "vrlg", OP48(0xe700000030b1LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder logical doubleword" }, + { "vdlg", OP48(0xe700000030b0LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide logical doubleword" }, + { "vmog", OP48(0xe700000030a7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply odd doubleword" }, + { "vmeg", OP48(0xe700000030a6LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply even doubleword" }, + { "vmlog", OP48(0xe700000030a5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply logical odd doubleword" }, + { "vmleg", OP48(0xe700000030a4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply logical even doubleword" }, + { "vmhg", OP48(0xe700000030a3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply high doubleword" }, + { "vmlg", OP48(0xe700000030a2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply low doubleword" }, + { "vmlhg", OP48(0xe700000030a1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 13, 0, "vector multiply logical high doubleword" }, + { "vpksg", OP48(0xe70000003097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate double word" }, + { "vpklsg", OP48(0xe70000003095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate double word" }, + { "vpkg", OP48(0xe70000003094LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack double word" }, + { "vesravg", OP48(0xe7000000307aLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right arithmetic reg doubleword" }, + { "vesrlvg", OP48(0xe70000003078LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right logical reg doubleword" }, + { "verllvg", OP48(0xe70000003073LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element rotate left logical reg doubleword" }, + { "verimg", OP48(0xe70000003072LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 9, 8, "vector element rotate and insert under mask doubleword" }, + { "veslvg", OP48(0xe70000003070LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift left reg doubleword" }, + { "vsumqg", OP48(0xe70000003067LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across quadword - doubleword elements" }, + { "vmrhg", OP48(0xe70000003061LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge high double word" }, + { "vmrlg", OP48(0xe70000003060LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge low double word" }, + { "vgemg", OP48(0xe70000003054LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector generate element masks doubleword" }, + { "vclzg", OP48(0xe70000003053LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count leading zeros doubleword" }, + { "vctzg", OP48(0xe70000003052LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count trailing zeros doubleword" }, + { "vpopctg", OP48(0xe70000003050LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector population count double word" }, + { "vrepg", OP48(0xe7000000304dLL), MASK_VRI_VVU, INSTR_VRI_VVU, 2, 9, 8, "vector replicate double word" }, + { "vftcidb", OP48(0xe7000000304aLL), MASK_VRI_VVU2, INSTR_VRI_VVU2, 2, 9, 8, "vector fp test data class immediate" }, + { "vgmg", OP48(0xe70000003046LL), MASK_VRI_V0UU, INSTR_VRI_V0UU, 2, 9, 8, "vector generate mask double word" }, + { "vrepig", OP48(0xe70000003045LL), MASK_VRI_V0I, INSTR_VRI_V0I, 2, 9, 8, "vector replicate immediate double word" }, + { "vesrag", OP48(0xe7000000303aLL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right arithmetic mem doubleword" }, + { "vesrlg", OP48(0xe70000003038LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right logical mem doubleword" }, + { "verllg", OP48(0xe70000003033LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element rotate left logical mem doubleword" }, + { "veslg", OP48(0xe70000003030LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift left mem doubleword" }, + { "vlvgg", OP48(0xe70000003022LL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector load VR double word element from GR" }, + { "vlgvg", OP48(0xe70000003021LL), MASK_VRS_RVRD, INSTR_VRS_RVRD, 2, 9, 8, "vector load GR from VR double word element" }, + { "vlrepg", OP48(0xe70000003005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load and replicate double word elements" }, + { "vllezg", OP48(0xe70000003004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load logical double word element and zero" }, + { "vmxf", OP48(0xe700000020ffLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum word" }, + { "vmnf", OP48(0xe700000020feLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum word" }, + { "vmxlf", OP48(0xe700000020fdLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum logical word" }, + { "vmnlf", OP48(0xe700000020fcLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum logical word" }, + { "vchf", OP48(0xe700000020fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high word" }, + { "vchlf", OP48(0xe700000020f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical word" }, + { "vceqf", OP48(0xe700000020f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal word" }, + { "vsf", OP48(0xe700000020f7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract word" }, + { "vscbif", OP48(0xe700000020f5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract compute borrow indication word" }, + { "vaf", OP48(0xe700000020f3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add word" }, + { "vavgf", OP48(0xe700000020f2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average word" }, + { "vaccf", OP48(0xe700000020f1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add compute carry word" }, + { "vavglf", OP48(0xe700000020f0LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average logical word" }, + { "vfmaxsb", OP48(0xe700000020efLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "vector fp maximum short" }, + { "vfminsb", OP48(0xe700000020eeLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 10, 0, "vector fp minimum short" }, + { "vfchsb", OP48(0xe700000020ebLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare high short" }, + { "vfchesb", OP48(0xe700000020eaLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare high or equal short" }, + { "vfcesb", OP48(0xe700000020e8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp compare equal short" }, + { "vfmsb", OP48(0xe700000020e7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp multiply short" }, + { "vfdsb", OP48(0xe700000020e5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp divide short" }, + { "vfasb", OP48(0xe700000020e3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp add short" }, + { "vfssb", OP48(0xe700000020e2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector fp subtract short" }, + { "vlpf", OP48(0xe700000020dfLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load positive word" }, + { "vlcf", OP48(0xe700000020deLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load complement word" }, + { "vecf", OP48(0xe700000020dbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare word" }, + { "veclf", OP48(0xe700000020d9LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare logical word" }, + { "vuphf", OP48(0xe700000020d7LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack high word" }, + { "vuplf", OP48(0xe700000020d6LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack low word" }, + { "vuplhf", OP48(0xe700000020d5LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical high word" }, + { "vupllf", OP48(0xe700000020d4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical low word" }, + { "vfsqsb", OP48(0xe700000020ceLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector fp square root short" }, + { "vfpsosb", OP48(0xe700000020ccLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 10, 0, "vector fp perform sign operation short" }, + { "vflcsb", OP48(0xe700000020ccLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector fp perform sign operation short" }, + { "wfcsb", OP48(0xe700000020cbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp compare scalar short" }, + { "wfksb", OP48(0xe700000020caLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "scalar vector fp compare and signal scalar short" }, + { "vfisb", OP48(0xe700000020c7LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 10, 0, "vector load fp integer short" }, + { "vflls", OP48(0xe700000020c4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector fp load lengthened" }, + { "vldeb", OP48(0xe700000020c4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector fp load lengthened short to long" }, + { "vcefb", OP48(0xe700000020c3LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 11, 0, "vector fp convert from fixed 32 bit" }, + { "vcfeb", OP48(0xe700000020c2LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 11, 0, "vector fp convert to fixed 32 bit" }, + { "vcelfb", OP48(0xe700000020c1LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 11, 0, "vector fp convert from logical 32 bit" }, + { "vclfeb", OP48(0xe700000020c0LL), MASK_VRR_VV0UU, INSTR_VRR_VV0UU, 2, 11, 0, "vector fp convert to logical 32 bit" }, + { "vgfmf", OP48(0xe700000020b4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector galois field multiply sum word" }, + { "vrf", OP48(0xe700000020b3LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder word" }, + { "vdf", OP48(0xe700000020b2LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide word" }, + { "vrlf", OP48(0xe700000020b1LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector remainder logical word" }, + { "vdlf", OP48(0xe700000020b0LL), MASK_VRR_VVV0U02, INSTR_VRR_VVV0U02, 2, 13, 0, "vector divide logical word" }, + { "vmof", OP48(0xe700000020a7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply odd word" }, + { "vmef", OP48(0xe700000020a6LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply even word" }, + { "vmlof", OP48(0xe700000020a5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical odd word" }, + { "vmlef", OP48(0xe700000020a4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical even word" }, + { "vmhf", OP48(0xe700000020a3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply high word" }, + { "vmlf", OP48(0xe700000020a2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply low word" }, + { "vmlhf", OP48(0xe700000020a1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical high word" }, + { "vpksf", OP48(0xe70000002097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate word" }, + { "vpklsf", OP48(0xe70000002095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate word" }, + { "vpkf", OP48(0xe70000002094LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack word" }, + { "vfaef", OP48(0xe70000002082LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find any element equal word" }, + { "vfenef", OP48(0xe70000002081LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element not equal word" }, + { "vfeef", OP48(0xe70000002080LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element equal word" }, + { "vesravf", OP48(0xe7000000207aLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right arithmetic reg word" }, + { "vesrlvf", OP48(0xe70000002078LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right logical reg word" }, + { "verllvf", OP48(0xe70000002073LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element rotate left logical reg word" }, + { "verimf", OP48(0xe70000002072LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 9, 8, "vector element rotate and insert under mask word" }, + { "veslvf", OP48(0xe70000002070LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift left reg word" }, + { "vsumqf", OP48(0xe70000002067LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across quadword - word elements" }, + { "vsumgf", OP48(0xe70000002065LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across doubleword - word" }, + { "vmrhf", OP48(0xe70000002061LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge high word" }, + { "vmrlf", OP48(0xe70000002060LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge low word" }, + { "vsegf", OP48(0xe7000000205fLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector sign extend word to double word" }, + { "vistrf", OP48(0xe7000000205cLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 9, 9, "vector isolate string word" }, + { "vgemf", OP48(0xe70000002054LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector generate element masks word" }, + { "vclzf", OP48(0xe70000002053LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count leading zeros word" }, + { "vctzf", OP48(0xe70000002052LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count trailing zeros word" }, + { "vpopctf", OP48(0xe70000002050LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector population count word" }, + { "vrepf", OP48(0xe7000000204dLL), MASK_VRI_VVU, INSTR_VRI_VVU, 2, 9, 8, "vector replicate word" }, + { "vftcisb", OP48(0xe7000000204aLL), MASK_VRI_VVU2, INSTR_VRI_VVU2, 2, 10, 0, "vector fp test data class immediate short" }, + { "vgmf", OP48(0xe70000002046LL), MASK_VRI_V0UU, INSTR_VRI_V0UU, 2, 9, 8, "vector generate mask word" }, + { "vrepif", OP48(0xe70000002045LL), MASK_VRI_V0I, INSTR_VRI_V0I, 2, 9, 8, "vector replicate immediate word" }, + { "vesraf", OP48(0xe7000000203aLL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right arithmetic mem word" }, + { "vesrlf", OP48(0xe70000002038LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right logical mem word" }, + { "verllf", OP48(0xe70000002033LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element rotate left logical mem word" }, + { "veslf", OP48(0xe70000002030LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift left mem word" }, + { "vlvgf", OP48(0xe70000002022LL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector load VR word element from GR" }, + { "vlgvf", OP48(0xe70000002021LL), MASK_VRS_RVRD, INSTR_VRS_RVRD, 2, 9, 8, "vector load GR from VR word element" }, + { "vlrepf", OP48(0xe70000002005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load and replicate word elements" }, + { "vllezf", OP48(0xe70000002004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load logical word element and zero" }, + { "vmxh", OP48(0xe700000010ffLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum halfword" }, + { "vmnh", OP48(0xe700000010feLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum halfword" }, + { "vmxlh", OP48(0xe700000010fdLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum logical halfword" }, + { "vmnlh", OP48(0xe700000010fcLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum logical halfword" }, + { "vchh", OP48(0xe700000010fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high half word" }, + { "vchlh", OP48(0xe700000010f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical half word" }, + { "vceqh", OP48(0xe700000010f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal half word" }, + { "vsh", OP48(0xe700000010f7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract halfword" }, + { "vscbih", OP48(0xe700000010f5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract compute borrow indication halfword" }, + { "vah", OP48(0xe700000010f3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add halfword" }, + { "vavgh", OP48(0xe700000010f2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average half word" }, + { "vacch", OP48(0xe700000010f1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add compute carry halfword" }, + { "vavglh", OP48(0xe700000010f0LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average logical half word" }, + { "vlph", OP48(0xe700000010dfLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load positive halfword" }, + { "vlch", OP48(0xe700000010deLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load complement halfword" }, + { "vech", OP48(0xe700000010dbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare half word" }, + { "veclh", OP48(0xe700000010d9LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare logical half word" }, + { "vuphh", OP48(0xe700000010d7LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack high halfword" }, + { "vuplhw", OP48(0xe700000010d6LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack low halfword" }, + { "vuplhh", OP48(0xe700000010d5LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical high halfword" }, + { "vupllh", OP48(0xe700000010d4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical low halfword" }, + { "vgfmh", OP48(0xe700000010b4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector galois field multiply sum halfword" }, + { "vmoh", OP48(0xe700000010a7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply odd halfword" }, + { "vmeh", OP48(0xe700000010a6LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply even halfword" }, + { "vmloh", OP48(0xe700000010a5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical odd halfword" }, + { "vmleh", OP48(0xe700000010a4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical even halfword" }, + { "vmhh", OP48(0xe700000010a3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply high halfword" }, + { "vmlhw", OP48(0xe700000010a2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply low halfword" }, + { "vmlhh", OP48(0xe700000010a1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical high halfword" }, + { "vpksh", OP48(0xe70000001097LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack saturate halfword" }, + { "vpklsh", OP48(0xe70000001095LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack logical saturate halfword" }, + { "vpkh", OP48(0xe70000001094LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector pack halfword" }, + { "vfaeh", OP48(0xe70000001082LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find any element equal halfword" }, + { "vfeneh", OP48(0xe70000001081LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element not equal halfword" }, + { "vfeeh", OP48(0xe70000001080LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element equal halfword" }, + { "vesravh", OP48(0xe7000000107aLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right arithmetic reg halfword" }, + { "vesrlvh", OP48(0xe70000001078LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right logical reg halfword" }, + { "verllvh", OP48(0xe70000001073LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element rotate left logical reg halfword" }, + { "verimh", OP48(0xe70000001072LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 9, 8, "vector element rotate and insert under mask halfword" }, + { "veslvh", OP48(0xe70000001070LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift left reg halfword" }, + { "vsumgh", OP48(0xe70000001065LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across doubleword - halfword" }, + { "vsumh", OP48(0xe70000001064LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across word - halfword elements" }, + { "vmrhh", OP48(0xe70000001061LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge high halfword" }, + { "vmrlh", OP48(0xe70000001060LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge low halfword" }, + { "vsegh", OP48(0xe7000000105fLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector sign extend halfword to double word" }, + { "vistrh", OP48(0xe7000000105cLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 9, 9, "vector isolate string halfword" }, + { "vgemh", OP48(0xe70000001054LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector generate element masks halfword" }, + { "vclzh", OP48(0xe70000001053LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count leading zeros halfword" }, + { "vctzh", OP48(0xe70000001052LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count trailing zeros halfword" }, + { "vpopcth", OP48(0xe70000001050LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector population count halfword" }, + { "vreph", OP48(0xe7000000104dLL), MASK_VRI_VVU, INSTR_VRI_VVU, 2, 9, 8, "vector replicate halfword" }, + { "vgmh", OP48(0xe70000001046LL), MASK_VRI_V0UU, INSTR_VRI_V0UU, 2, 9, 8, "vector generate mask halfword" }, + { "vrepih", OP48(0xe70000001045LL), MASK_VRI_V0I, INSTR_VRI_V0I, 2, 9, 8, "vector replicate immediate halfword" }, + { "vesrah", OP48(0xe7000000103aLL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right arithmetic mem halfword" }, + { "vesrlh", OP48(0xe70000001038LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right logical mem halfword" }, + { "verllh", OP48(0xe70000001033LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element rotate left logical mem halfword" }, + { "veslh", OP48(0xe70000001030LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift left mem halfword" }, + { "vlvgh", OP48(0xe70000001022LL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector load VR halfword element from GR" }, + { "vlgvh", OP48(0xe70000001021LL), MASK_VRS_RVRD, INSTR_VRS_RVRD, 2, 9, 8, "vector load GR from VR halfword element" }, + { "vlreph", OP48(0xe70000001005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load and replicate halfword elements" }, + { "vllezh", OP48(0xe70000001004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load logical halfword element and zero" }, + { "vmx", OP48(0xe700000000ffLL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector maximum" }, + { "vmxb", OP48(0xe700000000ffLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum byte" }, + { "vmn", OP48(0xe700000000feLL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector minimum" }, + { "vmnb", OP48(0xe700000000feLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum byte" }, + { "vmxl", OP48(0xe700000000fdLL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector maximum logical" }, + { "vmxlb", OP48(0xe700000000fdLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector maximum logical byte" }, + { "vmnl", OP48(0xe700000000fcLL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector minimum logical" }, + { "vmnlb", OP48(0xe700000000fcLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector minimum logical byte" }, + { "vch", OP48(0xe700000000fbLL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 8, "vector compare high" }, + { "vchb", OP48(0xe700000000fbLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high byte" }, + { "vchl", OP48(0xe700000000f9LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 8, "vector compare high logical" }, + { "vchlb", OP48(0xe700000000f9LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare high logical byte" }, + { "vceq", OP48(0xe700000000f8LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 8, "vector compare equal" }, + { "vceqb", OP48(0xe700000000f8LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector compare equal byte" }, + { "vs", OP48(0xe700000000f7LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector subtract" }, + { "vsb", OP48(0xe700000000f7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract byte" }, + { "vscbi", OP48(0xe700000000f5LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector subtract compute borrow indication" }, + { "vscbib", OP48(0xe700000000f5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector subtract compute borrow indication byte" }, + { "va", OP48(0xe700000000f3LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector add" }, + { "vab", OP48(0xe700000000f3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add byte" }, + { "vavg", OP48(0xe700000000f2LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector average" }, + { "vavgb", OP48(0xe700000000f2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average byte" }, + { "vacc", OP48(0xe700000000f1LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector add compute carry" }, + { "vaccb", OP48(0xe700000000f1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector add compute carry byte" }, + { "vavgl", OP48(0xe700000000f0LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector average logical" }, + { "vavglb", OP48(0xe700000000f0LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector average logical byte" }, + { "vfmax", OP48(0xe700000000efLL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 2, 10, 0, "vector fp maximum" }, + { "vfmin", OP48(0xe700000000eeLL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 2, 10, 0, "vector fp minimum" }, + { "vfch", OP48(0xe700000000ebLL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 2, 9, 8, "vector fp compare high" }, + { "vfche", OP48(0xe700000000eaLL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 2, 9, 8, "vector fp compare high or equal" }, + { "vfce", OP48(0xe700000000e8LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 2, 9, 8, "vector fp compare equal" }, + { "vfm", OP48(0xe700000000e7LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 9, 8, "vector fp multiply" }, + { "vfd", OP48(0xe700000000e5LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 9, 8, "vector fp divide" }, + { "vfa", OP48(0xe700000000e3LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 9, 8, "vector fp add" }, + { "vfs", OP48(0xe700000000e2LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 9, 8, "vector fp subtract" }, + { "vlp", OP48(0xe700000000dfLL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector load positive" }, + { "vlpb", OP48(0xe700000000dfLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load positive byte" }, + { "vlc", OP48(0xe700000000deLL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector load complement" }, + { "vlcb", OP48(0xe700000000deLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector load complement byte" }, + { "vec", OP48(0xe700000000dbLL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector element compare" }, + { "vecb", OP48(0xe700000000dbLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare byte" }, + { "vecl", OP48(0xe700000000d9LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector element compare logical" }, + { "veclb", OP48(0xe700000000d9LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector element compare logical byte" }, + { "vtm", OP48(0xe700000000d8LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector test under mask" }, + { "vuph", OP48(0xe700000000d7LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector unpack high" }, + { "vuphb", OP48(0xe700000000d7LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack high byte" }, + { "vupl", OP48(0xe700000000d6LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector unpack low" }, + { "vuplb", OP48(0xe700000000d6LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack low byte" }, + { "vuplh", OP48(0xe700000000d5LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector unpack logical high" }, + { "vuplhb", OP48(0xe700000000d5LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical high byte" }, + { "vupll", OP48(0xe700000000d4LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector unpack logical low" }, + { "vupllb", OP48(0xe700000000d4LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector unpack logical low byte" }, + { "vfsq", OP48(0xe700000000ceLL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 9, 8, "vector fp square root" }, + { "vfpso", OP48(0xe700000000ccLL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp perform sign operation" }, + { "wfc", OP48(0xe700000000cbLL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 9, 8, "vector fp compare scalar" }, + { "wfk", OP48(0xe700000000caLL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 9, 8, "vector fp compare and signal scalar" }, + { "vfi", OP48(0xe700000000c7LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector load fp integer" }, + { "vflr", OP48(0xe700000000c5LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 10, 0, "vector fp load rounded" }, + { "vled", OP48(0xe700000000c5LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp load rounded" }, + { "vfll", OP48(0xe700000000c4LL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 10, 0, "vector fp load lengthened" }, + { "vlde", OP48(0xe700000000c4LL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 9, 8, "vector fp load lengthened" }, + { "vcfps", OP48(0xe700000000c3LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 11, 0, "vector fp convert from fixed" }, + { "vcdg", OP48(0xe700000000c3LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp convert from fixed 64 bit" }, + { "vcsfp", OP48(0xe700000000c2LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 11, 0, "vector fp convert to fixed" }, + { "vcgd", OP48(0xe700000000c2LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp convert to fixed 64 bit" }, + { "vcfpl", OP48(0xe700000000c1LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 11, 0, "vector fp convert from logical" }, + { "vcdlg", OP48(0xe700000000c1LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp convert from logical 64 bit" }, + { "vclfp", OP48(0xe700000000c0LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 11, 0, "vector fp convert to logical" }, + { "vclgd", OP48(0xe700000000c0LL), MASK_VRR_VV0UUU, INSTR_VRR_VV0UUU, 2, 9, 8, "vector fp convert to logical 64 bit" }, + { "vsbi", OP48(0xe700000000bfLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector subtract with borrow indication" }, + { "vsbcbi", OP48(0xe700000000bdLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector subtract with borrow compute borrow indication" }, + { "vgfma", OP48(0xe700000000bcLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector galois field multiply sum and accumulate" }, + { "vgfmab", OP48(0xe700000000bcLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector galois field multiply sum and accumulate byte" }, + { "vac", OP48(0xe700000000bbLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector add with carry" }, + { "vaccc", OP48(0xe700000000b9LL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector add with carry compute carry" }, + { "vmsl", OP48(0xe700000000b8LL), MASK_VRR_VVVUU0V, INSTR_VRR_VVVUU0V, 2, 10, 0, "vector multiply sum logical" }, + { "vgfm", OP48(0xe700000000b4LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector galois field multiply sum" }, + { "vgfmb", OP48(0xe700000000b4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector galois field multiply sum byte" }, + { "vr", OP48(0xe700000000b3LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 13, 0, "vector remainder" }, + { "vd", OP48(0xe700000000b2LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 13, 0, "vector divide" }, + { "vrl", OP48(0xe700000000b1LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 13, 0, "vector remainder logical" }, + { "vdl", OP48(0xe700000000b0LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 13, 0, "vector divide logical" }, + { "vmao", OP48(0xe700000000afLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add odd" }, + { "vmaob", OP48(0xe700000000afLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add odd byte" }, + { "vmae", OP48(0xe700000000aeLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add even" }, + { "vmaeb", OP48(0xe700000000aeLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add even byte" }, + { "vmalo", OP48(0xe700000000adLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add logical odd" }, + { "vmalob", OP48(0xe700000000adLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical odd byte" }, + { "vmale", OP48(0xe700000000acLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add logical even" }, + { "vmaleb", OP48(0xe700000000acLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical even byte" }, + { "vmah", OP48(0xe700000000abLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add high" }, + { "vmahb", OP48(0xe700000000abLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add high byte" }, + { "vmal", OP48(0xe700000000aaLL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add low" }, + { "vmalb", OP48(0xe700000000aaLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add low byte" }, + { "vmalh", OP48(0xe700000000a9LL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 9, 8, "vector multiply and add logical high" }, + { "vmalhb", OP48(0xe700000000a9LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector multiply and add logical high byte" }, + { "vmo", OP48(0xe700000000a7LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply odd" }, + { "vmob", OP48(0xe700000000a7LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply odd byte" }, + { "vme", OP48(0xe700000000a6LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply even" }, + { "vmeb", OP48(0xe700000000a6LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply even byte" }, + { "vmlo", OP48(0xe700000000a5LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply logical odd" }, + { "vmlob", OP48(0xe700000000a5LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical odd byte" }, + { "vmle", OP48(0xe700000000a4LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply logical even" }, + { "vmleb", OP48(0xe700000000a4LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical even byte" }, + { "vmh", OP48(0xe700000000a3LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply high" }, + { "vmhb", OP48(0xe700000000a3LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply high byte" }, + { "vml", OP48(0xe700000000a2LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply low" }, + { "vmlb", OP48(0xe700000000a2LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply low byte" }, + { "vmlh", OP48(0xe700000000a1LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector multiply logical high" }, + { "vmlhb", OP48(0xe700000000a1LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector multiply logical high byte" }, + { "vfnma", OP48(0xe7000000009fLL), MASK_VRR_VVVU0UV, INSTR_VRR_VVVU0UV, 2, 10, 0, "vector fp negative multiply and add" }, + { "vfnms", OP48(0xe7000000009eLL), MASK_VRR_VVVU0UV, INSTR_VRR_VVVU0UV, 2, 10, 0, "vector fp negative multiply and subtract" }, + { "vpks", OP48(0xe70000000097LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 8, "vector pack saturate" }, + { "vpkls", OP48(0xe70000000095LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 8, "vector pack logical saturate" }, + { "vpk", OP48(0xe70000000094LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector pack" }, + { "vfma", OP48(0xe7000000008fLL), MASK_VRR_VVVU0UV, INSTR_VRR_VVVU0UV, 2, 9, 8, "vector fp multiply and add" }, + { "vfms", OP48(0xe7000000008eLL), MASK_VRR_VVVU0UV, INSTR_VRR_VVVU0UV, 2, 9, 8, "vector fp multiply and subtract" }, + { "vsel", OP48(0xe7000000008dLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector select" }, + { "vperm", OP48(0xe7000000008cLL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 9, 8, "vector permute" }, + { "vstrs", OP48(0xe7000000008bLL), MASK_VRR_VVVUU0V, INSTR_VRR_VVVUU0V, 2, 11, 1, "vector string search" }, + { "vstrsb", OP48(0xe7000000008bLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 11, 1, "vector string search byte" }, + { "vstrc", OP48(0xe7000000008aLL), MASK_VRR_VVVUU0V, INSTR_VRR_VVVUU0V, 2, 9, 9, "vector string range compare" }, + { "vstrcb", OP48(0xe7000000008aLL), MASK_VRR_VVVU0VB, INSTR_VRR_VVVU0VB, 2, 9, 9, "vector string range compare byte" }, + { "vblend", OP48(0xe70000000089LL), MASK_VRR_VVVU0V, INSTR_VRR_VVVU0V, 2, 13, 0, "vector blend" }, + { "vblendb", OP48(0xe70000000089LL), MASK_VRR_VVV0V, INSTR_VRR_VVV0V, 2, 13, 0, "vector blend byte" }, + { "veval", OP48(0xe70000000088LL), MASK_VRI_VVV0UV, INSTR_VRI_VVV0UV, 2, 13, 0, "vector evaluate" }, + { "vsrd", OP48(0xe70000000087LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 11, 0, "vector shift right double by bit" }, + { "vsld", OP48(0xe70000000086LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 11, 0, "vector shift left double by bit" }, + { "vbperm", OP48(0xe70000000085LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector bit permute" }, + { "vpdi", OP48(0xe70000000084LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector permute double word immediate" }, + { "vfae", OP48(0xe70000000082LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 9, "vector find any element equal" }, + { "vfaeb", OP48(0xe70000000082LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find any element equal byte" }, + { "vfene", OP48(0xe70000000081LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 9, "vector find element not equal" }, + { "vfeneb", OP48(0xe70000000081LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element not equal byte" }, + { "vfee", OP48(0xe70000000080LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 9, 9, "vector find element equal" }, + { "vfeeb", OP48(0xe70000000080LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 9, 9, "vector find element equal byte" }, + { "vsrab", OP48(0xe7000000007fLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift right arithmetic by byte" }, + { "vsra", OP48(0xe7000000007eLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift right arithmetic" }, + { "vsrlb", OP48(0xe7000000007dLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift right logical by byte" }, + { "vsrl", OP48(0xe7000000007cLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift right logical" }, + { "vesrav", OP48(0xe7000000007aLL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector element shift right arithmetic reg" }, + { "vesravb", OP48(0xe7000000007aLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right arithmetic reg byte" }, + { "vesrlv", OP48(0xe70000000078LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector element shift right logical reg" }, + { "vesrlvb", OP48(0xe70000000078LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift right logical reg byte" }, + { "vsldb", OP48(0xe70000000077LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 9, 8, "vector shift left double by byte" }, + { "vslb", OP48(0xe70000000075LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift left by byte" }, + { "vsl", OP48(0xe70000000074LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector shift left" }, + { "verllv", OP48(0xe70000000073LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector element rotate left logical reg" }, + { "verllvb", OP48(0xe70000000073LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element rotate left logical reg byte" }, + { "verim", OP48(0xe70000000072LL), MASK_VRI_VVV0UU, INSTR_VRI_VVV0UU, 2, 9, 8, "vector element rotate and insert under mask" }, + { "verimb", OP48(0xe70000000072LL), MASK_VRI_VVV0U, INSTR_VRI_VVV0U, 2, 9, 8, "vector element rotate and insert under mask byte" }, + { "veslv", OP48(0xe70000000070LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector element shift left reg" }, + { "veslvb", OP48(0xe70000000070LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector element shift left reg byte" }, + { "voc", OP48(0xe7000000006fLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector or with complement" }, + { "vnn", OP48(0xe7000000006eLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector nand" }, + { "vx", OP48(0xe7000000006dLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector exclusive or" }, + { "vnx", OP48(0xe7000000006cLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 10, 0, "vector not exclusive or" }, + { "vno", OP48(0xe7000000006bLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector nor" }, + { "vnot", OP48(0xe7000000006bLL), MASK_VRR_VVV2, INSTR_VRR_VVV2, 2, 9, 8, "vector not" }, + { "vo", OP48(0xe7000000006aLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector or" }, + { "vnc", OP48(0xe70000000069LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector and with complement" }, + { "vn", OP48(0xe70000000068LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector and" }, + { "vsumq", OP48(0xe70000000067LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector sum across quadword" }, + { "vcksm", OP48(0xe70000000066LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector checksum" }, + { "vsumg", OP48(0xe70000000065LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector sum across doubleword" }, + { "vsum", OP48(0xe70000000064LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector sum across word" }, + { "vsumb", OP48(0xe70000000064LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector sum across word - byte elements" }, + { "vlvgp", OP48(0xe70000000062LL), MASK_VRR_VRR, INSTR_VRR_VRR, 2, 9, 8, "vector load VR from GRs disjoint" }, + { "vmrh", OP48(0xe70000000061LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector merge high" }, + { "vmrhb", OP48(0xe70000000061LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge high byte" }, + { "vmrl", OP48(0xe70000000060LL), MASK_VRR_VVV0U, INSTR_VRR_VVV0U, 2, 9, 8, "vector merge low" }, + { "vmrlb", OP48(0xe70000000060LL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 9, 8, "vector merge low byte" }, + { "vseg", OP48(0xe7000000005fLL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector sign extend to double word" }, + { "vsegb", OP48(0xe7000000005fLL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector sign extend byte to double word" }, + { "vistr", OP48(0xe7000000005cLL), MASK_VRR_VV0U0U, INSTR_VRR_VV0U0U, 2, 9, 9, "vector isolate string" }, + { "vistrb", OP48(0xe7000000005cLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 9, 9, "vector isolate string byte" }, + { "vlr", OP48(0xe70000000056LL), MASK_VRX_VV, INSTR_VRX_VV, 2, 9, 8, "vector register load" }, + { "vgem", OP48(0xe70000000054LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 13, 0, "vector generate element masks" }, + { "vgemb", OP48(0xe70000000054LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 13, 0, "vector generate element masks byte" }, + { "vclz", OP48(0xe70000000053LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector count leading zeros" }, + { "vclzb", OP48(0xe70000000053LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count leading zeros byte" }, + { "vctz", OP48(0xe70000000052LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector count trailing zeros" }, + { "vctzb", OP48(0xe70000000052LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 9, 8, "vector count trailing zeros byte" }, + { "vpopctb", OP48(0xe70000000050LL), MASK_VRR_VV, INSTR_VRR_VV, 2, 10, 0, "vector population count byte" }, + { "vpopct", OP48(0xe70000000050LL), MASK_VRR_VV0U, INSTR_VRR_VV0U, 2, 9, 8, "vector population count" }, + { "vrep", OP48(0xe7000000004dLL), MASK_VRI_VVUU, INSTR_VRI_VVUU, 2, 9, 8, "vector replicate" }, + { "vrepb", OP48(0xe7000000004dLL), MASK_VRI_VVU, INSTR_VRI_VVU, 2, 9, 8, "vector replicate byte" }, + { "vftci", OP48(0xe7000000004aLL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 2, 9, 8, "vector fp test data class immediate" }, + { "vgm", OP48(0xe70000000046LL), MASK_VRI_V0UUU, INSTR_VRI_V0UUU, 2, 9, 8, "vector generate mask" }, + { "vgmb", OP48(0xe70000000046LL), MASK_VRI_V0UU, INSTR_VRI_V0UU, 2, 9, 8, "vector generate mask byte" }, + { "vrepi", OP48(0xe70000000045LL), MASK_VRI_V0IU, INSTR_VRI_V0IU, 2, 9, 8, "vector replicate immediate" }, + { "vrepib", OP48(0xe70000000045LL), MASK_VRI_V0I, INSTR_VRI_V0I, 2, 9, 8, "vector replicate immediate byte" }, + { "vgbm", OP48(0xe70000000044LL), MASK_VRI_V0U, INSTR_VRI_V0U, 2, 9, 8, "vector generate byte mask" }, + { "vzero", OP48(0xe70000000044LL), MASK_VRI_V, INSTR_VRI_V, 2, 9, 8, "vector set to zero" }, + { "vleif", OP48(0xe70000000043LL), MASK_VRI_V0IU, INSTR_VRI_V0IU, 2, 9, 8, "vector load word element immediate" }, + { "vleig", OP48(0xe70000000042LL), MASK_VRI_V0IU, INSTR_VRI_V0IU, 2, 9, 8, "vector load double word element immediate" }, + { "vleih", OP48(0xe70000000041LL), MASK_VRI_V0IU, INSTR_VRI_V0IU, 2, 9, 8, "vector load halfword element immediate" }, + { "vleib", OP48(0xe70000000040LL), MASK_VRI_V0IU, INSTR_VRI_V0IU, 2, 9, 8, "vector load byte element immediate" }, + { "vstl", OP48(0xe7000000003fLL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector store with length" }, + { "vstm", OP48(0xe7000000003eLL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 9, "vector store multiple" }, + { "vesra", OP48(0xe7000000003aLL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 8, "vector element shift right arithmetic mem" }, + { "vesrab", OP48(0xe7000000003aLL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right arithmetic mem byte" }, + { "vesrl", OP48(0xe70000000038LL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 8, "vector element shift right logical mem" }, + { "vesrlb", OP48(0xe70000000038LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift right logical mem byte" }, + { "vll", OP48(0xe70000000037LL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector load with length" }, + { "vlm", OP48(0xe70000000036LL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 9, "vector load multiple" }, + { "verll", OP48(0xe70000000033LL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 8, "vector element rotate left logical mem" }, + { "verllb", OP48(0xe70000000033LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element rotate left logical mem byte" }, + { "vesl", OP48(0xe70000000030LL), MASK_VRS_VVRDU, INSTR_VRS_VVRDU, 2, 9, 8, "vector element shift left mem" }, + { "veslb", OP48(0xe70000000030LL), MASK_VRS_VVRD, INSTR_VRS_VVRD, 2, 9, 8, "vector element shift left mem byte" }, + { "lcbb", OP48(0xe70000000027LL), MASK_RXE_RRRDU, INSTR_RXE_RRRDU, 2, 9, 8, "load count to block boundary" }, + { "vlvg", OP48(0xe70000000022LL), MASK_VRS_VRRDU, INSTR_VRS_VRRDU, 2, 9, 8, "vector load VR element from GR" }, + { "vlvgb", OP48(0xe70000000022LL), MASK_VRS_VRRD, INSTR_VRS_VRRD, 2, 9, 8, "vector load VR byte element from GR" }, + { "vlgv", OP48(0xe70000000021LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 2, 9, 8, "vector load GR from VR element" }, + { "vlgvb", OP48(0xe70000000021LL), MASK_VRS_RVRD, INSTR_VRS_RVRD, 2, 9, 8, "vector load GR from VR byte element" }, + { "vscef", OP48(0xe7000000001bLL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 2, 9, 8, "vector scatter element 4 byte" }, + { "vsceg", OP48(0xe7000000001aLL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 2, 9, 8, "vector scatter element 8 byte" }, + { "vgef", OP48(0xe70000000013LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 2, 9, 8, "vector gather element 4 byte elements" }, + { "vgeg", OP48(0xe70000000012LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 2, 9, 8, "vector gather element 8 byte elements" }, + { "vst", OP48(0xe7000000000eLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 9, "vector store" }, + { "vstef", OP48(0xe7000000000bLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector store word element" }, + { "vsteg", OP48(0xe7000000000aLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector store double word element" }, + { "vsteh", OP48(0xe70000000009LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector store halfword element" }, + { "vsteb", OP48(0xe70000000008LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector store byte element" }, + { "vlbb", OP48(0xe70000000007LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load to block boundary" }, + { "vl", OP48(0xe70000000006LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 9, "vector memory load" }, + { "vlrep", OP48(0xe70000000005LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load and replicate" }, + { "vlrepb", OP48(0xe70000000005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load and replicate byte elements" }, + { "vllez", OP48(0xe70000000004LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load logical element and zero" }, + { "vllezb", OP48(0xe70000000004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 9, 8, "vector load logical byte element and zero" }, + { "vlef", OP48(0xe70000000003LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load word element" }, + { "vleg", OP48(0xe70000000002LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load double word element" }, + { "vleh", OP48(0xe70000000001LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load halfword element" }, + { "vleb", OP48(0xe70000000000LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 9, 8, "vector load byte element" }, + { "lerv", OP48(0xe60000006004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "load byte reversed word" }, + { "vllebrze", OP48(0xe60000006004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed word element left-aligned and zero" }, + { "vschxp", OP48(0xe60000004074LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 12, 0, "decimal scale and convert to extended hfp" }, + { "vstbrq", OP48(0xe6000000400eLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store byte reversed quadword elements" }, + { "vlbrq", OP48(0xe60000004006LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed quadword elements" }, + { "vschdp", OP48(0xe60000003074LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 12, 0, "decimal scale and convert to long hfp" }, + { "vsterg", OP48(0xe6000000300fLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store doubleword elements reversed" }, + { "vstbrg", OP48(0xe6000000300eLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store byte reversed doubleword elements" }, + { "vlerg", OP48(0xe60000003007LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load doubleword elements reversed" }, + { "vlbrg", OP48(0xe60000003006LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed doubleword elements" }, + { "vlbrrepg", OP48(0xe60000003005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed doubleword element and replicate" }, + { "ldrv", OP48(0xe60000003004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "load byte reversed doubleword" }, + { "vllebrzg", OP48(0xe60000003004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed doubleword element and zero" }, + { "vschsp", OP48(0xe60000002074LL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 12, 0, "decimal scale and convert to short hfp" }, + { "vsterf", OP48(0xe6000000200fLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store word elements reversed" }, + { "vstbrf", OP48(0xe6000000200eLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store byte reversed word elements" }, + { "vlerf", OP48(0xe60000002007LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load word elements reversed" }, + { "vlbrf", OP48(0xe60000002006LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed word elements" }, + { "vlbrrepf", OP48(0xe60000002005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed word element and replicate" }, + { "vllebrzf", OP48(0xe60000002004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed word element and zero" }, + { "vsterh", OP48(0xe6000000100fLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store halfword elements reversed" }, + { "vstbrh", OP48(0xe6000000100eLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector store byte reversed halfword elements" }, + { "vlerh", OP48(0xe60000001007LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load halfword elements reversed" }, + { "vlbrh", OP48(0xe60000001006LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed halfword elements" }, + { "vlbrreph", OP48(0xe60000001005LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed halfword element and replicate" }, + { "vllebrzh", OP48(0xe60000001004LL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "vector load byte reversed halfword element and zero" }, + { "vtz", OP48(0xe6000000007fLL), MASK_VRR_0VVU, INSTR_VRR_0VVU, 2, 13, 0, "vector test zoned" }, + { "vsdp", OP48(0xe6000000007eLL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector shift and divide decimal" }, + { "vcsph", OP48(0xe6000000007dLL), MASK_VRR_VVV0U0, INSTR_VRR_VVV0U0, 2, 12, 0, "vector convert hfp to scaled decimal" }, + { "vscshp", OP48(0xe6000000007cLL), MASK_VRR_VVV, INSTR_VRR_VVV, 2, 12, 0, "decimal scale and convert and split to hfp" }, + { "vrp", OP48(0xe6000000007bLL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector remainder decimal" }, + { "vdp", OP48(0xe6000000007aLL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector divide decimal" }, + { "vmsp", OP48(0xe60000000079LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector multiply and shift decimal" }, + { "vmp", OP48(0xe60000000078LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector multiply decimal" }, + { "vcp", OP48(0xe60000000077LL), MASK_VRR_0VV0U, INSTR_VRR_0VV0U, 2, 10, 0, "vector compare decimal" }, + { "vcrnf", OP48(0xe60000000075LL), MASK_VRR_VVV0UU, INSTR_VRR_VVV0UU, 2, 12, 0, "vector fp convert and round to nnp" }, + { "vschp", OP48(0xe60000000074LL), MASK_VRR_VVV0U0U, INSTR_VRR_VVV0U0U, 2, 12, 0, "decimal scale and convert to hfp" }, + { "vsp", OP48(0xe60000000073LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector subtract decimal" }, + { "vsrpr", OP48(0xe60000000072LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 12, 0, "vector shift and round decimal register" }, + { "vap", OP48(0xe60000000071LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 10, 0, "vector add decimal" }, + { "vpkzr", OP48(0xe60000000070LL), MASK_VRI_VVV0UU2, INSTR_VRI_VVV0UU2, 2, 12, 0, "vector pack zoned register" }, + { "vtp", OP48(0xe6000000005fLL), MASK_VRR_0V0U, INSTR_VRR_0V0U, 2, 13, 1, "vector test decimal" }, + { "vtp", OP48(0xe6000000005fLL), MASK_VRR_0V, INSTR_VRR_0V, 2, 10, 0, "vector test decimal" }, + { "vclfnl", OP48(0xe6000000005eLL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 12, 0, "vector fp convert and lengthen from nnp low" }, + { "vcfn", OP48(0xe6000000005dLL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 12, 0, "vector fp convert from nnp" }, + { "vupkzl", OP48(0xe6000000005cLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 12, 0, "vector unpack zoned low" }, + { "vpsop", OP48(0xe6000000005bLL), MASK_VRI_VVUUU2, INSTR_VRI_VVUUU2, 2, 10, 0, "vector perform sign operation decimal" }, + { "vcvdg", OP48(0xe6000000005aLL), MASK_VRI_VR0UU, INSTR_VRI_VR0UU, 2, 10, 0, "vector convert to decimal 64 bit" }, + { "vsrp", OP48(0xe60000000059LL), MASK_VRI_VVUUU2, INSTR_VRI_VVUUU2, 2, 10, 0, "vector shift and round decimal" }, + { "vcvd", OP48(0xe60000000058LL), MASK_VRI_VR0UU, INSTR_VRI_VR0UU, 2, 10, 0, "vector convert to decimal 32 bit" }, + { "vclfnh", OP48(0xe60000000056LL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 12, 0, "vector fp convert and lengthen from nnp high" }, + { "vcnf", OP48(0xe60000000055LL), MASK_VRR_VV0UU2, INSTR_VRR_VV0UU2, 2, 12, 0, "vector fp convert to nnp" }, + { "vupkzh", OP48(0xe60000000054LL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 12, 0, "vector unpack zoned high" }, + { "vcvbg", OP48(0xe60000000052LL), MASK_VRR_RV0UU, INSTR_VRR_RV0UU, 2, 11, 1, "vector convert to binary 64 bit" }, + { "vcvbg", OP48(0xe60000000052LL), MASK_VRR_RV0U, INSTR_VRR_RV0U, 2, 10, 0, "vector convert to binary 64 bit" }, + { "vclzdp", OP48(0xe60000000051LL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 12, 0, "vector count leading zero digits" }, + { "vcvb", OP48(0xe60000000050LL), MASK_VRR_RV0UU, INSTR_VRR_RV0UU, 2, 11, 1, "vector convert to binary 32 bit" }, + { "vcvb", OP48(0xe60000000050LL), MASK_VRR_RV0U, INSTR_VRR_RV0U, 2, 10, 0, "vector convert to binary 32 bit" }, + { "vcvbq", OP48(0xe6000000004eLL), MASK_VRR_VV0U2, INSTR_VRR_VV0U2, 2, 13, 0, "vector convert to binary 128 bit" }, + { "vcvdq", OP48(0xe6000000004aLL), MASK_VRI_VV0UU, INSTR_VRI_VV0UU, 2, 13, 0, "vector convert to decimal 128 bit" }, + { "vlip", OP48(0xe60000000049LL), MASK_VRI_V0UU2, INSTR_VRI_V0UU2, 2, 10, 0, "vector load immediate decimal" }, + { "vstrlr", OP48(0xe6000000003fLL), MASK_VRS_RRDV, INSTR_VRS_RRDV, 2, 10, 0, "vector store rightmost with length" }, + { "vstrl", OP48(0xe6000000003dLL), MASK_VSI_URDV, INSTR_VSI_URDV, 2, 10, 0, "vector store rightmost with immediate length" }, + { "vupkz", OP48(0xe6000000003cLL), MASK_VSI_URDV, INSTR_VSI_URDV, 2, 10, 0, "vector unpack zoned" }, + { "vlrlr", OP48(0xe60000000037LL), MASK_VRS_RRDV, INSTR_VRS_RRDV, 2, 10, 0, "vector load rightmost with length" }, + { "vlrl", OP48(0xe60000000035LL), MASK_VSI_URDV, INSTR_VSI_URDV, 2, 10, 0, "vector load rightmost with immediate length" }, + { "vpkz", OP48(0xe60000000034LL), MASK_VSI_URDV, INSTR_VSI_URDV, 2, 10, 0, "vector pack zoned" }, + { "vster", OP48(0xe6000000000fLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector store elements reversed" }, + { "vstbr", OP48(0xe6000000000eLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector store byte reversed elements" }, + { "vstebrf", OP48(0xe6000000000bLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector store byte reversed word element" }, + { "sterv", OP48(0xe6000000000bLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "store byte reversed word" }, + { "vstebrg", OP48(0xe6000000000aLL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector store byte reversed doubleword element" }, + { "stdrv", OP48(0xe6000000000aLL), MASK_VRX_VRRD, INSTR_VRX_VRRD, 2, 11, 0, "store byte reversed doubleword" }, + { "vstebrh", OP48(0xe60000000009LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector store byte reversed halfword element" }, + { "vler", OP48(0xe60000000007LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load elements reversed" }, + { "vlbr", OP48(0xe60000000006LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed elements" }, + { "vlbrrep", OP48(0xe60000000005LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed element and replicate" }, + { "vllebrz", OP48(0xe60000000004LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed element and zero" }, + { "vlebrf", OP48(0xe60000000003LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed word element" }, + { "vlebrg", OP48(0xe60000000002LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed doubleword element" }, + { "vlebrh", OP48(0xe60000000001LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 2, 11, 0, "vector load byte reversed halfword element" }, + { "tbeginc", OP16(0xe561LL), MASK_SIL_RDU, INSTR_SIL_RDU, 2, 8, 4, "constrained transaction begin" }, + { "tbegin", OP16(0xe560LL), MASK_SIL_RDU, INSTR_SIL_RDU, 2, 8, 4, "transaction begin" }, + { "clfhsi", OP16(0xe55dLL), MASK_SIL_RDU, INSTR_SIL_RDU, 2, 6, 0, "compare logical immediate (32<16)" }, + { "chsi", OP16(0xe55cLL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "compare halfword immediate (32<16)" }, + { "clghsi", OP16(0xe559LL), MASK_SIL_RDU, INSTR_SIL_RDU, 2, 6, 0, "compare logical immediate (64<16)" }, + { "cghsi", OP16(0xe558LL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "compare halfword immediate (64<16)" }, + { "clhhsi", OP16(0xe555LL), MASK_SIL_RDU, INSTR_SIL_RDU, 2, 6, 0, "compare logical immediate (16<16)" }, + { "chhsi", OP16(0xe554LL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "compare halfword immediate (16<16)" }, + { "mvhi", OP16(0xe54cLL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "move (32<16)" }, + { "mvghi", OP16(0xe548LL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "move (64<16)" }, + { "mvhhi", OP16(0xe544LL), MASK_SIL_RDI, INSTR_SIL_RDI, 2, 6, 0, "move (16<16)" }, + { "mvcdk", OP16(0xe50fLL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, "move with destination key" }, + { "mvcsk", OP16(0xe50eLL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, "move with source key" }, + { "mvcrl", OP16(0xe50aLL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 2, 11, 0, "move right to left" }, + { "strag", OP16(0xe502LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 2, 2, 0, "store read address" }, + { "tprot", OP16(0xe501LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, "test protection" }, + { "lasp", OP16(0xe500LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, "load address space parameters" }, + { "bi", OP48(0xe3f000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "unconditional indirect branch" }, + { "bino", OP48(0xe3e000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not overflow / if not ones" }, + { "binh", OP48(0xe3d000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A not high" }, + { "binp", OP48(0xe3d000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not plus" }, + { "bile", OP48(0xe3c000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on low or equal" }, + { "binl", OP48(0xe3b000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A not low" }, + { "binm", OP48(0xe3b000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not minus / if not mixed" }, + { "bihe", OP48(0xe3a000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on high or equal" }, + { "binlh", OP48(0xe39000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not low or high" }, + { "bie", OP48(0xe38000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A equal B" }, + { "biz", OP48(0xe38000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on zero / if zeros" }, + { "bine", OP48(0xe37000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A not equal B" }, + { "binz", OP48(0xe37000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not zero / if not zeros" }, + { "bilh", OP48(0xe36000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on low or high" }, + { "binhe", OP48(0xe35000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not high or equal" }, + { "bil", OP48(0xe34000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A low" }, + { "bim", OP48(0xe34000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on minus / if mixed" }, + { "binle", OP48(0xe33000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on not low or equal" }, + { "bih", OP48(0xe32000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on A high" }, + { "bip", OP48(0xe32000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on plus" }, + { "bio", OP48(0xe31000000047LL), MASK_RXY_0RRD, INSTR_RXY_0RRD, 2, 10, 0, "branch indirect on condition on overflow / if ones" }, + { "clhf", OP48(0xe300000000cfLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "compare logical high" }, + { "chf", OP48(0xe300000000cdLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "compare high" }, + { "stfh", OP48(0xe300000000cbLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "store high" }, + { "lfh", OP48(0xe300000000caLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "load high" }, + { "lfhat", OP48(0xe300000000c8LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 0, "load high and trap" }, + { "sthh", OP48(0xe300000000c7LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "store halfword high" }, + { "llhh", OP48(0xe300000000c6LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "load logical halfword high" }, + { "lhh", OP48(0xe300000000c4LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "load halfword high" }, + { "stch", OP48(0xe300000000c3LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "store character high" }, + { "llch", OP48(0xe300000000c2LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "load logical character high" }, + { "lbh", OP48(0xe300000000c0LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 7, 0, "load byte high" }, + { "lat", OP48(0xe3000000009fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 0, "load and trap 32 bit" }, + { "llgfat", OP48(0xe3000000009dLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 0, "load logical and trap 32>64" }, + { "llgtat", OP48(0xe3000000009cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 0, "load logical thirty one bits and trap 31>64" }, + { "slb", OP48(0xe30000000099LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, "subtract logical with borrow 32" }, + { "slb", OP48(0xe30000000099LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "subtract logical with borrow 32" }, + { "alc", OP48(0xe30000000098LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, "add logical with carry 32" }, + { "alc", OP48(0xe30000000098LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "add logical with carry 32" }, + { "dl", OP48(0xe30000000097LL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 3, 3, 0, "divide logical 32" }, + { "dl", OP48(0xe30000000097LL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 3, 2, 0, "divide logical 32" }, + { "ml", OP48(0xe30000000096LL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 3, 3, 0, "multiply logical 32" }, + { "ml", OP48(0xe30000000096LL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 3, 2, 0, "multiply logical 32" }, + { "llh", OP48(0xe30000000095LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 4, 0, "load logical halfword 32" }, + { "llc", OP48(0xe30000000094LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 4, 0, "load logical character 32" }, + { "llgh", OP48(0xe30000000091LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load logical halfword" }, + { "llgh", OP48(0xe30000000091LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load logical halfword" }, + { "llgc", OP48(0xe30000000090LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load logical character" }, + { "llgc", OP48(0xe30000000090LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load logical character" }, + { "lpq", OP48(0xe3000000008fLL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 3, 0, "load pair from quadword" }, + { "lpq", OP48(0xe3000000008fLL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 2, 2, 0, "load pair from quadword" }, + { "stpq", OP48(0xe3000000008eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store pair to quadword" }, + { "stpq", OP48(0xe3000000008eLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "store pair to quadword" }, + { "slbg", OP48(0xe30000000089LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract logical with borrow 64" }, + { "slbg", OP48(0xe30000000089LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "subtract logical with borrow 64" }, + { "alcg", OP48(0xe30000000088LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add logical with carry 64" }, + { "alcg", OP48(0xe30000000088LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "add logical with carry 64" }, + { "dlg", OP48(0xe30000000087LL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 3, 0, "divide logical 64" }, + { "dlg", OP48(0xe30000000087LL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 2, 2, 0, "divide logical 64" }, + { "mlg", OP48(0xe30000000086LL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 3, 0, "multiply logical 64" }, + { "mlg", OP48(0xe30000000086LL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 2, 2, 0, "multiply logical 64" }, + { "lgat", OP48(0xe30000000085LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 0, "load and trap 64 bit" }, + { "mg", OP48(0xe30000000084LL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 10, 0, "multiply 64x64mem -> 128" }, + { "msgc", OP48(0xe30000000083LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "multiply single 64x64mem -> 64" }, + { "xg", OP48(0xe30000000082LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "exclusive or with long offset 64" }, + { "xg", OP48(0xe30000000082LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "exclusive or 64" }, + { "og", OP48(0xe30000000081LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "or with long offset 64" }, + { "og", OP48(0xe30000000081LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "or 64" }, + { "ng", OP48(0xe30000000080LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "and with long offset 64" }, + { "ng", OP48(0xe30000000080LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "and 64" }, + { "mhy", OP48(0xe3000000007cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 6, 0, "multiply halfword" }, + { "shy", OP48(0xe3000000007bLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract halfword with long offset" }, + { "ahy", OP48(0xe3000000007aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add halfword with long offset" }, + { "chy", OP48(0xe30000000079LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare halfword with long offset" }, + { "lhy", OP48(0xe30000000078LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load halfword with long offset" }, + { "lgb", OP48(0xe30000000077LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load byte with long offset 64" }, + { "lb", OP48(0xe30000000076LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load byte with long offset" }, + { "laey", OP48(0xe30000000075LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 6, 0, "load address extended" }, + { "icy", OP48(0xe30000000073LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "insert character with long offset" }, + { "stcy", OP48(0xe30000000072LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store character with long offset" }, + { "lay", OP48(0xe30000000071LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load address with long offset" }, + { "sthy", OP48(0xe30000000070LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store halfword with long offset" }, + { "llxaq", OP48(0xe30000000069LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load logical indexed address (shift left 4)" }, + { "lxaq", OP48(0xe30000000068LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load indexed address (shift left 4)" }, + { "llxag", OP48(0xe30000000067LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load logical indexed address (shift left 3)" }, + { "lxag", OP48(0xe30000000066LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load indexed address (shift left 3)" }, + { "llxaf", OP48(0xe30000000065LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load logical indexed address (shift left 2)" }, + { "lxaf", OP48(0xe30000000064LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load indexed address (shift left 2)" }, + { "llxah", OP48(0xe30000000063LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load logical indexed address (shift left 1)" }, + { "lxah", OP48(0xe30000000062LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load indexed address (shift left 1)" }, + { "llxab", OP48(0xe30000000061LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load logical indexed address (shift left 0)" }, + { "lxab", OP48(0xe30000000060LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 13, 0, "load indexed address (shift left 0)" }, + { "sly", OP48(0xe3000000005fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract logical with long offset" }, + { "aly", OP48(0xe3000000005eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add logical with long offset" }, + { "mfy", OP48(0xe3000000005cLL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 6, 0, "multiply" }, + { "sy", OP48(0xe3000000005bLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract with long offset" }, + { "ay", OP48(0xe3000000005aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add with long offset" }, + { "cy", OP48(0xe30000000059LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare with long offset" }, + { "ly", OP48(0xe30000000058LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load with long offset" }, + { "xy", OP48(0xe30000000057LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "exclusive or with long offset" }, + { "oy", OP48(0xe30000000056LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "or with long offset" }, + { "cly", OP48(0xe30000000055LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare logical with long offset" }, + { "ny", OP48(0xe30000000054LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "and with long offset" }, + { "msc", OP48(0xe30000000053LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "multiply single 32x32mem -> 32" }, + { "msy", OP48(0xe30000000051LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "multiply single with long offset" }, + { "sty", OP48(0xe30000000050LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store with long offset" }, + { "lgsc", OP48(0xe3000000004dLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "load guarded storage controls" }, + { "lgg", OP48(0xe3000000004cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "load guarded 64 bit" }, + { "stgsc", OP48(0xe30000000049LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "store guarded storage controls" }, + { "llgfsg", OP48(0xe30000000048LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "load logical and shift guarded 64 bit" }, + { "bic", OP48(0xe30000000047LL), MASK_RXY_URRD, INSTR_RXY_URRD, 2, 10, 0, "branch indirect on condition" }, + { "bctg", OP48(0xe30000000046LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "branch on count 64" }, + { "bctg", OP48(0xe30000000046LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "branch on count 64" }, + { "strvh", OP48(0xe3000000003fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store reversed 64" }, + { "strvh", OP48(0xe3000000003fLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "store reversed 64" }, + { "strv", OP48(0xe3000000003eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, "store reversed 32" }, + { "strv", OP48(0xe3000000003eLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "store reversed 32" }, + { "mgh", OP48(0xe3000000003cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "multiply halfword 64x16mem -> 64" }, + { "lzrf", OP48(0xe3000000003bLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 9, 0, "load and zero rightmost byte 32->32" }, + { "llzrgf", OP48(0xe3000000003aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 9, 0, "load logical and zero rightmost bytes 32->64" }, + { "sgh", OP48(0xe30000000039LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "subtract halfword from 64 bit value" }, + { "agh", OP48(0xe30000000038LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 10, 0, "add halfword to 64 bit value" }, + { "pfd", OP48(0xe30000000036LL), MASK_RXY_URRD, INSTR_RXY_URRD, 2, 6, 0, "prefetch data" }, + { "cgh", OP48(0xe30000000034LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 6, 0, "compare halfword (64<16)" }, + { "ltgf", OP48(0xe30000000032LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 6, 0, "load and test (64<32)" }, + { "clgf", OP48(0xe30000000031LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare logical with long offset 64<32" }, + { "clgf", OP48(0xe30000000031LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "compare logical 64<32" }, + { "cgf", OP48(0xe30000000030LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare with long offset 64<32" }, + { "cgf", OP48(0xe30000000030LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "compare 64<32" }, + { "strvg", OP48(0xe3000000002fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store reversed 64" }, + { "strvg", OP48(0xe3000000002fLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "store reversed 64" }, + { "cvdg", OP48(0xe3000000002eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "convert to decimal with long offset 64" }, + { "cvdg", OP48(0xe3000000002eLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "convert to decimal 64" }, + { "lzrg", OP48(0xe3000000002aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 9, 0, "load and zero rightmost byte 64->64" }, + { "cvdy", OP48(0xe30000000026LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "convert to decimal with long offset" }, + { "ntstg", OP48(0xe30000000025LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 8, 4, "nontransactional store" }, + { "stg", OP48(0xe30000000024LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "store with long offset 64" }, + { "stg", OP48(0xe30000000024LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "store 64" }, + { "clg", OP48(0xe30000000021LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare logical with long offset 64" }, + { "clg", OP48(0xe30000000021LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "compare logical 64" }, + { "cg", OP48(0xe30000000020LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "compare with long offset 64" }, + { "cg", OP48(0xe30000000020LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "compare 64" }, + { "lrvh", OP48(0xe3000000001fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, "load reversed 16" }, + { "lrvh", OP48(0xe3000000001fLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "load reversed 16" }, + { "lrv", OP48(0xe3000000001eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, "load reversed 32" }, + { "lrv", OP48(0xe3000000001eLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2, 0, "load reversed 32" }, + { "dsgf", OP48(0xe3000000001dLL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 3, 0, "divide single 64<32" }, + { "dsgf", OP48(0xe3000000001dLL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 2, 2, 0, "divide single 64<32" }, + { "msgf", OP48(0xe3000000001cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "multiply single with long offset 64<32" }, + { "msgf", OP48(0xe3000000001cLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "multiply single 64<32" }, + { "slgf", OP48(0xe3000000001bLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract logical with long offset 64<32" }, + { "slgf", OP48(0xe3000000001bLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "subtract logical 64<32" }, + { "algf", OP48(0xe3000000001aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add logical with long offset 64<32" }, + { "algf", OP48(0xe3000000001aLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "add logical 64<32" }, + { "sgf", OP48(0xe30000000019LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract with long offset 64<32" }, + { "sgf", OP48(0xe30000000019LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "subtract 64<32" }, + { "agf", OP48(0xe30000000018LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add with long offset 64<32" }, + { "agf", OP48(0xe30000000018LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "add 64<32" }, + { "llgt", OP48(0xe30000000017LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load logical thirty one bits" }, + { "llgt", OP48(0xe30000000017LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load logical thirty one bits" }, + { "llgf", OP48(0xe30000000016LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load logical 64<32" }, + { "llgf", OP48(0xe30000000016LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load logical 64<32" }, + { "lgh", OP48(0xe30000000015LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load halfword 64" }, + { "lgh", OP48(0xe30000000015LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load halfword 64" }, + { "lgf", OP48(0xe30000000014LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load 64<32" }, + { "lgf", OP48(0xe30000000014LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load 64<32" }, + { "lray", OP48(0xe30000000013LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load real address with long offset" }, + { "lt", OP48(0xe30000000012LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 4, 0, "load and test 32" }, + { "lrvg", OP48(0xe3000000000fLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load reversed 64" }, + { "lrvg", OP48(0xe3000000000fLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load reversed 64" }, + { "cvbg", OP48(0xe3000000000eLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "convert to binary with long offset 64" }, + { "cvbg", OP48(0xe3000000000eLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "convert to binary 64" }, + { "dsg", OP48(0xe3000000000dLL), MASK_RXY_RERRD, INSTR_RXY_RERRD, 2, 3, 0, "divide single 64" }, + { "dsg", OP48(0xe3000000000dLL), MASK_RXE_RERRD, INSTR_RXE_RERRD, 2, 2, 0, "divide single 64" }, + { "msg", OP48(0xe3000000000cLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "multiply single with long offset 64" }, + { "msg", OP48(0xe3000000000cLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "multiply single 64" }, + { "slg", OP48(0xe3000000000bLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract logical with long offset 64" }, + { "slg", OP48(0xe3000000000bLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "subtract logical 64" }, + { "alg", OP48(0xe3000000000aLL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add logical with long offset 64" }, + { "alg", OP48(0xe3000000000aLL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "add logical 64" }, + { "sg", OP48(0xe30000000009LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "subtract with long offset 64" }, + { "sg", OP48(0xe30000000009LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "subtract 64" }, + { "ag", OP48(0xe30000000008LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "add with long offset 64" }, + { "ag", OP48(0xe30000000008LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "add 64" }, + { "cvby", OP48(0xe30000000006LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "convert to binary with long offset" }, + { "lg", OP48(0xe30000000004LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load 64" }, + { "lg", OP48(0xe30000000004LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load 64" }, + { "lrag", OP48(0xe30000000003LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3, 0, "load real address with long offset 64" }, + { "lrag", OP48(0xe30000000003LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2, 0, "load real address 64" }, + { "ltg", OP48(0xe30000000002LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 4, 0, "load and test 64" }, + { "unpku", OP8(0xe2LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "unpack unicode" }, + { "pku", OP8(0xe1LL), MASK_SS_L2RDRD, INSTR_SS_L2RDRD, 3, 0, 0, "pack unicode" }, + { "edmk", OP8(0xdfLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "edit and mark" }, + { "ed", OP8(0xdeLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "edit" }, + { "trt", OP8(0xddLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "translate and test" }, + { "tr", OP8(0xdcLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "translate" }, + { "mvcs", OP8(0xdbLL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, "move to secondary" }, + { "mvcp", OP8(0xdaLL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, "move to primary" }, + { "mvck", OP8(0xd9LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, "move with key" }, + { "xc", OP8(0xd7LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "exclusive or" }, + { "oc", OP8(0xd6LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "or" }, + { "clc", OP8(0xd5LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "compare logical" }, + { "nc", OP8(0xd4LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "and" }, + { "mvz", OP8(0xd3LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "move zones" }, + { "mvc", OP8(0xd2LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "move" }, + { "mvn", OP8(0xd1LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0, 0, "move numerics" }, + { "trtr", OP8(0xd0LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 2, 4, 0, "tranlate and test reverse" }, + { "clih", OP16(0xcc0fLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 7, 0, "compare logical immediate" }, + { "cih", OP16(0xcc0dLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 7, 0, "compare immediate high" }, + { "alsihn", OP16(0xcc0bLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 7, 0, "add logical with signed immediate high no cc" }, + { "alsih", OP16(0xcc0aLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 7, 0, "add logical with signed immediate high with cc" }, + { "aih", OP16(0xcc08LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 7, 0, "add immediate high" }, + { "brcth", OP16(0xcc06LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 7, 112, "branch relative on count high" }, + { "jcth", OP16(0xcc06LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 7, 112, "jump on count high" }, + { "calgf", OP16(0xc80fLL), MASK_SSF_RRDRD2, INSTR_SSF_RRDRD2, 2, 13, 0, "compare and load 64<32" }, + { "calg", OP16(0xc807LL), MASK_SSF_RRDRD2, INSTR_SSF_RRDRD2, 2, 13, 0, "compare and load 64" }, + { "cal", OP16(0xc806LL), MASK_SSF_RRDRD2, INSTR_SSF_RRDRD2, 2, 13, 0, "compare and load 32" }, + { "lpdg", OP16(0xc805LL), MASK_SSF_RERDRD2, INSTR_SSF_RERDRD2, 2, 7, 0, "load pair disjoint 64 bit" }, + { "lpd", OP16(0xc804LL), MASK_SSF_RERDRD2, INSTR_SSF_RERDRD2, 2, 7, 0, "load pair disjoint 32 bit" }, + { "csst", OP16(0xc802LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 5, 0, "compare and swap and store" }, + { "ectg", OP16(0xc801LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 5, 0, "extract cpu time" }, + { "mvcos", OP16(0xc800LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 4, 0, "move with optional specifications" }, + { "bpp", OP8(0xc7LL), MASK_SMI_U0RDP, INSTR_SMI_U0RDP, 2, 8, 0, "branch prediction preload" }, + { "clrl", OP16(0xc60fLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare logical relative long (32)" }, + { "clgfrl", OP16(0xc60eLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare logical relative long (64<32)" }, + { "crl", OP16(0xc60dLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare relative long (32)" }, + { "cgfrl", OP16(0xc60cLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare relative long (64<32)" }, + { "clgrl", OP16(0xc60aLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare logical relative long (64)" }, + { "cgrl", OP16(0xc608LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare relative long (64)" }, + { "clhrl", OP16(0xc607LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare logical relative long (32<16)" }, + { "clghrl", OP16(0xc606LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare logical relative long (64<16)" }, + { "chrl", OP16(0xc605LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare halfword relative long (32<8)" }, + { "cghrl", OP16(0xc604LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "compare halfword relative long (64<8)" }, + { "pfdrl", OP16(0xc602LL), MASK_RIL_UP, INSTR_RIL_UP, 2, 6, 0, "prefetch data relative long" }, + { "exrl", OP16(0xc600LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "execute relative long" }, + { "bprp", OP8(0xc5LL), MASK_MII_UPP, INSTR_MII_UPP, 2, 8, 0, "branch prediction relative preload" }, + { "strl", OP16(0xc40fLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "store relative long (32)" }, + { "llgfrl", OP16(0xc40eLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load logical relative long (64<32)" }, + { "lrl", OP16(0xc40dLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load relative long (32)" }, + { "lgfrl", OP16(0xc40cLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load relative long (64<32)" }, + { "stgrl", OP16(0xc40bLL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "store relative long (64)" }, + { "lgrl", OP16(0xc408LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load relative long (64)" }, + { "sthrl", OP16(0xc407LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "store halfword relative long" }, + { "llghrl", OP16(0xc406LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load logical halfword relative long (64<16)" }, + { "lhrl", OP16(0xc405LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load halfword relative long (32<16)" }, + { "lghrl", OP16(0xc404LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load halfword relative long (64<16)" }, + { "llhrl", OP16(0xc402LL), MASK_RIL_RP, INSTR_RIL_RP, 2, 6, 0, "load logical halfword relative long (32<16)" }, + { "clfi", OP16(0xc20fLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "compare logical immediate 32" }, + { "clgfi", OP16(0xc20eLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "compare logical immediate 64<32" }, + { "cfi", OP16(0xc20dLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4, 0, "compare immediate 32" }, + { "cgfi", OP16(0xc20cLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4, 0, "compare immediate 64<32" }, + { "alfi", OP16(0xc20bLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "add logical immediate 32" }, + { "algfi", OP16(0xc20aLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "add logical immediate 64<32" }, + { "afi", OP16(0xc209LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4, 0, "add immediate 32" }, + { "agfi", OP16(0xc208LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4, 0, "add immediate 64<32" }, + { "slfi", OP16(0xc205LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "subtract logical immediate 32" }, + { "slgfi", OP16(0xc204LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "subtract logical immediate 64<32" }, + { "msfi", OP16(0xc201LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 6, 0, "multiply single immediate (32)" }, + { "msgfi", OP16(0xc200LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 6, 0, "multiply single immediate (64)" }, + { "jg", OP16(0xc0f4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 48, "unconditional jump long" }, + { "brul", OP16(0xc0f4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 48, "unconditional jump long" }, + { "jgno", OP16(0xc0e4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not overflow / if not ones" }, + { "brnol", OP16(0xc0e4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not overflow / if not ones" }, + { "jgnh", OP16(0xc0d4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not high" }, + { "jgnp", OP16(0xc0d4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not plus" }, + { "brnhl", OP16(0xc0d4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not high" }, + { "brnpl", OP16(0xc0d4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not plus" }, + { "jgle", OP16(0xc0c4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on low or equal" }, + { "brlel", OP16(0xc0c4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on low or equal" }, + { "jgnl", OP16(0xc0b4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not low" }, + { "jgnm", OP16(0xc0b4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not minus / if not mixed" }, + { "brnll", OP16(0xc0b4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not low" }, + { "brnml", OP16(0xc0b4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not minus / if not mixed" }, + { "jghe", OP16(0xc0a4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on high or equal" }, + { "brhel", OP16(0xc0a4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on high or equal" }, + { "jgnlh", OP16(0xc094LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not low or high" }, + { "brnlhl", OP16(0xc094LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not low or high" }, + { "jge", OP16(0xc084LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A equal B" }, + { "jgz", OP16(0xc084LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on zero / if zeros" }, + { "brel", OP16(0xc084LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A equal B" }, + { "brzl", OP16(0xc084LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on zero / if zeros" }, + { "jgne", OP16(0xc074LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not equal B" }, + { "jgnz", OP16(0xc074LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not zero / if not zeros" }, + { "brnel", OP16(0xc074LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A not equal B" }, + { "brnzl", OP16(0xc074LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not zero / if not zeros" }, + { "jglh", OP16(0xc064LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on low or high" }, + { "brlhl", OP16(0xc064LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on low or high" }, + { "jgnhe", OP16(0xc054LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not high or equal" }, + { "brnhel", OP16(0xc054LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not high or equal" }, + { "jgl", OP16(0xc044LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A low" }, + { "jgm", OP16(0xc044LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on minus / if mixed" }, + { "brll", OP16(0xc044LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A low" }, + { "brml", OP16(0xc044LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on minus / if mixed" }, + { "jgnle", OP16(0xc034LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not low or equal" }, + { "brnlel", OP16(0xc034LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on not low or equal" }, + { "jgh", OP16(0xc024LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A high" }, + { "jgp", OP16(0xc024LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on plus" }, + { "brhl", OP16(0xc024LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on A high" }, + { "brpl", OP16(0xc024LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on plus" }, + { "jgo", OP16(0xc014LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on overflow / if ones" }, + { "brol", OP16(0xc014LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 112, "conditional jump long on overflow / if ones" }, + { "llilf", OP16(0xc00fLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "load logical immediate low" }, + { "llgfi", OP16(0xc00fLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "load logical immediate" }, + { "llihf", OP16(0xc00eLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "load logical immediate high" }, + { "oilf", OP16(0xc00dLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "or immediate low" }, + { "oihf", OP16(0xc00cLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "or immediate high" }, + { "nilf", OP16(0xc00bLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "and immediate low" }, + { "nihf", OP16(0xc00aLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "and immediate high" }, + { "iilf", OP16(0xc009LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "insert immediate low" }, + { "lfi", OP16(0xc009LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "insert immediate 32" }, + { "iihf", OP16(0xc008LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "insert immediate high" }, + { "xilf", OP16(0xc007LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "exclusive or immediate low" }, + { "xihf", OP16(0xc006LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4, 0, "exclusive or immediate high" }, + { "brasl", OP16(0xc005LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 2, 176, "branch relative and save long" }, + { "jasl", OP16(0xc005LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 2, 176, "branch relative and save long" }, + { "brcl", OP16(0xc004LL), MASK_RIL_UP, INSTR_RIL_UP, 3, 2, 112, "branch relative on condition long" }, + { "jgnop", OP16(0xc004LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2, 0, "nop jump long" }, + { "lgfi", OP16(0xc001LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4, 0, "load immediate 64<32" }, + { "larl", OP16(0xc000LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 2, 0, "load address relative long" }, + { "icm", OP8(0xbfLL), MASK_RS_RURD, INSTR_RS_RURD, 3, 0, 0, "insert characters under mask" }, + { "stcm", OP8(0xbeLL), MASK_RS_RURD, INSTR_RS_RURD, 3, 0, 0, "store characters under mask" }, + { "clm", OP8(0xbdLL), MASK_RS_RURD, INSTR_RS_RURD, 3, 0, 0, "compare logical characters under mask" }, + { "cds", OP8(0xbbLL), MASK_RS_RERERD, INSTR_RS_RERERD, 3, 0, 0, "compare double and swap" }, + { "cs", OP8(0xbaLL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "compare and swap" }, + { "msrkc", OP16(0xb9fdLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 10, 0, "multiply single 32x32 -> 32" }, + { "slrk", OP16(0xb9fbLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract logical 3 operands 32 bit" }, + { "alrk", OP16(0xb9faLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add logical 3 operands 32 bit" }, + { "srk", OP16(0xb9f9LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract 3 operands 32 bit" }, + { "ark", OP16(0xb9f8LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add 3 operands 32 bit" }, + { "xrk", OP16(0xb9f7LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "xor 3 operands 32 bit" }, + { "ork", OP16(0xb9f6LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "or 3 operands 32 bit" }, + { "ncrk", OP16(0xb9f5LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "and with complement 32 bit" }, + { "nrk", OP16(0xb9f4LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "and 3 operands 32 bit" }, + { "locrno", OP32(0xb9f2e000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not overflow / if not ones" }, + { "locrnh", OP32(0xb9f2d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A not high" }, + { "locrnp", OP32(0xb9f2d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not plus" }, + { "locrle", OP32(0xb9f2c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on low or equal" }, + { "locrnl", OP32(0xb9f2b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A not low" }, + { "locrnm", OP32(0xb9f2b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not minus / if not mixed" }, + { "locrhe", OP32(0xb9f2a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on high or equal" }, + { "locrnlh", OP32(0xb9f29000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not low or high" }, + { "locre", OP32(0xb9f28000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A equal B" }, + { "locrz", OP32(0xb9f28000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on zero / if zeros" }, + { "locrne", OP32(0xb9f27000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A not equal B" }, + { "locrnz", OP32(0xb9f27000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not zero / if not zeros" }, + { "locrlh", OP32(0xb9f26000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on low or high" }, + { "locrnhe", OP32(0xb9f25000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not high or equal" }, + { "locrl", OP32(0xb9f24000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A low" }, + { "locrm", OP32(0xb9f24000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on minus / if mixed" }, + { "locrnle", OP32(0xb9f23000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on not low or equal" }, + { "locrh", OP32(0xb9f22000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on A high" }, + { "locrp", OP32(0xb9f22000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on plus" }, + { "locro", OP32(0xb9f21000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 32 bit on overflow / if ones" }, + { "locr", OP16(0xb9f2LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 7, 0, "load on condition 32 bit" }, + { "selrno", OP32(0xb9f00e00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not overflow / if not ones" }, + { "selrnh", OP32(0xb9f00d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A not high" }, + { "selrnp", OP32(0xb9f00d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not plus" }, + { "selrle", OP32(0xb9f00c00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on low or equal" }, + { "selrnl", OP32(0xb9f00b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A not low" }, + { "selrnm", OP32(0xb9f00b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not minus / if not mixed" }, + { "selrhe", OP32(0xb9f00a00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on high or equal" }, + { "selrnlh", OP32(0xb9f00900LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not low or high" }, + { "selre", OP32(0xb9f00800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A equal B" }, + { "selrz", OP32(0xb9f00800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on zero / if zeros" }, + { "selrne", OP32(0xb9f00700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A not equal B" }, + { "selrnz", OP32(0xb9f00700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not zero / if not zeros" }, + { "selrlh", OP32(0xb9f00600LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on low or high" }, + { "selrnhe", OP32(0xb9f00500LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not high or equal" }, + { "selrl", OP32(0xb9f00400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A low" }, + { "selrm", OP32(0xb9f00400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on minus / if mixed" }, + { "selrnle", OP32(0xb9f00300LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on not low or equal" }, + { "selrh", OP32(0xb9f00200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on A high" }, + { "selrp", OP32(0xb9f00200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on plus" }, + { "selro", OP32(0xb9f00100LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 32 bit on overflow / if ones" }, + { "selr", OP16(0xb9f0LL), MASK_RRF_RURR, INSTR_RRF_RURR, 2, 11, 0, "select 32 bit" }, + { "msgrkc", OP16(0xb9edLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 10, 0, "multiply single 64x64 -> 64" }, + { "mgrk", OP16(0xb9ecLL), MASK_RRF_R0RER, INSTR_RRF_R0RER, 2, 10, 0, "multiply 64x64reg -> 128" }, + { "slgrk", OP16(0xb9ebLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract logical 3 operands 64 bit" }, + { "algrk", OP16(0xb9eaLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add logical 3 operands 64 bit" }, + { "sgrk", OP16(0xb9e9LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract 3 operands 64 bit" }, + { "agrk", OP16(0xb9e8LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add 3 operands 64 bit" }, + { "xgrk", OP16(0xb9e7LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "xor 3 operands 64 bit" }, + { "ogrk", OP16(0xb9e6LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "or 3 operands 64 bit" }, + { "ncgrk", OP16(0xb9e5LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "and with complement 64 bit" }, + { "ngrk", OP16(0xb9e4LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "and 3 operands 64 bit" }, + { "selgrno", OP32(0xb9e30e00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not overflow / if not ones" }, + { "selgrnh", OP32(0xb9e30d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A not high" }, + { "selgrnp", OP32(0xb9e30d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not plus" }, + { "selgrle", OP32(0xb9e30c00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on low or equal" }, + { "selgrnl", OP32(0xb9e30b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A not low" }, + { "selgrnm", OP32(0xb9e30b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not minus / if not mixed" }, + { "selgrhe", OP32(0xb9e30a00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on high or equal" }, + { "selgrnlh", OP32(0xb9e30900LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not low or high" }, + { "selgre", OP32(0xb9e30800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A equal B" }, + { "selgrz", OP32(0xb9e30800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on zero / if zeros" }, + { "selgrne", OP32(0xb9e30700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A not equal B" }, + { "selgrnz", OP32(0xb9e30700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not zero / if not zeros" }, + { "selgrlh", OP32(0xb9e30600LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on low or high" }, + { "selgrnhe", OP32(0xb9e30500LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not high or equal" }, + { "selgrl", OP32(0xb9e30400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A low" }, + { "selgrm", OP32(0xb9e30400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on minus / if mixed" }, + { "selgrnle", OP32(0xb9e30300LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on not low or equal" }, + { "selgrh", OP32(0xb9e30200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on A high" }, + { "selgrp", OP32(0xb9e30200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on plus" }, + { "selgro", OP32(0xb9e30100LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select 64 bit on overflow / if ones" }, + { "selgr", OP16(0xb9e3LL), MASK_RRF_RURR, INSTR_RRF_RURR, 2, 11, 0, "select 64 bit" }, + { "locgrno", OP32(0xb9e2e000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not overflow / if not ones" }, + { "locgrnh", OP32(0xb9e2d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A not high" }, + { "locgrnp", OP32(0xb9e2d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not plus" }, + { "locgrle", OP32(0xb9e2c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on low or equal" }, + { "locgrnl", OP32(0xb9e2b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A not low" }, + { "locgrnm", OP32(0xb9e2b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not minus / if not mixed" }, + { "locgrhe", OP32(0xb9e2a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on high or equal" }, + { "locgrnlh", OP32(0xb9e29000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not low or high" }, + { "locgre", OP32(0xb9e28000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A equal B" }, + { "locgrz", OP32(0xb9e28000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on zero / if zeros" }, + { "locgrne", OP32(0xb9e27000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A not equal B" }, + { "locgrnz", OP32(0xb9e27000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not zero / if not zeros" }, + { "locgrlh", OP32(0xb9e26000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on low or high" }, + { "locgrnhe", OP32(0xb9e25000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not high or equal" }, + { "locgrl", OP32(0xb9e24000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A low" }, + { "locgrm", OP32(0xb9e24000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on minus / if mixed" }, + { "locgrnle", OP32(0xb9e23000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on not low or equal" }, + { "locgrh", OP32(0xb9e22000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on A high" }, + { "locgrp", OP32(0xb9e22000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on plus" }, + { "locgro", OP32(0xb9e21000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 7, 0, "load on condition 64 bit on overflow / if ones" }, + { "locgr", OP16(0xb9e2LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 7, 0, "load on condition 64 bit" }, + { "popcnt", OP16(0xb9e1LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 11, 1, "population count arch13" }, + { "popcnt", OP16(0xb9e1LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "population count" }, + { "locfhrno", OP32(0xb9e0e000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not overflow / if not ones" }, + { "locfhrnh", OP32(0xb9e0d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A not high" }, + { "locfhrnp", OP32(0xb9e0d000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not plus" }, + { "locfhrle", OP32(0xb9e0c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on low or equal" }, + { "locfhrnl", OP32(0xb9e0b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A not low" }, + { "locfhrnm", OP32(0xb9e0b000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not minus / if not mixed" }, + { "locfhrhe", OP32(0xb9e0a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on high or equal" }, + { "locfhrnlh", OP32(0xb9e09000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not low or high" }, + { "locfhre", OP32(0xb9e08000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A equal B" }, + { "locfhrz", OP32(0xb9e08000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on zero / if zeros" }, + { "locfhrne", OP32(0xb9e07000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A not equal B" }, + { "locfhrnz", OP32(0xb9e07000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not zero / if not zeros" }, + { "locfhrlh", OP32(0xb9e06000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on low or high" }, + { "locfhrnhe", OP32(0xb9e05000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not high or equal" }, + { "locfhrl", OP32(0xb9e04000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A low" }, + { "locfhrm", OP32(0xb9e04000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on minus / if mixed" }, + { "locfhrnle", OP32(0xb9e03000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on not low or equal" }, + { "locfhrh", OP32(0xb9e02000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on A high" }, + { "locfhrp", OP32(0xb9e02000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on plus" }, + { "locfhro", OP32(0xb9e01000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 9, 0, "load high on condition from gpr on overflow / if ones" }, + { "locfhr", OP16(0xb9e0LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 9, 0, "load high on condition from gpr" }, + { "clhlr", OP16(0xb9dfLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "compare logical high low" }, + { "chlr", OP16(0xb9ddLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "compare high low" }, + { "slhhlr", OP16(0xb9dbLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract logical high low" }, + { "alhhlr", OP16(0xb9daLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add logical high low" }, + { "shhlr", OP16(0xb9d9LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract high low" }, + { "ahhlr", OP16(0xb9d8LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add high low" }, + { "clhhr", OP16(0xb9cfLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "compare logical high high" }, + { "chhr", OP16(0xb9cdLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "compare high high" }, + { "slhhhr", OP16(0xb9cbLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract logical high high" }, + { "alhhhr", OP16(0xb9caLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add logical high high" }, + { "shhhr", OP16(0xb9c9LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "subtract high high" }, + { "ahhhr", OP16(0xb9c8LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 7, 0, "add high high" }, + { "selfhrno", OP32(0xb9c00e00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not overflow / if not ones" }, + { "selfhrnh", OP32(0xb9c00d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A not high" }, + { "selfhrnp", OP32(0xb9c00d00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not plus" }, + { "selfhrle", OP32(0xb9c00c00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on low or equal" }, + { "selfhrnl", OP32(0xb9c00b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A not low" }, + { "selfhrnm", OP32(0xb9c00b00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not minus / if not mixed" }, + { "selfhrhe", OP32(0xb9c00a00LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on high or equal" }, + { "selfhrnlh", OP32(0xb9c00900LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not low or high" }, + { "selfhre", OP32(0xb9c00800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A equal B" }, + { "selfhrz", OP32(0xb9c00800LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on zero / if zeros" }, + { "selfhrne", OP32(0xb9c00700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A not equal B" }, + { "selfhrnz", OP32(0xb9c00700LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not zero / if not zeros" }, + { "selfhrlh", OP32(0xb9c00600LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on low or high" }, + { "selfhrnhe", OP32(0xb9c00500LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not high or equal" }, + { "selfhrl", OP32(0xb9c00400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A low" }, + { "selfhrm", OP32(0xb9c00400LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on minus / if mixed" }, + { "selfhrnle", OP32(0xb9c00300LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on not low or equal" }, + { "selfhrh", OP32(0xb9c00200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on A high" }, + { "selfhrp", OP32(0xb9c00200LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on plus" }, + { "selfhro", OP32(0xb9c00100LL), MASK_RRF_R0RR3, INSTR_RRF_R0RR3, 2, 11, 0, "select high on overflow / if ones" }, + { "selfhr", OP16(0xb9c0LL), MASK_RRF_RURR, INSTR_RRF_RURR, 2, 11, 0, "select high" }, + { "trte", OP16(0xb9bfLL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 2, 6, 1, "translate and test extended" }, + { "srstu", OP16(0xb9beLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "search string unicode" }, + { "trtre", OP16(0xb9bdLL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 2, 6, 1, "translate and test reverse extended" }, + { "cu42", OP16(0xb9b3LL), MASK_RRE_RERE, INSTR_RRE_RERE, 2, 4, 0, "convert utf-32 to utf-16" }, + { "cu41", OP16(0xb9b2LL), MASK_RRE_RERE, INSTR_RRE_RERE, 2, 4, 0, "convert utf-32 to utf-8" }, + { "cu24", OP16(0xb9b1LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert utf-16 to utf-32" }, + { "cu14", OP16(0xb9b0LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert utf-8 to utf-32" }, + { "pfmf", OP16(0xb9afLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "perform frame management function" }, + { "rrbm", OP16(0xb9aeLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "reset reference bits multiple" }, + { "irbm", OP16(0xb9acLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 10, 0, "insert reference bits multiple" }, + { "lptea", OP16(0xb9aaLL), MASK_RRF_RURR2, INSTR_RRF_RURR2, 2, 4, 0, "load page-table-entry address" }, + { "ptf", OP16(0xb9a2LL), MASK_RRE_R0, INSTR_RRE_R0, 2, 6, 0, "perform topology function" }, + { "tpei", OP16(0xb9a1LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 10, 0, "test pending external interruption" }, + { "ssair", OP16(0xb99fLL), MASK_RRE_R0, INSTR_RRE_R0, 3, 3, 0, "set secondary ASN with instance" }, + { "pti", OP16(0xb99eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "program transfer with instance" }, + { "esea", OP16(0xb99dLL), MASK_RRE_R0, INSTR_RRE_R0, 2, 2, 0, "extract and set extended authority" }, + { "esair", OP16(0xb99bLL), MASK_RRE_R0, INSTR_RRE_R0, 3, 3, 0, "extract secondary ASN and instance" }, + { "epair", OP16(0xb99aLL), MASK_RRE_R0, INSTR_RRE_R0, 3, 3, 0, "extract primary ASN and instance" }, + { "slbr", OP16(0xb999LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 2, 0, "subtract logical with borrow 32" }, + { "alcr", OP16(0xb998LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 2, 0, "add logical with carry 32" }, + { "dlr", OP16(0xb997LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 2, 0, "divide logical 32" }, + { "mlr", OP16(0xb996LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 2, 0, "multiply logical 32" }, + { "llhr", OP16(0xb995LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load logical halfword 32" }, + { "llcr", OP16(0xb994LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load logical character 32" }, + { "troo", OP16(0xb993LL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 3, 4, 1, "translate one to one" }, + { "troo", OP16(0xb993LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 0, 0, "translate one to one" }, + { "trot", OP16(0xb992LL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 3, 4, 1, "translate one to two" }, + { "trot", OP16(0xb992LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 0, 0, "translate one to two" }, + { "trto", OP16(0xb991LL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 3, 4, 1, "translate two to one" }, + { "trto", OP16(0xb991LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 0, 0, "translate two to one" }, + { "trtt", OP16(0xb990LL), MASK_RRF_U0RER, INSTR_RRF_U0RER, 3, 4, 1, "translate two to two" }, + { "trtt", OP16(0xb990LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 0, 0, "translate two to two" }, + { "crdte", OP16(0xb98fLL), MASK_RRF_RURR2, INSTR_RRF_RURR2, 2, 8, 1, "compare and replace DAT table entry" }, + { "idte", OP16(0xb98eLL), MASK_RRF_RURR2, INSTR_RRF_RURR2, 2, 3, 1, "invalidate dat table entry" }, + { "epsw", OP16(0xb98dLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 2, 0, "extract psw" }, + { "rdp", OP16(0xb98bLL), MASK_RRF_RURR2, INSTR_RRF_RURR2, 2, 12, 1, "reset dat protection" }, + { "cspg", OP16(0xb98aLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 3, 0, "compare and swap and purge" }, + { "slbgr", OP16(0xb989LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "subtract logical with borrow 64" }, + { "alcgr", OP16(0xb988LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "add logical with carry 64" }, + { "dlgr", OP16(0xb987LL), MASK_RRE_RER, INSTR_RRE_RER, 2, 2, 0, "divide logical 64" }, + { "mlgr", OP16(0xb986LL), MASK_RRE_RER, INSTR_RRE_RER, 2, 2, 0, "multiply logical 64" }, + { "llghr", OP16(0xb985LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load logical halfword 64" }, + { "llgcr", OP16(0xb984LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load logical character 64" }, + { "flogr", OP16(0xb983LL), MASK_RRE_RER, INSTR_RRE_RER, 2, 4, 0, "find leftmost one" }, + { "xgr", OP16(0xb982LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "exclusive or 64" }, + { "ogr", OP16(0xb981LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "or 64" }, + { "ngr", OP16(0xb980LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "and 64" }, + { "nxrk", OP16(0xb977LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "not exclusive or 32 bit" }, + { "nork", OP16(0xb976LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "nor 32 bit" }, + { "notr", OP16(0xb976LL), MASK_RRF_R0RR4, INSTR_RRF_R0RR4, 2, 11, 0, "not 32 bit" }, + { "ocrk", OP16(0xb975LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "or with complement 32 bit" }, + { "nnrk", OP16(0xb974LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "nand 32 bit" }, + { "clrtnh", OP32(0xb973c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A not high" }, + { "clrtle", OP32(0xb973c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on low or equal" }, + { "clrtnl", OP32(0xb973a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A not low" }, + { "clrthe", OP32(0xb973a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on high or equal" }, + { "clrte", OP32(0xb9738000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A equal B" }, + { "clrtnlh", OP32(0xb9738000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on not low or high" }, + { "clrtne", OP32(0xb9736000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A not equal B" }, + { "clrtlh", OP32(0xb9736000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on low or high" }, + { "clrtl", OP32(0xb9734000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A low" }, + { "clrtnhe", OP32(0xb9734000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on not high or equal" }, + { "clrth", OP32(0xb9732000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on A high" }, + { "clrtnle", OP32(0xb9732000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (32) on not low or equal" }, + { "clrt", OP16(0xb973LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 6, 0, "compare logical and trap (32)" }, + { "crtnh", OP32(0xb972c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A not high" }, + { "crtle", OP32(0xb972c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on low or equal" }, + { "crtnl", OP32(0xb972a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A not low" }, + { "crthe", OP32(0xb972a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on high or equal" }, + { "crte", OP32(0xb9728000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A equal B" }, + { "crtnlh", OP32(0xb9728000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on not low or high" }, + { "crtne", OP32(0xb9726000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A not equal B" }, + { "crtlh", OP32(0xb9726000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on low or high" }, + { "crtl", OP32(0xb9724000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A low" }, + { "crtnhe", OP32(0xb9724000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on not high or equal" }, + { "crth", OP32(0xb9722000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on A high" }, + { "crtnle", OP32(0xb9722000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap on not low or equal" }, + { "crt", OP16(0xb972LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 6, 0, "compare and trap" }, + { "bdepg", OP16(0xb96dLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 13, 0, "bit deposit" }, + { "bextg", OP16(0xb96cLL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 13, 0, "bit extract" }, + { "ctzg", OP16(0xb969LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 13, 0, "count trailing zeros" }, + { "clzg", OP16(0xb968LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 13, 0, "count leading zeros" }, + { "nxgrk", OP16(0xb967LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "not exclusive or 64 bit" }, + { "nogrk", OP16(0xb966LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "nor 64 bit" }, + { "notgr", OP16(0xb966LL), MASK_RRF_R0RR4, INSTR_RRF_R0RR4, 2, 11, 0, "not 64 bit" }, + { "ocgrk", OP16(0xb965LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "or with complement 64 bit" }, + { "nngrk", OP16(0xb964LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "nand 64 bit" }, + { "clgrtnh", OP32(0xb961c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A not high" }, + { "clgrtle", OP32(0xb961c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on low or equal" }, + { "clgrtnl", OP32(0xb961a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A not low" }, + { "clgrthe", OP32(0xb961a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on high or equal" }, + { "clgrte", OP32(0xb9618000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A equal B" }, + { "clgrtnlh", OP32(0xb9618000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on not low or high" }, + { "clgrtne", OP32(0xb9616000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A not equal B" }, + { "clgrtlh", OP32(0xb9616000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on low or high" }, + { "clgrtl", OP32(0xb9614000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A low" }, + { "clgrtnhe", OP32(0xb9614000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on not high or equal" }, + { "clgrth", OP32(0xb9612000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on A high" }, + { "clgrtnle", OP32(0xb9612000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare logical and trap (64) on not low or equal" }, + { "clgrt", OP16(0xb961LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 6, 0, "compare logical and trap (64)" }, + { "cgrtnh", OP32(0xb960c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A not high" }, + { "cgrtle", OP32(0xb960c000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on low or equal" }, + { "cgrtnl", OP32(0xb960a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A not low" }, + { "cgrthe", OP32(0xb960a000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on high or equal" }, + { "cgrte", OP32(0xb9608000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A equal B" }, + { "cgrtnlh", OP32(0xb9608000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on not low or high" }, + { "cgrtne", OP32(0xb9606000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A not equal B" }, + { "cgrtlh", OP32(0xb9606000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on low or high" }, + { "cgrtl", OP32(0xb9604000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A low" }, + { "cgrtnhe", OP32(0xb9604000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on not high or equal" }, + { "cgrth", OP32(0xb9602000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on A high" }, + { "cgrtnle", OP32(0xb9602000LL), MASK_RRF_00RR, INSTR_RRF_00RR, 2, 6, 0, "compare and trap 64 on not low or equal" }, + { "cgrt", OP16(0xb960LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 6, 0, "compare and trap 64" }, + { "cxlftr", OP16(0xb95bLL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit fixed logical to extended dfp with rounding mode" }, + { "cxlgtr", OP16(0xb95aLL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 64 bit fixed logical to extended dfp with rounding mode" }, + { "cxftr", OP16(0xb959LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 32 bit fixed to extended dfp with rounding mode" }, + { "cdlftr", OP16(0xb953LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit fixed logical to long dfp with rounding mode" }, + { "cdlgtr", OP16(0xb952LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 64 bit fixed logical to long dfp with rounding mode" }, + { "cdftr", OP16(0xb951LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit fixed to long dfp with rounding mode" }, + { "clfxtr", OP16(0xb94bLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 32 bit fixed logical from extended dfp with rounding mode" }, + { "clgxtr", OP16(0xb94aLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 64 bit fixed logical from extended dfp with rounding mode" }, + { "cfxtr", OP16(0xb949LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed from extended dfp source with rounding mode" }, + { "bctgr", OP16(0xb946LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "branch on count 64" }, + { "clfdtr", OP16(0xb943LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed logical from long dfp with rounding mode" }, + { "clgdtr", OP16(0xb942LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed logical from long dfp with rounding mode" }, + { "cfdtr", OP16(0xb941LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed from long dfp source with rounding mode" }, + { "klmd", OP16(0xb93fLL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 13, 1, "compute last message digest" }, + { "klmd", OP16(0xb93fLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "compute last message digest" }, + { "kimd", OP16(0xb93eLL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 13, 1, "compute intermediate message digest" }, + { "kimd", OP16(0xb93eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "compute intermediate message digest" }, + { "prno", OP16(0xb93cLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 10, 0, "perform random number operation" }, + { "ppno", OP16(0xb93cLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 9, 0, "perform pseudorandom number operation" }, + { "nnpa", OP16(0xb93bLL), MASK_RRE_00, INSTR_RRE_00, 2, 12, 0, "neural network processing assist" }, + { "kdsa", OP16(0xb93aLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 11, 0, "compute digital signature authentication" }, + { "dfltcc", OP16(0xb939LL), MASK_RRF_R0RR2, INSTR_RRF_R0RR2, 2, 11, 0, "deflate conversion call" }, + { "sortl", OP16(0xb938LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 11, 0, "sort lists" }, + { "clgfr", OP16(0xb931LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "compare logical 64<32" }, + { "cgfr", OP16(0xb930LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "compare 64<32" }, + { "kmc", OP16(0xb92fLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "cipher message with chaining" }, + { "km", OP16(0xb92eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "cipher message" }, + { "kmctr", OP16(0xb92dLL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 2, 7, 0, "cipher message with counter" }, + { "pcc", OP16(0xb92cLL), MASK_RRE_00, INSTR_RRE_00, 2, 7, 0, "perform cryptographic computation" }, + { "kmo", OP16(0xb92bLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "cipher message with OFB" }, + { "kmf", OP16(0xb92aLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 7, 0, "cipher message with CFB" }, + { "kma", OP16(0xb929LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 2, 10, 0, "cipher message with galois counter mode" }, + { "pckmo", OP16(0xb928LL), MASK_RRE_00, INSTR_RRE_00, 2, 7, 0, "perform cryptographic key management operation" }, + { "lhr", OP16(0xb927LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load halfword 32" }, + { "lbr", OP16(0xb926LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load byte 32" }, + { "sturg", OP16(0xb925LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "store using real address 64" }, + { "clgr", OP16(0xb921LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "compare logical 64" }, + { "cgr", OP16(0xb920LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "compare 64" }, + { "lrvr", OP16(0xb91fLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 2, 0, "load reversed 32" }, + { "kmac", OP16(0xb91eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 3, 0, "compute message authentication code" }, + { "dsgfr", OP16(0xb91dLL), MASK_RRE_RER, INSTR_RRE_RER, 2, 2, 0, "divide single 64<32" }, + { "msgfr", OP16(0xb91cLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "multiply single 64<32" }, + { "slgfr", OP16(0xb91bLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "subtract logical 64<32" }, + { "algfr", OP16(0xb91aLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "add logical 64<32" }, + { "sgfr", OP16(0xb919LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "subtract 64<32" }, + { "agfr", OP16(0xb918LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "add 64<32" }, + { "llgtr", OP16(0xb917LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load logical thirty one bits" }, + { "llgfr", OP16(0xb916LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load logical 64<32" }, + { "lgfr", OP16(0xb914LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load 64<32" }, + { "lcgfr", OP16(0xb913LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load complement 64<32" }, + { "ltgfr", OP16(0xb912LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load and test 64<32" }, + { "lngfr", OP16(0xb911LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load negative 64<32" }, + { "lpgfr", OP16(0xb910LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load positive 64<32" }, + { "lrvgr", OP16(0xb90fLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load reversed 64" }, + { "eregg", OP16(0xb90eLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "extract stacked registers 64" }, + { "dsgr", OP16(0xb90dLL), MASK_RRE_RER, INSTR_RRE_RER, 2, 2, 0, "divide single 64" }, + { "msgr", OP16(0xb90cLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "multiply single 64" }, + { "slgr", OP16(0xb90bLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "subtract logical 64" }, + { "algr", OP16(0xb90aLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "add logical 64" }, + { "sgr", OP16(0xb909LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "subtract 64" }, + { "agr", OP16(0xb908LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "add 64" }, + { "lghr", OP16(0xb907LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load halfword 64" }, + { "lgbr", OP16(0xb906LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 4, 0, "load byte 64" }, + { "lurag", OP16(0xb905LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load using real address 64" }, + { "lgr", OP16(0xb904LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load 64" }, + { "lcgr", OP16(0xb903LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load complement 64" }, + { "ltgr", OP16(0xb902LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load and test 64" }, + { "lngr", OP16(0xb901LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load negative 64" }, + { "lpgr", OP16(0xb900LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2, 0, "load positive 64" }, + { "lctl", OP8(0xb7LL), MASK_RS_CCRD, INSTR_RS_CCRD, 3, 0, 0, "load control" }, + { "stctl", OP8(0xb6LL), MASK_RS_CCRD, INSTR_RS_CCRD, 3, 0, 0, "store control" }, + { "rrxtr", OP16(0xb3ffLL), MASK_RRF_FEFERU, INSTR_RRF_FEFERU, 2, 5, 0, "Reround extended dfp" }, + { "iextr", OP16(0xb3feLL), MASK_RRF_FE0FER, INSTR_RRF_FE0FER, 2, 5, 0, "insert biased exponent extended dfp" }, + { "qaxtr", OP16(0xb3fdLL), MASK_RRF_FEUFEFE, INSTR_RRF_FEUFEFE, 2, 5, 0, "Quantize extended dfp" }, + { "cextr", OP16(0xb3fcLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 2, 5, 0, "compare exponent extended dfp" }, + { "cxstr", OP16(0xb3fbLL), MASK_RRE_FR, INSTR_RRE_FR, 2, 5, 0, "convert from signed bcd extended dfp" }, + { "cxutr", OP16(0xb3faLL), MASK_RRE_FER, INSTR_RRE_FER, 2, 5, 0, "convert from unsigned bcd to extended dfp" }, + { "cxgtra", OP16(0xb3f9LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from fixed extended dfp with rounding mode" }, + { "cxgtr", OP16(0xb3f9LL), MASK_RRE_FER, INSTR_RRE_FER, 2, 5, 0, "convert from fixed extended dfp" }, + { "rrdtr", OP16(0xb3f7LL), MASK_RRF_FFRU, INSTR_RRF_FFRU, 2, 5, 0, "Reround long dfp" }, + { "iedtr", OP16(0xb3f6LL), MASK_RRF_F0FR, INSTR_RRF_F0FR, 2, 5, 0, "insert biased exponent long dfp" }, + { "qadtr", OP16(0xb3f5LL), MASK_RRF_FUFF, INSTR_RRF_FUFF, 2, 5, 0, "Quantize long dfp" }, + { "cedtr", OP16(0xb3f4LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "compare exponent long dfp" }, + { "cdstr", OP16(0xb3f3LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 5, 0, "convert from signed bcd long dfp" }, + { "cdutr", OP16(0xb3f2LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 5, 0, "convert from unsigned bcd to long dfp" }, + { "cdgtra", OP16(0xb3f1LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from fixed long dfp with rounding mode" }, + { "cdgtr", OP16(0xb3f1LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 5, 0, "convert from fixed long dfp" }, + { "esxtr", OP16(0xb3efLL), MASK_RRE_RFE, INSTR_RRE_RFE, 2, 5, 0, "extract significance from extended dfp" }, + { "eextr", OP16(0xb3edLL), MASK_RRE_RFE, INSTR_RRE_RFE, 2, 5, 0, "extract biased exponent from extended dfp" }, + { "cxtr", OP16(0xb3ecLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 2, 5, 0, "compare extended dfp" }, + { "csxtr", OP16(0xb3ebLL), MASK_RRF_0UREFE, INSTR_RRF_0UREFE, 2, 5, 0, "convert from extended dfp to signed bcd" }, + { "cuxtr", OP16(0xb3eaLL), MASK_RRE_RFE, INSTR_RRE_RFE, 2, 5, 0, "convert from extended dfp to unsigned bcd" }, + { "cgxtra", OP16(0xb3e9LL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 64 bit fixed from extended dfp with rounding mode" }, + { "cgxtr", OP16(0xb3e9LL), MASK_RRF_U0RFE, INSTR_RRF_U0RFE, 2, 5, 0, "convert from extended dfp to fixed" }, + { "kxtr", OP16(0xb3e8LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "compare and signal extended dfp" }, + { "esdtr", OP16(0xb3e7LL), MASK_RRE_RF, INSTR_RRE_RF, 2, 5, 0, "extract significance from long dfp" }, + { "eedtr", OP16(0xb3e5LL), MASK_RRE_RF, INSTR_RRE_RF, 2, 5, 0, "extract biased exponent from long dfp" }, + { "cdtr", OP16(0xb3e4LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "compare long dfp" }, + { "csdtr", OP16(0xb3e3LL), MASK_RRF_0URF, INSTR_RRF_0URF, 2, 5, 0, "convert from long dfp to signed bcd" }, + { "cudtr", OP16(0xb3e2LL), MASK_RRE_RF, INSTR_RRE_RF, 2, 5, 0, "convert from long dfp to unsigned bcd" }, + { "cgdtra", OP16(0xb3e1LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed from long dfp with rounding mode" }, + { "cgdtr", OP16(0xb3e1LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 2, 5, 0, "convert from long dfp to fixed" }, + { "kdtr", OP16(0xb3e0LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "compare and signal long dfp" }, + { "fixtr", OP16(0xb3dfLL), MASK_RRF_UUFEFE, INSTR_RRF_UUFEFE, 2, 5, 0, "load fp integer extended dfp" }, + { "ltxtr", OP16(0xb3deLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 2, 5, 0, "load and test extended dfp" }, + { "ldxtr", OP16(0xb3ddLL), MASK_RRF_UUFFE, INSTR_RRF_UUFFE, 2, 5, 0, "load rounded extended dfp" }, + { "lxdtr", OP16(0xb3dcLL), MASK_RRF_0UFEF, INSTR_RRF_0UFEF, 2, 5, 0, "load lengthened extended dfp" }, + { "sxtra", OP16(0xb3dbLL), MASK_RRF_FEUFEFE2, INSTR_RRF_FEUFEFE2, 2, 7, 0, "subtract extended dfp with rounding mode" }, + { "sxtr", OP16(0xb3dbLL), MASK_RRR_FE0FEFE, INSTR_RRR_FE0FEFE, 2, 5, 0, "subtract extended dfp" }, + { "axtra", OP16(0xb3daLL), MASK_RRF_FEUFEFE2, INSTR_RRF_FEUFEFE2, 2, 7, 0, "add extended dfp with rounding mode" }, + { "axtr", OP16(0xb3daLL), MASK_RRR_FE0FEFE, INSTR_RRR_FE0FEFE, 2, 5, 0, "add extended dfp" }, + { "dxtra", OP16(0xb3d9LL), MASK_RRF_FEUFEFE2, INSTR_RRF_FEUFEFE2, 2, 7, 0, "divide extended dfp with rounding mode" }, + { "dxtr", OP16(0xb3d9LL), MASK_RRR_FE0FEFE, INSTR_RRR_FE0FEFE, 2, 5, 0, "divide extended dfp" }, + { "mxtra", OP16(0xb3d8LL), MASK_RRF_FEUFEFE2, INSTR_RRF_FEUFEFE2, 2, 7, 0, "multiply extended dfp with rounding mode" }, + { "mxtr", OP16(0xb3d8LL), MASK_RRR_FE0FEFE, INSTR_RRR_FE0FEFE, 2, 5, 0, "multiply extended dfp" }, + { "fidtr", OP16(0xb3d7LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 2, 5, 0, "load fp integer long dfp" }, + { "ltdtr", OP16(0xb3d6LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "load and test long dfp" }, + { "ledtr", OP16(0xb3d5LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 2, 5, 0, "load rounded long dfp" }, + { "ldetr", OP16(0xb3d4LL), MASK_RRF_0UFF, INSTR_RRF_0UFF, 2, 5, 0, "load lengthened long dfp" }, + { "sdtra", OP16(0xb3d3LL), MASK_RRF_FUFF2, INSTR_RRF_FUFF2, 2, 7, 0, "subtract long dfp with rounding mode" }, + { "sdtr", OP16(0xb3d3LL), MASK_RRR_F0FF, INSTR_RRR_F0FF, 2, 5, 0, "subtract long dfp" }, + { "adtra", OP16(0xb3d2LL), MASK_RRF_FUFF2, INSTR_RRF_FUFF2, 2, 7, 0, "add long dfp with rounding mode" }, + { "adtr", OP16(0xb3d2LL), MASK_RRR_F0FF, INSTR_RRR_F0FF, 2, 5, 0, "add long dfp" }, + { "ddtra", OP16(0xb3d1LL), MASK_RRF_FUFF2, INSTR_RRF_FUFF2, 2, 7, 0, "divide long dfp with rounding mode" }, + { "ddtr", OP16(0xb3d1LL), MASK_RRR_F0FF, INSTR_RRR_F0FF, 2, 5, 0, "divide long dfp" }, + { "mdtra", OP16(0xb3d0LL), MASK_RRF_FUFF2, INSTR_RRF_FUFF2, 2, 7, 0, "multiply long dfp with rounding mode" }, + { "mdtr", OP16(0xb3d0LL), MASK_RRR_F0FF, INSTR_RRR_F0FF, 2, 5, 0, "multiply long dfp" }, + { "lgdr", OP16(0xb3cdLL), MASK_RRE_RF, INSTR_RRE_RF, 2, 5, 0, "load GR from FPR" }, + { "cgxr", OP16(0xb3caLL), MASK_RRF_U0RFE, INSTR_RRF_U0RFE, 2, 2, 0, "convert to fixed extended hfp to 64" }, + { "cgdr", OP16(0xb3c9LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 2, 2, 0, "convert to fixed long hfp to 64" }, + { "cger", OP16(0xb3c8LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 2, 2, 0, "convert to fixed short hfp to 64" }, + { "cxgr", OP16(0xb3c6LL), MASK_RRE_FER, INSTR_RRE_FER, 2, 2, 0, "convert from fixed 64 to extended hfp" }, + { "cdgr", OP16(0xb3c5LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 2, 0, "convert from fixed 64 to long hfp" }, + { "cegr", OP16(0xb3c4LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 2, 0, "convert from fixed 64 to short hfp" }, + { "ldgr", OP16(0xb3c1LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 5, 0, "load FPR from GR" }, + { "cfxr", OP16(0xb3baLL), MASK_RRF_U0RFE, INSTR_RRF_U0RFE, 3, 0, 0, "convert to fixed extended hfp to 32" }, + { "cfdr", OP16(0xb3b9LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 3, 0, 0, "convert to fixed long hfp to 32" }, + { "cfer", OP16(0xb3b8LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 3, 0, 0, "convert to fixed short hfp to 32" }, + { "cxfr", OP16(0xb3b6LL), MASK_RRE_FER, INSTR_RRE_FER, 3, 0, 0, "convert from fixed 32 to extended hfp" }, + { "cdfr", OP16(0xb3b5LL), MASK_RRE_FR, INSTR_RRE_FR, 3, 0, 0, "convert from fixed 32 to long hfp" }, + { "cefr", OP16(0xb3b4LL), MASK_RRE_FR, INSTR_RRE_FR, 3, 0, 0, "convert from fixed 32 to short hfp" }, + { "clgxbr", OP16(0xb3aeLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 64 bit fixed logical from extended bfp with rounding mode" }, + { "clgdbr", OP16(0xb3adLL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed logical from long bfp with rounding mode" }, + { "clgebr", OP16(0xb3acLL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed logical from short bfp with rounding mode" }, + { "cgxbra", OP16(0xb3aaLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 64 bit fixed from extended bfp with rounding mode" }, + { "cgxbr", OP16(0xb3aaLL), MASK_RRF_U0RFE, INSTR_RRF_U0RFE, 2, 2, 0, "convert to fixed extended bfp to 64" }, + { "cgdbra", OP16(0xb3a9LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed from long bfp with rounding mode" }, + { "cgdbr", OP16(0xb3a9LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 2, 2, 0, "convert to fixed long bfp to 64" }, + { "cgebra", OP16(0xb3a8LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 64 bit fixed from short bfp with rounding mode" }, + { "cgebr", OP16(0xb3a8LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 2, 2, 0, "convert to fixed short bfd to 64" }, + { "cxgbra", OP16(0xb3a6LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 64 bit fixed to extended bfp with rounding mode" }, + { "cxgbr", OP16(0xb3a6LL), MASK_RRE_FER, INSTR_RRE_FER, 2, 2, 0, "convert from fixed 64 to extended bfp" }, + { "cdgbra", OP16(0xb3a5LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 64 bit fixed to long bfp with rounding mode" }, + { "cdgbr", OP16(0xb3a5LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 2, 0, "convert from fixed 64 to long bfp" }, + { "cegbra", OP16(0xb3a4LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 64 bit fixed to short bfp with rounding mode" }, + { "cegbr", OP16(0xb3a4LL), MASK_RRE_FR, INSTR_RRE_FR, 2, 2, 0, "convert from fixed 64 to short bfp" }, + { "cxlgbr", OP16(0xb3a2LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 64 bit logical fixed to extended bfp with rounding mode" }, + { "cdlgbr", OP16(0xb3a1LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 64 bit logical fixed to long bfp with rounding mode" }, + { "celgbr", OP16(0xb3a0LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 64 bit logical fixed to short bfp with rounding mode" }, + { "clfxbr", OP16(0xb39eLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 32 bit fixed logical from extended bfp with rounding mode" }, + { "clfdbr", OP16(0xb39dLL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed logical from long bfp with rounding mode" }, + { "clfebr", OP16(0xb39cLL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed logical from short bfp with rounding mode" }, + { "cfxbra", OP16(0xb39aLL), MASK_RRF_UURFE, INSTR_RRF_UURFE, 2, 7, 0, "convert to 32 bit fixed from extended bfp with rounding mode" }, + { "cfxbr", OP16(0xb39aLL), MASK_RRF_U0RFE, INSTR_RRF_U0RFE, 3, 0, 0, "convert to fixed extended bfp to 32" }, + { "cfdbra", OP16(0xb399LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed from long bfp with rounding mode" }, + { "cfdbr", OP16(0xb399LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 3, 0, 0, "convert to fixed long bfp to 32" }, + { "cfebra", OP16(0xb398LL), MASK_RRF_UURF, INSTR_RRF_UURF, 2, 7, 0, "convert to 32 bit fixed from short bfp with rounding mode" }, + { "cfebr", OP16(0xb398LL), MASK_RRF_U0RF, INSTR_RRF_U0RF, 3, 0, 0, "convert to fixed short bfp to 32" }, + { "cxfbra", OP16(0xb396LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 32 bit fixed to extended bfp with rounding mode" }, + { "cxfbr", OP16(0xb396LL), MASK_RRE_FER, INSTR_RRE_FER, 3, 0, 0, "convert from fixed 32 to extended bfp" }, + { "cdfbra", OP16(0xb395LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit fixed to long bfp with rounding mode" }, + { "cdfbr", OP16(0xb395LL), MASK_RRE_FR, INSTR_RRE_FR, 3, 0, 0, "convert from fixed 32 to long bfp" }, + { "cefbra", OP16(0xb394LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit fixed to short bfp with rounding mode" }, + { "cefbr", OP16(0xb394LL), MASK_RRE_FR, INSTR_RRE_FR, 3, 0, 0, "convert from fixed 32 to short bfp" }, + { "cxlfbr", OP16(0xb392LL), MASK_RRF_UUFER, INSTR_RRF_UUFER, 2, 7, 0, "convert from 32 bit logical fixed to extended bfp with rounding mode" }, + { "cdlfbr", OP16(0xb391LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit logical fixed to long bfp with rounding mode" }, + { "celfbr", OP16(0xb390LL), MASK_RRF_UUFR, INSTR_RRF_UUFR, 2, 7, 0, "convert from 32 bit logical fixed to short bfp with rounding mode" }, + { "efpc", OP16(0xb38cLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 1, "extract fpc" }, + { "sfasr", OP16(0xb385LL), MASK_RRE_R0, INSTR_RRE_R0, 2, 5, 0, "set fpc and signal" }, + { "sfpc", OP16(0xb384LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 1, "set fpc" }, + { "fidr", OP16(0xb37fLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load fp integer long hfp" }, + { "fier", OP16(0xb377LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load fp integer short hfp" }, + { "lzxr", OP16(0xb376LL), MASK_RRE_FE0, INSTR_RRE_FE0, 3, 0, 0, "load extended zero" }, + { "lzdr", OP16(0xb375LL), MASK_RRE_F0, INSTR_RRE_F0, 3, 0, 0, "load long zero" }, + { "lzer", OP16(0xb374LL), MASK_RRE_F0, INSTR_RRE_F0, 3, 0, 0, "load short zero" }, + { "lcdfr", OP16(0xb373LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "load complement no cc" }, + { "cpsdr", OP16(0xb372LL), MASK_RRF_F0FF2, INSTR_RRF_F0FF2, 2, 5, 0, "copy sign" }, + { "lndfr", OP16(0xb371LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "load negative no cc" }, + { "lpdfr", OP16(0xb370LL), MASK_RRE_FF, INSTR_RRE_FF, 2, 5, 0, "load positive no cc" }, + { "cxr", OP16(0xb369LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "compare extended hfp" }, + { "fixr", OP16(0xb367LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load fp integer extended hfp" }, + { "lexr", OP16(0xb366LL), MASK_RRE_FFE, INSTR_RRE_FFE, 3, 0, 0, "load rounded extended to short hfp" }, + { "lxr", OP16(0xb365LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load extended fp" }, + { "lcxr", OP16(0xb363LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load complement extended hfp" }, + { "ltxr", OP16(0xb362LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load and test extended hfp" }, + { "lnxr", OP16(0xb361LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load negative extended hfp" }, + { "lpxr", OP16(0xb360LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load positive extended hfp" }, + { "fidbra", OP16(0xb35fLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 2, 7, 0, "load fp integer long bfp with inexact suppression" }, + { "fidbr", OP16(0xb35fLL), MASK_RRF_U0FF, INSTR_RRF_U0FF, 3, 0, 0, "load fp integer long bfp" }, + { "didbr", OP16(0xb35bLL), MASK_RRF_FUFF, INSTR_RRF_FUFF, 3, 0, 0, "divide to integer long bfp" }, + { "thdr", OP16(0xb359LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "convert long bfp to long hfp" }, + { "thder", OP16(0xb358LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "convert short bfp to long hfp" }, + { "fiebra", OP16(0xb357LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 2, 7, 0, "load fp integer short bfp with inexact suppression" }, + { "fiebr", OP16(0xb357LL), MASK_RRF_U0FF, INSTR_RRF_U0FF, 3, 0, 0, "load fp integer short bfp" }, + { "diebr", OP16(0xb353LL), MASK_RRF_FUFF, INSTR_RRF_FUFF, 3, 0, 0, "divide to integer short bfp" }, + { "tbdr", OP16(0xb351LL), MASK_RRF_U0FF, INSTR_RRF_U0FF, 3, 0, 0, "convert long hfp to long bfp" }, + { "tbedr", OP16(0xb350LL), MASK_RRF_U0FF, INSTR_RRF_U0FF, 3, 0, 0, "convert long hfp to short bfp" }, + { "dxbr", OP16(0xb34dLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "divide extended bfp" }, + { "mxbr", OP16(0xb34cLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "multiply extended bfp" }, + { "sxbr", OP16(0xb34bLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "subtract extended bfp" }, + { "axbr", OP16(0xb34aLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "add extended bfp" }, + { "cxbr", OP16(0xb349LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "compare extended bfp" }, + { "kxbr", OP16(0xb348LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "compare and signal extended bfp" }, + { "fixbra", OP16(0xb347LL), MASK_RRF_UUFEFE, INSTR_RRF_UUFEFE, 2, 7, 0, "load fp integer extended bfp with inexact suppression" }, + { "fixbr", OP16(0xb347LL), MASK_RRF_U0FEFE, INSTR_RRF_U0FEFE, 3, 0, 0, "load fp integer extended bfp" }, + { "lexbra", OP16(0xb346LL), MASK_RRF_UUFEFE, INSTR_RRF_UUFEFE, 2, 7, 0, "load rounded short/extended bfp to short/extended bfp with rounding mode" }, + { "lexbr", OP16(0xb346LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load rounded extended to short bfp" }, + { "ldxbra", OP16(0xb345LL), MASK_RRF_UUFEFE, INSTR_RRF_UUFEFE, 2, 7, 0, "load rounded long/extended bfp to long/extended bfp with rounding mode" }, + { "ldxbr", OP16(0xb345LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load rounded extended to long bfp" }, + { "ledbra", OP16(0xb344LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 2, 7, 0, "load rounded short/long bfp to short/long bfp with rounding mode" }, + { "ledbr", OP16(0xb344LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load rounded long to short bfp" }, + { "lcxbr", OP16(0xb343LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load complement extended bfp" }, + { "ltxbr", OP16(0xb342LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load and test extended bfp" }, + { "lnxbr", OP16(0xb341LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load negative extended bfp" }, + { "lpxbr", OP16(0xb340LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "load positive extended bfp" }, + { "msdr", OP16(0xb33fLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 3, 0, "multiply and subtract long hfp" }, + { "madr", OP16(0xb33eLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 3, 0, "multiply and add long hfp" }, + { "myhr", OP16(0xb33dLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 2, 4, 0, "multiply unnormalized long hfp high" }, + { "mayhr", OP16(0xb33cLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 2, 4, 0, "multiply and add unnormalized long hfp high" }, + { "myr", OP16(0xb33bLL), MASK_RRF_FE0FF, INSTR_RRF_FE0FF, 2, 4, 0, "multiply unnormalized long hfp" }, + { "mayr", OP16(0xb33aLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 2, 4, 0, "multiply and add unnormalized long hfp" }, + { "mylr", OP16(0xb339LL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 2, 4, 0, "multiply unnormalized long hfp low" }, + { "maylr", OP16(0xb338LL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 2, 4, 0, "multiply and add unnormalized long hfp low" }, + { "meer", OP16(0xb337LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "multiply short hfp" }, + { "sqxr", OP16(0xb336LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "square root extended hfp" }, + { "mser", OP16(0xb32fLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 3, 0, "mutliply and subtract short hfp" }, + { "maer", OP16(0xb32eLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 3, 0, "multiply and add short hfp" }, + { "lxer", OP16(0xb326LL), MASK_RRE_FEF, INSTR_RRE_FEF, 3, 0, 0, "load lengthened short to extended hfp" }, + { "lxdr", OP16(0xb325LL), MASK_RRE_FEF, INSTR_RRE_FEF, 3, 0, 0, "load lengthened long to extended hfp" }, + { "lder", OP16(0xb324LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load lengthened short to long hfp" }, + { "msdbr", OP16(0xb31fLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 0, 0, "multiply and subtract long bfp" }, + { "madbr", OP16(0xb31eLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 0, 0, "multiply and add long bfp" }, + { "ddbr", OP16(0xb31dLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "divide long bfp" }, + { "mdbr", OP16(0xb31cLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "multiply long bfp" }, + { "sdbr", OP16(0xb31bLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "subtract long bfp" }, + { "adbr", OP16(0xb31aLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "add long bfp" }, + { "cdbr", OP16(0xb319LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "compare long bfp" }, + { "kdbr", OP16(0xb318LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "compare and signal long bfp" }, + { "meebr", OP16(0xb317LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "multiply short bfp" }, + { "sqxbr", OP16(0xb316LL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "square root extended bfp" }, + { "sqdbr", OP16(0xb315LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "square root long bfp" }, + { "sqebr", OP16(0xb314LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "square root short bfp" }, + { "lcdbr", OP16(0xb313LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load complement long bfp" }, + { "ltdbr", OP16(0xb312LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load and test long bfp" }, + { "lndbr", OP16(0xb311LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load negative long bfp" }, + { "lpdbr", OP16(0xb310LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load positive long bfp" }, + { "msebr", OP16(0xb30fLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 0, 0, "multiply and subtract short bfp" }, + { "maebr", OP16(0xb30eLL), MASK_RRF_F0FF, INSTR_RRF_F0FF, 3, 0, 0, "multiply and add short bfp" }, + { "debr", OP16(0xb30dLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "divide short bfp" }, + { "mdebr", OP16(0xb30cLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "multiply short to long bfp" }, + { "sebr", OP16(0xb30bLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "subtract short bfp" }, + { "aebr", OP16(0xb30aLL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "add short bfp" }, + { "cebr", OP16(0xb309LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "compare short bfp" }, + { "kebr", OP16(0xb308LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "compare and signal short bfp" }, + { "mxdbr", OP16(0xb307LL), MASK_RRE_FEF, INSTR_RRE_FEF, 3, 0, 0, "multiply long to extended bfp" }, + { "lxebr", OP16(0xb306LL), MASK_RRE_FEF, INSTR_RRE_FEF, 3, 0, 0, "load lengthened short to extended bfp" }, + { "lxdbr", OP16(0xb305LL), MASK_RRE_FEF, INSTR_RRE_FEF, 3, 0, 0, "load lengthened long to extended bfp" }, + { "ldebr", OP16(0xb304LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load lengthened short to long bfp" }, + { "lcebr", OP16(0xb303LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load complement short bfp" }, + { "ltebr", OP16(0xb302LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load and test short bfp" }, + { "lnebr", OP16(0xb301LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load negative short bfp" }, + { "lpebr", OP16(0xb300LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "load positive short bfp" }, + { "trap4", OP16(0xb2ffLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "trap4" }, + { "tabort", OP16(0xb2fcLL), MASK_S_RD, INSTR_S_RD, 2, 8, 4, "transaction abort" }, + { "niai", OP16(0xb2faLL), MASK_IE_UU, INSTR_IE_UU, 2, 8, 0, "next instruction access intent" }, + { "tend", OP16(0xb2f8LL), MASK_S_00, INSTR_S_00, 2, 8, 4, "transaction end" }, + { "ecpga", OP16(0xb2edLL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "extract coprocessor-group address" }, + { "etnd", OP16(0xb2ecLL), MASK_RRE_R0, INSTR_RRE_R0, 2, 8, 4, "extract transaction nesting depth" }, + { "ppa", OP16(0xb2e8LL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 8, 4, "perform processor assist" }, + { "epctr", OP16(0xb2e5LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "extract peripheral counter" }, + { "ecctr", OP16(0xb2e4LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "extract cpu counter" }, + { "spctr", OP16(0xb2e1LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "set peripheral counter" }, + { "scctr", OP16(0xb2e0LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 6, 0, "set cpu counter" }, + { "lfas", OP16(0xb2bdLL), MASK_S_RD, INSTR_S_RD, 2, 5, 0, "load fpd and signal" }, + { "srnmt", OP16(0xb2b9LL), MASK_S_RD, INSTR_S_RD, 2, 5, 0, "set rounding mode dfp" }, + { "srnmb", OP16(0xb2b8LL), MASK_S_RD, INSTR_S_RD, 2, 7, 0, "set 3 bit bfp rounding mode" }, + { "lpswe", OP16(0xb2b2LL), MASK_S_RD, INSTR_S_RD, 2, 2, 0, "load psw extended" }, + { "stfl", OP16(0xb2b1LL), MASK_S_RD, INSTR_S_RD, 3, 2, 0, "store facility list" }, + { "stfle", OP16(0xb2b0LL), MASK_S_RD, INSTR_S_RD, 2, 4, 0, "store facility list extended" }, + { "cu12", OP16(0xb2a7LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert utf-8 to utf-16" }, + { "cutfu", OP16(0xb2a7LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert utf-8 to unicode" }, + { "cutfu", OP16(0xb2a7LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "convert utf-8 to unicode" }, + { "cu21", OP16(0xb2a6LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert utf-16 to utf-8" }, + { "cuutf", OP16(0xb2a6LL), MASK_RRF_U0RERE, INSTR_RRF_U0RERE, 2, 4, 1, "convert unicode to utf-8" }, + { "cuutf", OP16(0xb2a6LL), MASK_RRE_RERE, INSTR_RRE_RERE, 3, 0, 0, "convert unicode to utf-8" }, + { "tre", OP16(0xb2a5LL), MASK_RRE_RER, INSTR_RRE_RER, 3, 0, 0, "translate extended" }, + { "lfpc", OP16(0xb29dLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "load fpc" }, + { "stfpc", OP16(0xb29cLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store fpc" }, + { "srnm", OP16(0xb299LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set rounding mode" }, + { "qpaci", OP16(0xb28fLL), MASK_S_RD, INSTR_S_RD, 2, 12, 0, "query processor activity counter information" }, + { "qctri", OP16(0xb28eLL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "query counter information" }, + { "lsctl", OP16(0xb287LL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "load sampling controls" }, + { "qsi", OP16(0xb286LL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "query sampling information" }, + { "lpctl", OP16(0xb285LL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "load peripheral-counter-set controls" }, + { "lcctl", OP16(0xb284LL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "load cpu-counter-set controls" }, + { "lpp", OP16(0xb280LL), MASK_S_RD, INSTR_S_RD, 2, 6, 0, "load program parameter" }, + { "stsi", OP16(0xb27dLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store system information" }, + { "stckf", OP16(0xb27cLL), MASK_S_RD, INSTR_S_RD, 2, 4, 0, "store clock fast" }, + { "sacf", OP16(0xb279LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set address space control fast" }, + { "stcke", OP16(0xb278LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store clock extended" }, + { "rp", OP16(0xb277LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "resume program" }, + { "xsch", OP16(0xb276LL), MASK_S_00, INSTR_S_00, 3, 0, 0, "cancel subchannel" }, + { "siga", OP16(0xb274LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "signal adapter" }, + { "cmpsc", OP16(0xb263LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "compression call" }, + { "srst", OP16(0xb25eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "search string" }, + { "clst", OP16(0xb25dLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "compare logical string" }, + { "bsa", OP16(0xb25aLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "branch and set authority" }, + { "bsg", OP16(0xb258LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "branch in subspace group" }, + { "cuse", OP16(0xb257LL), MASK_RRE_RERE, INSTR_RRE_RERE, 3, 0, 0, "compare until substring equal" }, + { "mvst", OP16(0xb255LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "move string" }, + { "mvpg", OP16(0xb254LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "move page" }, + { "msr", OP16(0xb252LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "multiply single" }, + { "csp", OP16(0xb250LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "compare and swap and purge" }, + { "ear", OP16(0xb24fLL), MASK_RRE_RA, INSTR_RRE_RA, 3, 0, 0, "extract access" }, + { "sar", OP16(0xb24eLL), MASK_RRE_AR, INSTR_RRE_AR, 3, 0, 0, "set access" }, + { "cpya", OP16(0xb24dLL), MASK_RRE_AA, INSTR_RRE_AA, 3, 0, 0, "copy access" }, + { "tar", OP16(0xb24cLL), MASK_RRE_AR, INSTR_RRE_AR, 3, 0, 0, "test access" }, + { "lura", OP16(0xb24bLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "load using real address" }, + { "esta", OP16(0xb24aLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "extract stacked state" }, + { "ereg", OP16(0xb249LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "extract stacked registers" }, + { "palb", OP16(0xb248LL), MASK_RRE_00, INSTR_RRE_00, 3, 0, 0, "purge ALB" }, + { "msta", OP16(0xb247LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "modify stacked state" }, + { "stura", OP16(0xb246LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "store using real address" }, + { "sqer", OP16(0xb245LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "square root (short)" }, + { "sqdr", OP16(0xb244LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0, 0, "square root (long)" }, + { "cksm", OP16(0xb241LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "checksum" }, + { "bakr", OP16(0xb240LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "branch and stack" }, + { "schm", OP16(0xb23cLL), MASK_S_00, INSTR_S_00, 3, 0, 0, "set channel monitor" }, + { "rchp", OP16(0xb23bLL), MASK_S_00, INSTR_S_00, 3, 0, 0, "reset channel path" }, + { "stcps", OP16(0xb23aLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store channel path status" }, + { "stcrw", OP16(0xb239LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store channel report word" }, + { "rsch", OP16(0xb238LL), MASK_S_00, INSTR_S_00, 3, 0, 0, "resume subchannel" }, + { "sal", OP16(0xb237LL), MASK_S_00, INSTR_S_00, 3, 0, 0, "set address limit" }, + { "tpi", OP16(0xb236LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "test pending interruption" }, + { "tsch", OP16(0xb235LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "test subchannel" }, + { "stsch", OP16(0xb234LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store subchannel" }, + { "ssch", OP16(0xb233LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "start subchannel" }, + { "msch", OP16(0xb232LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "modify subchannel" }, + { "hsch", OP16(0xb231LL), MASK_S_00, INSTR_S_00, 3, 0, 0, "halt subchannel" }, + { "csch", OP16(0xb230LL), MASK_S_00, INSTR_S_00, 3, 0, 0, "clear subchannel" }, + { "pgout", OP16(0xb22fLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "page out" }, + { "pgin", OP16(0xb22eLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "page in" }, + { "dxr", OP16(0xb22dLL), MASK_RRE_FEFE, INSTR_RRE_FEFE, 3, 0, 0, "divide (ext.)" }, + { "tb", OP16(0xb22cLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "test block" }, + { "sske", OP16(0xb22bLL), MASK_RRF_U0RR, INSTR_RRF_U0RR, 2, 4, 1, "set storage key extended" }, + { "sske", OP16(0xb22bLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "set storage key extended" }, + { "rrbe", OP16(0xb22aLL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "reset reference bit extended" }, + { "iske", OP16(0xb229LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "insert storage key extended" }, + { "pt", OP16(0xb228LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "program transfer" }, + { "esar", OP16(0xb227LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "extract secondary ASN" }, + { "epar", OP16(0xb226LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "extract primary ASN" }, + { "ssar", OP16(0xb225LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "set secondary ASN" }, + { "iac", OP16(0xb224LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "insert address space control" }, + { "ivsk", OP16(0xb223LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, "insert virtual storage key" }, + { "ipm", OP16(0xb222LL), MASK_RRE_R0, INSTR_RRE_R0, 3, 0, 0, "insert program mask" }, + { "ipte", OP16(0xb221LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 2, "invalidate page table entry" }, + { "cfc", OP16(0xb21aLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "compare and form codeword" }, + { "sac", OP16(0xb219LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set address space control" }, + { "pc", OP16(0xb218LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "program call" }, + { "sie", OP16(0xb214LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "start interpretive execution" }, + { "stap", OP16(0xb212LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store CPU address" }, + { "stpx", OP16(0xb211LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store prefix" }, + { "spx", OP16(0xb210LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set prefix" }, + { "ptlb", OP16(0xb20dLL), MASK_S_00, INSTR_S_00, 3, 0, 0, "purge TLB" }, + { "ipk", OP16(0xb20bLL), MASK_S_00, INSTR_S_00, 3, 0, 0, "insert PSW key" }, + { "spka", OP16(0xb20aLL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set PSW key from address" }, + { "stpt", OP16(0xb209LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store CPU timer" }, + { "spt", OP16(0xb208LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set CPU timer" }, + { "stckc", OP16(0xb207LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store clock comparator" }, + { "sckc", OP16(0xb206LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set clock comparator" }, + { "stck", OP16(0xb205LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store clock" }, + { "sck", OP16(0xb204LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "set clock" }, + { "stidp", OP16(0xb202LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, "store CPU id" }, + { "stbear", OP16(0xb201LL), MASK_S_RD, INSTR_S_RD, 2, 12, 0, "store bear" }, + { "lbear", OP16(0xb200LL), MASK_S_RD, INSTR_S_RD, 2, 12, 0, "load bear" }, + { "lra", OP8(0xb1LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "load real address" }, + { "mc", OP16(0xaf00LL), MASK_SI_URD, INSTR_SI_URD, 2, 6, 0, "monitor call" }, + { "mc", OP8(0xafLL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "monitor call" }, + { "sigp", OP8(0xaeLL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "signal processor" }, + { "stosm", OP8(0xadLL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "store then or system mask" }, + { "stnsm", OP8(0xacLL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "store then and system mask" }, + { "clcle", OP8(0xa9LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "compare logical long extended" }, + { "mvcle", OP8(0xa8LL), MASK_RS_RERERD, INSTR_RS_RERERD, 3, 0, 0, "move long extended" }, + { "j", OP16(0xa7f4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 48, "unconditional jump" }, + { "bru", OP16(0xa7f4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 48, "unconditional jump" }, + { "jno", OP16(0xa7e4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not overflow / if not ones" }, + { "brno", OP16(0xa7e4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not overflow / if not ones" }, + { "jnh", OP16(0xa7d4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not high" }, + { "jnp", OP16(0xa7d4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not plus" }, + { "brnh", OP16(0xa7d4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not high" }, + { "brnp", OP16(0xa7d4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not plus" }, + { "jle", OP16(0xa7c4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on low or equal" }, + { "brle", OP16(0xa7c4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on low or equal" }, + { "jnl", OP16(0xa7b4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not low" }, + { "jnm", OP16(0xa7b4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not minus / if not mixed" }, + { "brnl", OP16(0xa7b4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not low" }, + { "brnm", OP16(0xa7b4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not minus / if not mixed" }, + { "jhe", OP16(0xa7a4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on high or equal" }, + { "brhe", OP16(0xa7a4LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on high or equal" }, + { "jnlh", OP16(0xa794LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not low or high" }, + { "brnlh", OP16(0xa794LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not low or high" }, + { "je", OP16(0xa784LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A equal B" }, + { "jz", OP16(0xa784LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on zero / if zeros" }, + { "bre", OP16(0xa784LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A equal B" }, + { "brz", OP16(0xa784LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on zero / if zeros" }, + { "jne", OP16(0xa774LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not equal B" }, + { "jnz", OP16(0xa774LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not zero / if not zeros" }, + { "brne", OP16(0xa774LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A not equal B" }, + { "brnz", OP16(0xa774LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not zero / if not zeros" }, + { "jlh", OP16(0xa764LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on low or high" }, + { "brlh", OP16(0xa764LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on low or high" }, + { "jnhe", OP16(0xa754LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not high or equal" }, + { "brnhe", OP16(0xa754LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not high or equal" }, + { "jl", OP16(0xa744LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A low" }, + { "jm", OP16(0xa744LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on minus / if mixed" }, + { "brl", OP16(0xa744LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A low" }, + { "brm", OP16(0xa744LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on minus / if mixed" }, + { "jnle", OP16(0xa734LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not low or equal" }, + { "brnle", OP16(0xa734LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on not low or equal" }, + { "jh", OP16(0xa724LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A high" }, + { "jp", OP16(0xa724LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on plus" }, + { "brh", OP16(0xa724LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on A high" }, + { "brp", OP16(0xa724LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on plus" }, + { "jo", OP16(0xa714LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on overflow / if ones" }, + { "bro", OP16(0xa714LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 112, "conditional jump on overflow / if ones" }, + { "cghi", OP16(0xa70fLL), MASK_RI_RI, INSTR_RI_RI, 2, 2, 0, "compare halfword immediate 64" }, + { "chi", OP16(0xa70eLL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, "compare halfword immediate" }, + { "mghi", OP16(0xa70dLL), MASK_RI_RI, INSTR_RI_RI, 2, 2, 0, "multiply halfword immediate 64" }, + { "mhi", OP16(0xa70cLL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, "multiply halfword immediate" }, + { "aghi", OP16(0xa70bLL), MASK_RI_RI, INSTR_RI_RI, 2, 2, 0, "add halfword immediate 64" }, + { "ahi", OP16(0xa70aLL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, "add halfword immediate" }, + { "lghi", OP16(0xa709LL), MASK_RI_RI, INSTR_RI_RI, 2, 2, 0, "load halfword immediate 64" }, + { "lhi", OP16(0xa708LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, "load halfword immediate" }, + { "brctg", OP16(0xa707LL), MASK_RI_RP, INSTR_RI_RP, 2, 2, 112, "branch relative on count 64" }, + { "jctg", OP16(0xa707LL), MASK_RI_RP, INSTR_RI_RP, 2, 2, 112, "branch relative on count 64" }, + { "brct", OP16(0xa706LL), MASK_RI_RP, INSTR_RI_RP, 3, 0, 112, "branch relative on count" }, + { "jct", OP16(0xa706LL), MASK_RI_RP, INSTR_RI_RP, 3, 0, 112, "branch relative on count" }, + { "bras", OP16(0xa705LL), MASK_RI_RP, INSTR_RI_RP, 3, 0, 176, "branch relative and save" }, + { "jas", OP16(0xa705LL), MASK_RI_RP, INSTR_RI_RP, 3, 0, 176, "branch relative and save" }, + { "brc", OP16(0xa704LL), MASK_RI_UP, INSTR_RI_UP, 3, 0, 112, "branch relative on condition" }, + { "jc", OP16(0xa704LL), MASK_RI_UP, INSTR_RI_UP, 3, 0, 112, "conditional jump" }, + { "jnop", OP16(0xa704LL), MASK_RI_0P, INSTR_RI_0P, 3, 0, 0, "nop jump" }, + { "tmhl", OP16(0xa703LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "test under mask high low" }, + { "tmhh", OP16(0xa702LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "test under mask high high" }, + { "tmll", OP16(0xa701LL), MASK_RI_RU, INSTR_RI_RU, 3, 0, 0, "test under mask low low" }, + { "tml", OP16(0xa701LL), MASK_RI_RU, INSTR_RI_RU, 3, 0, 0, "test under mask low" }, + { "tmlh", OP16(0xa700LL), MASK_RI_RU, INSTR_RI_RU, 3, 0, 0, "test under mask low high" }, + { "tmh", OP16(0xa700LL), MASK_RI_RU, INSTR_RI_RU, 3, 0, 0, "test under mask high" }, + { "llill", OP16(0xa50fLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "load logical immediate low low" }, + { "llghi", OP16(0xa50fLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "load logical immediate" }, + { "llilh", OP16(0xa50eLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "load logical immediate low high" }, + { "llihl", OP16(0xa50dLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "load logical immediate high low" }, + { "llihh", OP16(0xa50cLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "load logical immediate high high" }, + { "oill", OP16(0xa50bLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "or immediate low low" }, + { "oilh", OP16(0xa50aLL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "or immediate low high" }, + { "oihl", OP16(0xa509LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "or immediate high low" }, + { "oihh", OP16(0xa508LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "or immediate high high" }, + { "nill", OP16(0xa507LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "and immediate low low" }, + { "nilh", OP16(0xa506LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "and immediate low high" }, + { "nihl", OP16(0xa505LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "and immediate high low" }, + { "nihh", OP16(0xa504LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "and immediate high high" }, + { "iill", OP16(0xa503LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "insert immediate low low" }, + { "iilh", OP16(0xa502LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "insert immediate low high" }, + { "iihl", OP16(0xa501LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "insert immediate high low" }, + { "iihh", OP16(0xa500LL), MASK_RI_RU, INSTR_RI_RU, 2, 2, 0, "insert immediate high high" }, + { "stam", OP8(0x9bLL), MASK_RS_AARD, INSTR_RS_AARD, 3, 0, 0, "store access multiple" }, + { "lam", OP8(0x9aLL), MASK_RS_AARD, INSTR_RS_AARD, 3, 0, 0, "load access multiple" }, + { "trace", OP8(0x99LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "trace" }, + { "lm", OP8(0x98LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "load multiple" }, + { "xi", OP8(0x97LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "exclusive or" }, + { "oi", OP8(0x96LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "or" }, + { "cli", OP8(0x95LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "compare logical" }, + { "ni", OP8(0x94LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "and" }, + { "ts", OP8(0x93LL), MASK_SI_RD, INSTR_SI_RD, 3, 0, 0, "test and set" }, + { "mvi", OP8(0x92LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "move" }, + { "tm", OP8(0x91LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, "test under mask" }, + { "stm", OP8(0x90LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "store multiple" }, + { "slda", OP8(0x8fLL), MASK_RS_RE0RD, INSTR_RS_RE0RD, 3, 0, 0, "shift left double (long)" }, + { "srda", OP8(0x8eLL), MASK_RS_RE0RD, INSTR_RS_RE0RD, 3, 0, 0, "shift right double (long)" }, + { "sldl", OP8(0x8dLL), MASK_RS_RE0RD, INSTR_RS_RE0RD, 3, 0, 0, "shift left double logical (long)" }, + { "srdl", OP8(0x8cLL), MASK_RS_RE0RD, INSTR_RS_RE0RD, 3, 0, 0, "shift right double logical (long)" }, + { "sla", OP8(0x8bLL), MASK_RS_R0RD, INSTR_RS_R0RD, 3, 0, 0, "shift left single" }, + { "sra", OP8(0x8aLL), MASK_RS_R0RD, INSTR_RS_R0RD, 3, 0, 0, "shift right single" }, + { "sll", OP8(0x89LL), MASK_RS_R0RD, INSTR_RS_R0RD, 3, 0, 0, "shift left single logical" }, + { "srl", OP8(0x88LL), MASK_RS_R0RD, INSTR_RS_R0RD, 3, 0, 0, "shift right single logical" }, + { "bxle", OP8(0x87LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "branch on index low or equal" }, + { "bxh", OP8(0x86LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "branch on index high" }, + { "brxle", OP8(0x85LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 112, "branch relative on index low or equal" }, + { "jxle", OP8(0x85LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 112, "branch relative on index low or equal" }, + { "brxh", OP8(0x84LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 112, "branch relative on index high" }, + { "jxh", OP8(0x84LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 112, "branch relative on index high" }, + { "diag", OP8(0x83LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, "diagnose" }, + { "lpsw", OP8(0x82LL), MASK_SI_RD, INSTR_SI_RD, 3, 0, 0, "load PSW" }, + { "ssm", OP8(0x80LL), MASK_SI_RD, INSTR_SI_RD, 3, 0, 0, "set system mask" }, + { "su", OP8(0x7fLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "subtract unnormalized (short)" }, + { "au", OP8(0x7eLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "add unnormalized (short)" }, + { "de", OP8(0x7dLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "divide (short)" }, + { "mde", OP8(0x7cLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "multiply (short to long)" }, + { "me", OP8(0x7cLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "multiply (short to long)" }, + { "se", OP8(0x7bLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "subtract normalized (short)" }, + { "ae", OP8(0x7aLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "add normalized (short)" }, + { "ce", OP8(0x79LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "compare (short)" }, + { "le", OP8(0x78LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "load (short)" }, + { "ms", OP8(0x71LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "multiply single" }, + { "ste", OP8(0x70LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "store (short)" }, + { "sw", OP8(0x6fLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "subtract unnormalized (long)" }, + { "aw", OP8(0x6eLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "add unnormalized (long)" }, + { "dd", OP8(0x6dLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "divide (long)" }, + { "md", OP8(0x6cLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "multiply (long)" }, + { "sd", OP8(0x6bLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "subtract normalized (long)" }, + { "ad", OP8(0x6aLL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "add normalized (long)" }, + { "cd", OP8(0x69LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "compare (long)" }, + { "ld", OP8(0x68LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "load (long)" }, + { "mxd", OP8(0x67LL), MASK_RX_FERRD, INSTR_RX_FERRD, 3, 0, 0, "multiply (long to ext.)" }, + { "std", OP8(0x60LL), MASK_RX_FRRD, INSTR_RX_FRRD, 3, 0, 0, "store (long)" }, + { "sl", OP8(0x5fLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "subtract logical" }, + { "al", OP8(0x5eLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "add logical" }, + { "d", OP8(0x5dLL), MASK_RX_RERRD, INSTR_RX_RERRD, 3, 0, 0, "divide" }, + { "m", OP8(0x5cLL), MASK_RX_RERRD, INSTR_RX_RERRD, 3, 0, 0, "multiply" }, + { "s", OP8(0x5bLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "subtract" }, + { "a", OP8(0x5aLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "add" }, + { "c", OP8(0x59LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "compare" }, + { "l", OP8(0x58LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "load" }, + { "x", OP8(0x57LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "exclusive or" }, + { "o", OP8(0x56LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "or" }, + { "cl", OP8(0x55LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "compare logical" }, + { "n", OP8(0x54LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "and" }, + { "lae", OP8(0x51LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "load address extended" }, + { "st", OP8(0x50LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "store" }, + { "cvb", OP8(0x4fLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "convert to binary" }, + { "cvd", OP8(0x4eLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "convert to decimal" }, + { "bas", OP8(0x4dLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "branch and save" }, + { "mh", OP8(0x4cLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "multiply halfword" }, + { "sh", OP8(0x4bLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "subtract halfword" }, + { "ah", OP8(0x4aLL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "add halfword" }, + { "ch", OP8(0x49LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "compare halfword" }, + { "lh", OP8(0x48LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "load halfword" }, + { "b", OP16(0x47f0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "unconditional branch" }, + { "bno", OP16(0x47e0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not overflow / if not ones" }, + { "bnh", OP16(0x47d0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A not high" }, + { "bnp", OP16(0x47d0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not plus" }, + { "ble", OP16(0x47c0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on low or equal" }, + { "bnl", OP16(0x47b0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A not low" }, + { "bnm", OP16(0x47b0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not minus / if not mixed" }, + { "bhe", OP16(0x47a0LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on high or equal" }, + { "bnlh", OP16(0x4790LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not low or high" }, + { "be", OP16(0x4780LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A equal B" }, + { "bz", OP16(0x4780LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on zero / if zeros" }, + { "bne", OP16(0x4770LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A not equal B" }, + { "bnz", OP16(0x4770LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not zero / if not zeros" }, + { "blh", OP16(0x4760LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on low or high" }, + { "bnhe", OP16(0x4750LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not high or equal" }, + { "bl", OP16(0x4740LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A low" }, + { "bm", OP16(0x4740LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on minus / if mixed" }, + { "bnle", OP16(0x4730LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on not low or equal" }, + { "bh", OP16(0x4720LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on A high" }, + { "bp", OP16(0x4720LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on plus" }, + { "bo", OP16(0x4710LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 0, "conditional branch on overflow / if ones" }, + { "bc", OP8(0x47LL), MASK_RX_URRD, INSTR_RX_URRD, 3, 0, 0, "branch on condition" }, + { "nop", OP16(0x4700LL), MASK_RX_0RRD, INSTR_RX_0RRD, 3, 0, 1, "no operation" }, + { "bct", OP8(0x46LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "branch on count" }, + { "bal", OP8(0x45LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "branch and link" }, + { "ex", OP8(0x44LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "execute" }, + { "ic", OP8(0x43LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "insert character" }, + { "stc", OP8(0x42LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "store character" }, + { "la", OP8(0x41LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "load address" }, + { "sth", OP8(0x40LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, "store halfword" }, + { "sur", OP8(0x3fLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "subtract unnormalized (short)" }, + { "aur", OP8(0x3eLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "add unnormalized (short)" }, + { "der", OP8(0x3dLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "divide (short)" }, + { "mder", OP8(0x3cLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "multiply short to long hfp" }, + { "mer", OP8(0x3cLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "multiply (short to long)" }, + { "ser", OP8(0x3bLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "subtract normalized (short)" }, + { "aer", OP8(0x3aLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "add normalized (short)" }, + { "cer", OP8(0x39LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "compare (short)" }, + { "ler", OP8(0x38LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load (short)" }, + { "sxr", OP8(0x37LL), MASK_RR_FEFE, INSTR_RR_FEFE, 3, 0, 0, "subtract normalized (ext.)" }, + { "axr", OP8(0x36LL), MASK_RR_FEFE, INSTR_RR_FEFE, 3, 0, 0, "add normalized" }, + { "ledr", OP8(0x35LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load rounded (long to short)" }, + { "lrer", OP8(0x35LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load rounded (long to short)" }, + { "her", OP8(0x34LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "halve (short)" }, + { "lcer", OP8(0x33LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load complement (short)" }, + { "lter", OP8(0x32LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load and test (short)" }, + { "lner", OP8(0x31LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load negative (short)" }, + { "lper", OP8(0x30LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load positive (short)" }, + { "swr", OP8(0x2fLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "subtract unnormalized (long)" }, + { "awr", OP8(0x2eLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "add unnormalized (long)" }, + { "ddr", OP8(0x2dLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "divide (long)" }, + { "mdr", OP8(0x2cLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "multiply (long)" }, + { "sdr", OP8(0x2bLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "subtract normalized (long)" }, + { "adr", OP8(0x2aLL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "add normalized (long)" }, + { "cdr", OP8(0x29LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "compare (long)" }, + { "ldr", OP8(0x28LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load (long)" }, + { "mxdr", OP8(0x27LL), MASK_RR_FEF, INSTR_RR_FEF, 3, 0, 0, "multiply (long to ext.)" }, + { "mxr", OP8(0x26LL), MASK_RR_FEFE, INSTR_RR_FEFE, 3, 0, 0, "multiply (ext.)" }, + { "ldxr", OP8(0x25LL), MASK_RR_FFE, INSTR_RR_FFE, 3, 0, 0, "load rounded (ext. to long)" }, + { "lrdr", OP8(0x25LL), MASK_RR_FFE, INSTR_RR_FFE, 3, 0, 0, "load rounded (ext. to long)" }, + { "hdr", OP8(0x24LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "halve (long)" }, + { "lcdr", OP8(0x23LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load complement (long)" }, + { "ltdr", OP8(0x22LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load and test (long)" }, + { "lndr", OP8(0x21LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load negative (long)" }, + { "lpdr", OP8(0x20LL), MASK_RR_FF, INSTR_RR_FF, 3, 0, 0, "load positive (long)" }, + { "slr", OP8(0x1fLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "subtract logical" }, + { "alr", OP8(0x1eLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "add logical" }, + { "dr", OP8(0x1dLL), MASK_RR_RER, INSTR_RR_RER, 3, 0, 0, "divide" }, + { "mr", OP8(0x1cLL), MASK_RR_RER, INSTR_RR_RER, 3, 0, 0, "multiply" }, + { "sr", OP8(0x1bLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "subtract" }, + { "ar", OP8(0x1aLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "add" }, + { "cr", OP8(0x19LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "compare" }, + { "lr", OP8(0x18LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "load" }, + { "xr", OP8(0x17LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "exclusive or" }, + { "or", OP8(0x16LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "or" }, + { "clr", OP8(0x15LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "compare logical" }, + { "nr", OP8(0x14LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "and" }, + { "lcr", OP8(0x13LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "load complement" }, + { "ltr", OP8(0x12LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "load and test" }, + { "lnr", OP8(0x11LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "load negative" }, + { "lpr", OP8(0x10LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "load positive" }, + { "clcl", OP8(0x0fLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "compare logical long" }, + { "mvcl", OP8(0x0eLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "move long" }, + { "basr", OP8(0x0dLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "branch and save" }, + { "bassm", OP8(0x0cLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "branch and save and set mode" }, + { "bsm", OP8(0x0bLL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "branch and set mode" }, + { "svc", OP8(0x0aLL), MASK_RR_U0, INSTR_RR_U0, 3, 0, 0, "supervisor call" }, + { "br", OP16(0x07f0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "unconditional branch" }, + { "bnor", OP16(0x07e0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not overflow / if not ones" }, + { "bnhr", OP16(0x07d0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A not high" }, + { "bnpr", OP16(0x07d0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not plus" }, + { "bler", OP16(0x07c0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on low or equal" }, + { "bnlr", OP16(0x07b0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A not low" }, + { "bnmr", OP16(0x07b0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not minus / if not mixed" }, + { "bher", OP16(0x07a0LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on high or equal" }, + { "bnlhr", OP16(0x0790LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not low or high" }, + { "ber", OP16(0x0780LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A equal B" }, + { "bzr", OP16(0x0780LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on zero / if zeros" }, + { "bner", OP16(0x0770LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A not equal B" }, + { "bnzr", OP16(0x0770LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not zero / if not zeros" }, + { "blhr", OP16(0x0760LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on low or high" }, + { "bnher", OP16(0x0750LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not high or equal" }, + { "blr", OP16(0x0740LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A low" }, + { "bmr", OP16(0x0740LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on minus / if mixed" }, + { "bnler", OP16(0x0730LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on not low or equal" }, + { "bhr", OP16(0x0720LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on A high" }, + { "bpr", OP16(0x0720LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on plus" }, + { "bor", OP16(0x0710LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 0, "conditional branch on overflow / if ones" }, + { "bcr", OP8(0x07LL), MASK_RR_UR, INSTR_RR_UR, 3, 0, 0, "branch on condition" }, + { "nopr", OP16(0x0700LL), MASK_RR_0R, INSTR_RR_0R, 3, 0, 1, "no operation" }, + { "bctr", OP8(0x06LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "branch on count" }, + { "balr", OP8(0x05LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, "branch and link" }, + { "spm", OP8(0x04LL), MASK_RR_R0, INSTR_RR_R0, 3, 0, 0, "set program mask" }, + { "trap2", OP16(0x01ffLL), MASK_E, INSTR_E, 3, 0, 0, "trap" }, + { "sam64", OP16(0x010eLL), MASK_E, INSTR_E, 2, 2, 0, "set addressing mode 64" }, + { "sam31", OP16(0x010dLL), MASK_E, INSTR_E, 3, 2, 0, "set addressing mode 31" }, + { "sam24", OP16(0x010cLL), MASK_E, INSTR_E, 3, 2, 0, "set addressing mode 24" }, + { "tam", OP16(0x010bLL), MASK_E, INSTR_E, 3, 2, 0, "test addressing mode" }, + { "pfpo", OP16(0x010aLL), MASK_E, INSTR_E, 2, 5, 0, "perform floating point operation" }, + { "sckpf", OP16(0x0107LL), MASK_E, INSTR_E, 3, 0, 0, "set clock programmable field" }, + { "ptff", OP16(0x0104LL), MASK_E, INSTR_E, 2, 4, 0, "perform timing facility function" }, + { "upt", OP16(0x0102LL), MASK_E, INSTR_E, 3, 0, 0, "update tree" }, + { "pr", OP16(0x0101LL), MASK_E, INSTR_E, 3, 0, 0, "program return" } +}; + +const int s390_num_opcodes = + sizeof (s390_opcodes) / sizeof (s390_opcodes[0]); diff --git a/VEX/priv/objdump/s390.h b/VEX/priv/objdump/s390.h new file mode 100644 index 0000000000..c0a396fc94 --- /dev/null +++ b/VEX/priv/objdump/s390.h @@ -0,0 +1,197 @@ +/* s390.h -- Header file for S390 opcode table + Copyright (C) 2000-2025 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of BFD, the Binary File Descriptor library. + + 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 3 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. */ + +#ifndef S390_H +#define S390_H + +/* List of instruction sets variations. */ + +enum s390_opcode_mode_val + { + S390_OPCODE_ESA = 0, + S390_OPCODE_ZARCH + }; + +enum s390_opcode_cpu_val + { + S390_OPCODE_G5 = 0, + S390_OPCODE_G6, + S390_OPCODE_Z900, + S390_OPCODE_Z990, + S390_OPCODE_Z9_109, + S390_OPCODE_Z9_EC, + S390_OPCODE_Z10, + S390_OPCODE_Z196, + S390_OPCODE_ZEC12, + S390_OPCODE_Z13, + S390_OPCODE_ARCH12, + S390_OPCODE_ARCH13, + S390_OPCODE_ARCH14, + S390_OPCODE_ARCH15, + S390_OPCODE_MAXCPU + }; + +/* Values defined for the flags field of a struct s390_opcode. */ + +/* Last one or two instruction operands are optional. */ +#define S390_INSTR_FLAG_OPTPARM 0x1 +#define S390_INSTR_FLAG_OPTPARM2 0x2 + +/* Instruction requires a specific facility. */ +#define S390_INSTR_FLAG_HTM 0x4 +#define S390_INSTR_FLAG_VX 0x8 +#define S390_INSTR_FLAG_FACILITY_MASK 0xc + +/* Instruction annotations for jump visualization. */ +#define S390_INSTR_FLAG_CLASS_BRANCH 0x10 +#define S390_INSTR_FLAG_CLASS_RELATIVE 0x20 +#define S390_INSTR_FLAG_CLASS_CONDITIONAL 0x40 +#define S390_INSTR_FLAG_CLASS_SUBROUTINE 0x80 +#define S390_INSTR_FLAG_CLASS_MASK 0xf0 + +#define S390_INSTR_FLAGS_CLASS_JUMP \ + (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE) + +#define S390_INSTR_FLAGS_CLASS_CONDJUMP \ + (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE \ + | S390_INSTR_FLAG_CLASS_CONDITIONAL) + +#define S390_INSTR_FLAGS_CLASS_JUMPSR \ + (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE \ + | S390_INSTR_FLAG_CLASS_SUBROUTINE) + +/* Instruction is an .insn pseudo-mnemonic. */ +#define S390_INSTR_FLAG_PSEUDO_MNEMONIC 0x100 + +/* The opcode table is an array of struct s390_opcode. */ + +struct s390_opcode + { + /* The opcode name (mnemonic). */ + const char * name; + + /* The opcode itself. Those bits which will be filled in with + operands are zeroes. */ + unsigned char opcode[6]; + + /* The opcode mask. This is used by the disassembler. This is a + mask containing ones indicating those bits which must match the + opcode field, and zeroes indicating those bits which need not + match (and are presumably filled in by operands). */ + unsigned char mask[6]; + + /* The opcode length in bytes. */ + int oplen; + + /* An array of operand codes. Each code is an index into the + operand table. They appear in the order which the operands must + appear in assembly code, and are terminated by a zero. */ + unsigned char operands[6]; + + /* Bitmask of execution modes this opcode is available for. */ + unsigned int modes; + + /* First cpu this opcode is available for. */ + enum s390_opcode_cpu_val min_cpu; + + /* Instruction specific flags. */ + unsigned int flags; + + /* Instruction description. */ + const char * description; + }; + +/* The table itself is sorted by major opcode number, and is otherwise + in the order in which the disassembler should consider + instructions. */ +extern const struct s390_opcode s390_opcodes[]; +extern const int s390_num_opcodes; + +/* A opcode format table for the .insn pseudo mnemonic. */ +extern const struct s390_opcode s390_opformats[]; +extern const int s390_num_opformats; + +/* The operands table is an array of struct s390_operand. */ + +struct s390_operand + { + /* The number of bits in the operand. */ + int bits; + + /* How far the operand is left shifted in the instruction. */ + int shift; + + /* One bit syntax flags. */ + unsigned long flags; + }; + +/* Elements in the table are retrieved by indexing with values from + the operands field of the s390_opcodes table. */ + +extern const struct s390_operand s390_operands[]; + +/* Values defined for the flags field of a struct s390_operand. */ + +/* This operand names a register. The disassembler uses this to print + register names with a leading 'r'. */ +#define S390_OPERAND_GPR 0x1 + +/* This operand names a floating point register. The disassembler + prints these with a leading 'f'. */ +#define S390_OPERAND_FPR 0x2 + +/* This operand names an access register. The disassembler + prints these with a leading 'a'. */ +#define S390_OPERAND_AR 0x4 + +/* This operand names a control register. The disassembler + prints these with a leading 'c'. */ +#define S390_OPERAND_CR 0x8 + +/* This operand is a displacement. */ +#define S390_OPERAND_DISP 0x10 + +/* This operand names a base register. */ +#define S390_OPERAND_BASE 0x20 + +/* This operand names an index register, it can be skipped. */ +#define S390_OPERAND_INDEX 0x40 + +/* This operand is a relative branch displacement. The disassembler + prints these symbolically if possible. */ +#define S390_OPERAND_PCREL 0x80 + +/* This operand takes signed values. */ +#define S390_OPERAND_SIGNED 0x100 + +/* This operand is a length. */ +#define S390_OPERAND_LENGTH 0x200 + +/* The operand needs to be a valid GP or FP register pair. */ +#define S390_OPERAND_REG_PAIR 0x400 + +/* This operand names a vector register. The disassembler uses this + to print register names with a leading 'v'. */ +#define S390_OPERAND_VR 0x800 + +#define S390_OPERAND_CP16 0x1000 + +#endif /* S390_H */ diff --git a/VEX/priv/objdump/stubs.h b/VEX/priv/objdump/stubs.h new file mode 100644 index 0000000000..0b71c6908f --- /dev/null +++ b/VEX/priv/objdump/stubs.h @@ -0,0 +1,49 @@ +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __VEX_STUBS_H +#define __VEX_STUBS_H + +/* This file contains things that need to be defined to get the + objdump stuff compiled and to avoid pulling in more header files. */ + +#define bool _Bool +#define true 1 +#define false 0 + +typedef unsigned char bfd_byte; // uint8_t originally +typedef unsigned long long bfd_vma; // uint64_t originally +typedef unsigned long size_t; + +#define ATTRIBUTE_FPTR_PRINTF_2 \ + __attribute__ ((__format__ (__printf__, 2, 3))) \ + __attribute__ ((__nonnull__ (2))); +#define ATTRIBUTE_FPTR_PRINTF_3 \ + __attribute__ ((__format__ (__printf__, 3, 4))) \ + __attribute__ ((__nonnull__ (3))) +#define ATTRIBUTE_UNUSED __attribute__ ((unused)) + +/* This is defined in VEX, too. But we want to avoid mixing VEX + and binutils headers. */ +#ifndef NULL +#define NULL ((void *)0) +#endif + +#endif // __VEX_STUBS_H diff --git a/VEX/priv/s390_disasm.c b/VEX/priv/s390_disasm.c deleted file mode 100644 index d2325e7ca4..0000000000 --- a/VEX/priv/s390_disasm.c +++ /dev/null @@ -1,1267 +0,0 @@ -/* -*- mode: C; c-basic-offset: 3; -*- */ - -/*---------------------------------------------------------------*/ -/*--- begin s390_disasm.c ---*/ -/*---------------------------------------------------------------*/ - -/* - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright IBM Corp. 2010-2017 - - 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 3 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, see . - - The GNU General Public License is contained in the file COPYING. -*/ - -/* Contributed by Florian Krohm */ - -#include "libvex_basictypes.h" -#include "main_util.h" // vassert -#include "main_globals.h" // vex_traceflags -#include "s390_defs.h" // S390_MAX_MNEMONIC_LEN -#include "s390_disasm.h" - -static HChar *s390_disasm_aux(const s390_opnd *, const HChar *, HChar *, - Int (*)(UInt, UInt, UInt *)); - -/* Return the mnemonic padded with blanks to its right */ -static const HChar * -padmnm(const HChar *mnm) -{ - vassert(vex_strlen(mnm) <= S390_MAX_MNEMONIC_LEN); - - static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; - - vex_sprintf(buf, "%-*s", S390_MAX_MNEMONIC_LEN, mnm); - - return buf; -} - - -/* Return the name of a general purpose register for dis-assembly purposes. */ -static const HChar * -gpr_operand(UInt archreg) -{ - static const HChar names[16][5] = { - "%r0", "%r1", "%r2", "%r3", - "%r4", "%r5", "%r6", "%r7", - "%r8", "%r9", "%r10", "%r11", - "%r12", "%r13", "%r14", "%r15", - }; - - vassert(archreg < 16); - - return names[archreg]; -} - - -/* Return the name of a floating point register for dis-assembly purposes. */ -static const HChar * -fpr_operand(UInt archreg) -{ - static const HChar names[16][5] = { - "%f0", "%f1", "%f2", "%f3", - "%f4", "%f5", "%f6", "%f7", - "%f8", "%f9", "%f10", "%f11", - "%f12", "%f13", "%f14", "%f15", - }; - - vassert(archreg < 16); - - return names[archreg]; -} - - -/* Return the name of an access register for dis-assembly purposes. */ -static const HChar * -ar_operand(UInt archreg) -{ - static const HChar names[16][5] = { - "%a0", "%a1", "%a2", "%a3", - "%a4", "%a5", "%a6", "%a7", - "%a8", "%a9", "%a10", "%a11", - "%a12", "%a13", "%a14", "%a15", - }; - - vassert(archreg < 16); - - return names[archreg]; -} - - -/* Return the name of a vector register for dis-assembly purposes. */ -static const HChar * -vr_operand(UInt archreg) -{ - static const HChar names[32][5] = { - "%v0", "%v1", "%v2", "%v3", - "%v4", "%v5", "%v6", "%v7", - "%v8", "%v9", "%v10", "%v11", - "%v12", "%v13", "%v14", "%v15", - "%v16", "%v17", "%v18", "%v19", - "%v20", "%v21", "%v22", "%v23", - "%v24", "%v25", "%v26", "%v27", - "%v28", "%v29", "%v30", "%v31", - }; - - vassert(archreg < 32); - - return names[archreg]; -} - - -/* Common function used to construct a mnemonic based on a condition code - mask. */ -static const HChar * -construct_mnemonic(const HChar *prefix, const HChar *suffix, UInt mask) -{ - static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; - - static HChar mask_id[16][4] = { - "", /* 0 -> unused */ - "o", "h", "nle", "l", "nhe", "lh", "ne", - "e", "nlh", "he", "nl", "le", "nh", "no", - "" /* 15 -> unused */ - }; - - /* Guard against buffer overflow */ - vassert(vex_strlen(prefix) + vex_strlen(suffix) + - sizeof mask_id[0] <= sizeof buf); - - HChar *p = buf; - - p += vex_sprintf(p, "%s%s%s", prefix, mask_id[mask], suffix); - *p = '\0'; - - return buf; -} - - -/* An operand with a base register, an index register, and a displacement. - If the displacement is signed, the rightmost 20 bit of D need to be - sign extended */ -static HChar * -dxb_operand(HChar *p, UInt d, UInt x, UInt b, Bool displacement_is_signed) -{ - if (displacement_is_signed) { - Int displ = (Int)(d << 12) >> 12; /* sign extend */ - - p += vex_sprintf(p, "%d", displ); - } else { - p += vex_sprintf(p, "%u", d); - } - if (x != 0) { - p += vex_sprintf(p, "(%s,%s)", gpr_operand(x), - b != 0 ? gpr_operand(b) : "0"); - } else { - if (b != 0) { - p += vex_sprintf(p, "(%s)", gpr_operand(b)); - } - } - - return p; -} - - -/* An operand with base register, unsigned length, and a 12-bit - unsigned displacement */ -static HChar * -udlb_operand(HChar *p, UInt d, UInt length, UInt b) -{ - p += vex_sprintf(p, "%u", d); - p += vex_sprintf(p, "(%u", length + 1); // actual length is +1 - p += vex_sprintf(p, ",%s", b != 0 ? gpr_operand(b) : "0"); - p += vex_sprintf(p, ")"); - - return p; -} - - -/* An operand with a base register, an vector register, and a displacement. - If the displacement is signed, the rightmost 20 bit of D need to be - sign extended */ -static HChar * -dvb_operand(HChar *p, UInt d, UInt v, UInt b, Bool displacement_is_signed) -{ - if (displacement_is_signed) { - Int displ = (Int)(d << 12) >> 12; /* sign extend */ - - p += vex_sprintf(p, "%d", displ); - } else { - p += vex_sprintf(p, "%u", d); - } - p += vex_sprintf(p, "(%s", vr_operand(v)); - p += vex_sprintf(p, ",%s", b != 0 ? gpr_operand(b) : "0"); - p += vex_sprintf(p, ")"); - - return p; -} - - -/* Return the number of MASK operands */ -static UInt -mask_count(const s390_opnd *opnds) -{ - UInt num_masks = 0; - - for (UInt ix = 0; opnds[ix].kind != S390_OPND_DONE; ++ix) { - if (opnds[ix].kind == S390_OPND_MASK) { - ++num_masks; - } - } - return num_masks; -} - - -/* Given the mask number return its index in the operands array. - Mask numbers begin at 1. */ -static UInt -get_mask_index(const s390_opnd *opnds, UInt mask_no) -{ - vassert(mask_no <= mask_count(opnds)); - - UInt count = 0; - - for (UInt ix = 0; opnds[ix].kind != S390_OPND_DONE; ++ix) { - if (opnds[ix].kind == S390_OPND_MASK) { - ++count; - if (count == mask_no) - return ix; - } - } - /* not reachable */ - return 0; -} - - -/* It is expected that OPNDS contains exactly one MASK operand. Return - its index. Assert, if there is no mask or multiple mask fields. */ -static UInt -unique_mask_index(const s390_opnd *opnds) -{ - vassert(mask_count(opnds) == 1); - - return get_mask_index(opnds, 1); -} - - -/* Special handling for the BCR opcode */ -HChar * -bcr_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *xmnm; - UInt mask = opnds[1].mask; - - if (mask == 0) - xmnm = "nopr"; - else if (mask == 15) - xmnm = "br"; - else - xmnm = construct_mnemonic("b", "r", mask); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Special handling for the BC opcode */ -HChar * -bc_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *xmnm; - UInt mask = opnds[1].mask; - - if (mask == 0) { - xmnm = "nop"; - if (opnds[2].d == 0 && opnds[2].b == 0 && opnds[2].x == 0) - return p += vex_sprintf(p, "nop"); - } else if (mask == 15) - xmnm = "b"; - else - xmnm = construct_mnemonic("b", "", mask); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Special handling for the BRC opcode */ -HChar * -brc_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *xmnm; - UInt mask = opnds[1].mask; - - if (mask == 0) - xmnm = "jnop"; - else if (mask == 15) - xmnm = "j"; - else - xmnm = construct_mnemonic("j", "", mask); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Special handling for the BRCL opcode */ -HChar * -brcl_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *xmnm; - UInt mask = opnds[1].mask; - - if (mask == 0) - xmnm = "jgnop"; - else if (mask == 15) - xmnm = "jg"; - else - xmnm = construct_mnemonic("jg", "", mask); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Return 1, if mask should be printed. In *VALUE return the mask value - that should be printed. */ -static Int -cabt_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - return (mask & 1) || mask == 0 || mask == 14; -} - - -/* Special handling for the various compare and branch / trap opcodes: - CLFIT, CLGIT, C[G]IT, C[L][G]RJ, C[L][G]IJ, C[L][G]IB, C[L][G]RB, - CL[G]T, C[L][G]RT -*/ -HChar * -cabt_disasm(const s390_opnd *opnds, HChar *p) -{ - static HChar xmnm[S390_MAX_MNEMONIC_LEN + 1]; - - static const HChar suffix[8][3] = { - "", "h", "l", "ne", "e", "nl", "nh", "" - }; - - const HChar *base = opnds[0].xmnm.base; - - /* Guard against buffer overflow */ - vassert(vex_strlen(base) + sizeof suffix[0] <= sizeof xmnm); - - HChar *x = xmnm; - UInt mask = opnds[unique_mask_index(opnds)].mask; - - x += vex_sprintf(x, "%s", base); - if (! (mask & 0x1)) { - x += vex_sprintf(x, "%s", suffix[mask >> 1]); - } - *x = '\0'; - - return s390_disasm_aux(opnds, xmnm, p, cabt_mh); -} - - -static Int -cls_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - return mask == 0 || mask == 15; -} - - -/* Special handling for the various conditional load / store opcodes: - LOC[G]R, LOCFHR, LOC[G]HI, LOCHHI, LOC[G], LOCFH, STOC[G], STOFH - Also used for SEL[G]R and SELFHR -*/ -HChar * -cls_disasm(const s390_opnd *opnds, HChar *p) -{ - UInt mask = opnds[unique_mask_index(opnds)].mask; - const HChar *base = opnds[0].xmnm.base; - const HChar *xmnm = construct_mnemonic(base, "", mask); - - return s390_disasm_aux(opnds, xmnm, p, cls_mh); -} - - -static Int -bic_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - return mask == 0; -} - - -/* Special handling for the BIC opcode */ -HChar * -bic_disasm(const s390_opnd *opnds, HChar *p) -{ - UInt mask = opnds[1].mask; - const HChar *xmnm; - - if (mask == 0) { - /* There is no special opcode when mask == 0. */ - xmnm = opnds[0].xmnm.base; - } else { - xmnm = construct_mnemonic("bi", "", mask); - } - - return s390_disasm_aux(opnds, xmnm, p, bic_mh); -} - - -/* Special handling for the VGBM opcode */ -HChar * -vgbm_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *xmnm; - const HChar *v1 = vr_operand(opnds[1].regno); - UInt i2 = opnds[2].u; - - if (i2 == 0) { - xmnm = padmnm("vzero"); - p += vex_sprintf(p, "%s %s", xmnm, v1); - } else if (i2 == 0xffff) { - xmnm = padmnm("vone"); - p += vex_sprintf(p, "%s %s", xmnm, v1); - } else { - xmnm = padmnm(opnds[0].xmnm.base); - p += vex_sprintf(p, "%s %s,%u", xmnm, v1, i2); - } - return p; -} - - -static Int -mask0_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - return mask != 0; -} - - -/* Write out the operands, except if the unique mask is 0 do not write it */ -HChar * -mask0_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 1); - - const HChar *mnm = opnds[0].xmnm.base; - - if (vex_streq(mnm, "cu12") && opnds[unique_mask_index(opnds)].mask == 0) - mnm = "cutfu"; - if (vex_streq(mnm, "cu21") && opnds[unique_mask_index(opnds)].mask == 0) - mnm = "cuutf"; - - return s390_disasm_aux(opnds, mnm, p, mask0_mh); -} - - -/* Opcode is expected to have a single MASK operand. Use its value - to determine a single-character suffix to be appended to the base - mnemonic. The mask itself is not printed. */ -HChar * -va_like_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar suffix[] = { 'b', 'h', 'f', 'g', 'q' }; - const HChar *base = opnds[0].xmnm.base; - UInt mask = opnds[unique_mask_index(opnds)].mask; - HChar xmnm[vex_strlen(base) + 2 + 1]; - HChar extra = '\0'; - - vassert(mask < sizeof suffix); - - if (mask == 1 && - (vex_streq(base, "vupl") || vex_streq(base, "vmal") || - vex_streq(base, "vml"))) { - extra = 'w'; - } - vex_sprintf(xmnm, "%s%c%c", base, suffix[mask], extra); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Opcode is expected to have two MASK operands. Use their values - to determine a suffix to be appended to the base mnemonic. The - masks themselves are not printed. */ -HChar * -vch_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix1[] = { 'b', 'h', 'f', 'g' }; - const HChar suffix2[] = { '\0', 's' }; - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt m5 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + 2 + 1]; - - vassert(m4 < sizeof suffix1); - vassert(m5 < sizeof suffix2); - - vex_sprintf(xmnm, "%s%c%c", base, suffix1[m4], suffix2[m5]); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -static Int -always_mh(UInt ix __attribute__((unused)), - UInt mask, UInt *value) -{ - *value = mask; - return 1; -} - - -static Int -never_mh(UInt ix __attribute__((unused)), - UInt mask, UInt *value) -{ - *value = mask; - return 0; -} - - -HChar * -vfce_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 3); - - const HChar suffix1[][3] = { "sb", "db", "xb" }; - const HChar suffix2[] = { '\0', 's' }; - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt m5 = opnds[get_mask_index(opnds, 2)].mask; - UInt m6 = opnds[get_mask_index(opnds, 3)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix1 - 1) + 1 + 1]; - - if (m4 == 4 && (m5 == 0 || m5 == 4)) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m4 - 2 < sizeof suffix1 / sizeof *suffix1); - vassert(m6 < sizeof suffix2); - - vex_sprintf(xmnm, "%s%s%c", base, suffix1[m4 - 2], suffix2[m6]); - - if (m5 & 0x8) xmnm[0] = 'w'; - if (m5 & 0x4) xmnm[2] = 'k'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -HChar * -vfmix_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt m5 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - if (m4 == 4 && m5 == 0) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m4 - 2 < sizeof suffix / sizeof *suffix); - - vex_sprintf(xmnm, "%s%s", base, suffix[m4 - 2]); - - if (m5 & 0x8) xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -HChar * -vfa_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt m5 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - if (m4 == 4 && m5 == 0) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m4 - 2 < sizeof suffix / sizeof *suffix); - - vex_sprintf(xmnm, "%s%s", base, suffix[m4 - 2]); - - if (m5 & 0x8) xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -/* Also used for VFEE, VFENE, and VSTRS. But for those opcodes m5 < 8. - Hence, the return value is 0 and no mask will be written for - those opcodes. */ -static Int -vfae_mh(UInt ix, UInt mask, UInt *value) -{ - *value = mask & 0xC; - return (ix == 5) && (mask & 0xC); -} - - -HChar * -vfae_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[] = { 'b', 'h', 'f' }; - const HChar *base = opnds[0].xmnm.base; - - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt m5 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + 3 + 1]; - - HChar s = (m5 & 0x1) ? 's' : '\0'; - HChar z = (m5 & 0x2) ? 'z' : '\0'; - - vex_sprintf(xmnm, "%s%c%c%c", base, z, suffix[m4], s); - - return s390_disasm_aux(opnds, xmnm, p, vfae_mh); -} - - -HChar * -vfms_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m5 = opnds[get_mask_index(opnds, 1)].mask; - UInt m6 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - if (m6 == 4 && m5 == 0) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m6 - 2 < sizeof suffix / sizeof *suffix); - - vex_sprintf(xmnm, "%s%s", base, suffix[m6 - 2]); - - if (m5 & 0x8) xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -static Int -vmsl_mh(UInt ix, UInt mask, UInt *value) -{ - *value = mask; - return ix == 6; -} - - -HChar * -vmsl_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[] = { 'g' }; - const HChar *base = opnds[0].xmnm.base; - UInt m5 = opnds[get_mask_index(opnds, 1)].mask; - /* m6 does not influence the extended mnemonic */ - HChar xmnm[vex_strlen(base) + 1 + 1]; - - vassert(m5 - 3 < sizeof suffix); - - vex_sprintf(xmnm, "%s%c", base, suffix[m5 - 3]); - - return s390_disasm_aux(opnds, xmnm, p, vmsl_mh); -} - - -static Int -vstrc_mh(UInt ix, UInt mask, UInt *value) -{ - *value = mask & 0xC; - return (ix == 6) && (mask & 0xC); -} - - -HChar * -vstrc_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[] = { 'b', 'h', 'f' }; - const HChar *base = opnds[0].xmnm.base; - - UInt m5 = opnds[get_mask_index(opnds, 1)].mask; - UInt m6 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + 3 + 1]; - - HChar s = (m6 & 0x1) ? 's' : '\0'; - HChar z = (m6 & 0x2) ? 'z' : '\0'; - - vex_sprintf(xmnm, "%s%c%c%c", base, z, suffix[m5], s); - - return s390_disasm_aux(opnds, xmnm, p, vstrc_mh); -} - - -HChar * -vllebrz_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 1); - - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - const HChar *xmnm; - - switch (m3) { - case 1: xmnm = "vllebrzh"; break; - case 2: xmnm = "vllebrzf"; break; - case 3: xmnm = "ldrv"; break; - case 6: xmnm = "lerv"; break; - default: vassert(0); - } - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -HChar * -vstebrf_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 1); - - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - const HChar *xmnm; - - if (m3 == 0) - xmnm = "sterv"; - else - xmnm = opnds[0].xmnm.base; - - return s390_disasm_aux(opnds, xmnm, p, mask0_mh); -} - - -HChar * -vstebrg_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 1); - - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - const HChar *xmnm; - - if (m3 == 0) - xmnm = "stdrv"; - else - xmnm = opnds[0].xmnm.base; - - return s390_disasm_aux(opnds, xmnm, p, mask0_mh); -} - - -HChar * -vllez_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 1); - - const HChar suffix[][3] = { "b", "h", "f", "g", "", "", "lf" }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - vassert(m3 < sizeof suffix / sizeof *suffix); - vex_sprintf(xmnm, "%s%s", base, suffix[m3]); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -HChar * -wfc_like_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - vassert(m3 - 2 < sizeof suffix / sizeof *suffix); - - vex_sprintf(xmnm, "%s%s", base, suffix[m3 - 2]); - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -HChar * -vfll_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[] = { 's', 'd' }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + 1 + 1]; - - if (m3 == 3 && m4 == 0) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m3 - 2 < sizeof suffix); - vex_sprintf(xmnm, "%s%c", base, suffix[m3 - 2]); - - if (m4 == 8) - xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -static Int -always_m4(UInt ix, UInt mask, UInt *value) -{ - *value = mask & 0x4; - return ix == 4; -} - - -HChar * -vflr_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[] = { 'd', 'x' }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + 1 + 1]; - - if (m3 == 4 && m4 < 8) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m3 - 3 < sizeof suffix); - vex_sprintf(xmnm, "%s%c", base, suffix[m3 - 3]); - - if (m4 & 0x8) - xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, always_m4); -} - - -HChar * -vfi_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar suffix[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; - - if (m3 == 4 && m4 < 8) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(m3 - 2 < sizeof suffix / sizeof *suffix); - vex_sprintf(xmnm, "%s%s", base, suffix[m3 - 2]); - - if (m4 & 0x8) - xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, always_m4); -} - - -HChar * -vfpso_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 3); - - const HChar suffix1[] = { 'c', 'n', 'p' }; - const HChar suffix2[][3] = { "sb", "db", "xb" }; - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - UInt m5 = opnds[get_mask_index(opnds, 3)].mask; - HChar xmnm[vex_strlen(base) + 1 + (sizeof *suffix2 - 1) + 1]; - - if (m3 == 4 && m4 == 0) - return s390_disasm_aux(opnds, base, p, always_mh); - - vassert(vex_strlen("vfl") <= vex_strlen(base)); - vassert(m5 < sizeof suffix1); - vassert(m3 - 2 < sizeof suffix2 / sizeof *suffix2); - vex_sprintf(xmnm, "%s%c%s", "vfl", suffix1[m5], suffix2[m3 - 2]); - - if (m4 & 0x8) - xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, NULL); -} - - -static Int -vcgd_mh(UInt ix, UInt mask, UInt *value) -{ - *value = mask; - if (ix == 5) - return 1; - if (ix == 4) { - if (mask >= 8) - *value = mask - 8; - return 1; - } - return 0; -} - - -static HChar * -vcgd_like_disasm(const s390_opnd *opnds, const HChar *mnm[2], HChar *p) -{ - vassert(mask_count(opnds) == 3); - vassert(vex_strlen(mnm[0]) == vex_strlen(mnm[1])); - - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - HChar xmnm[vex_strlen(mnm[0]) + 1]; - - vex_sprintf(xmnm, "%s", mnm[m3 - 2]); - if (m4 & 0x8) - xmnm[0] = 'w'; - - return s390_disasm_aux(opnds, xmnm, p, vcgd_mh); -} - - -HChar * -vcgd_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *mnm[2] = { "vcfeb", "vcgdb" }; - - return vcgd_like_disasm(opnds, mnm, p); -} - - -HChar * -vcdg_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *mnm[2] = { "vcefb", "vcdgb" }; - - return vcgd_like_disasm(opnds, mnm, p); -} - - -HChar * -vclgd_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *mnm[2] = { "vclfeb", "vclgdb" }; - - return vcgd_like_disasm(opnds, mnm, p); -} - - -HChar * -vcgld_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *mnm[2] = { "vcelfb", "vcdlgb" }; - - return vcgd_like_disasm(opnds, mnm, p); -} - - -/* Used by BFP / DFP convert from fixed / logical opcodes - - 1) Mnemonics ending in 'A', e.g. CEFBRA - a) m3 == m4 == 0 --> CEFBR and no mask values written - b) otherwise --> CEFBRA and both mask values written - - 2) Mnemonics for "logical" opcodes, e.g. CELFBR - These do not end in 'A' - --> mnemonic unchanged, both mask values written - - 3) Neither #1 nor #2, e.g. CDFTR - --> mnemonic unchanged, both mask values written -*/ -HChar * -fp_convf_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar *base = opnds[0].xmnm.base; - UInt m3 = opnds[get_mask_index(opnds, 1)].mask; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - UInt len = vex_strlen(base); - - HChar xmnm[len + 1]; - - vex_sprintf(xmnm, "%s", base); - - if (xmnm[len - 1] == 'a' && m3 + m4 == 0) { - xmnm[len - 1] = '\0'; - return s390_disasm_aux(opnds, xmnm, p, never_mh); - } - return s390_disasm_aux(opnds, xmnm, p, always_mh); -} - - -/* Return 1, if mask should be printed. In *VALUE return the mask value - that should be printed. */ -static Int -fp_convt_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - return (ix == 2 || mask != 0) ? 1 : 0; -} - - -/* Used by BFP / DFP convert to fixed / logical opcodes - - 1) Mnemonics ending in 'A', e.g. CFEBRA - a) m4 == 0 --> CFEBR and no mask values written - b) otherwise --> CFEBRA and both mask values written - - 2) Mnemonics for "logical" opcodes, e.g. CLFEBR - These do not end in 'A' - --> mnemonic unchanged, both mask values written - - 3) Neither #1 nor #2, e.g. CFDTR - --> mnemonic unchanged, both mask values written -*/ -HChar * -fp_convt_disasm(const s390_opnd *opnds, HChar *p) -{ - vassert(mask_count(opnds) == 2); - - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 2)].mask; - UInt len = vex_strlen(base); - - HChar xmnm[len + 1]; - - vex_sprintf(xmnm, "%s", base); - - if (xmnm[len - 1] == 'a' && m4 == 0) { - xmnm[len - 1] = '\0'; - return s390_disasm_aux(opnds, xmnm, p, fp_convt_mh); - } - return s390_disasm_aux(opnds, xmnm, p, always_mh); -} - - -HChar * -adtra_like_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *base = opnds[0].xmnm.base; - UInt m4 = opnds[get_mask_index(opnds, 1)].mask; - UInt len = vex_strlen(base); - - HChar xmnm[len + 1]; - - vex_sprintf(xmnm, "%s", base); - - if (xmnm[len - 1] == 'a' && m4 == 0) { - xmnm[len - 1] = '\0'; - } - return s390_disasm_aux(opnds, xmnm, p, mask0_mh); -} - - -static Int -rotate_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) -{ - *value = mask; - if (ix == 5 && mask == 0) return 0; - if (ix == 3) // rosbg, etc - *value = mask & ~0x80; - if (ix == 4) // risbg - *value = mask & ~0x80; - return 1; -} - - -HChar * -rotate_disasm(const s390_opnd *opnds, HChar *p) -{ - const HChar *base = opnds[0].xmnm.base; - UInt len = vex_strlen(base); - HChar xmnm[len + 1]; - - if (opnds[0].xmnm.base[1] == 'i') - vex_sprintf(xmnm, "%s%c", base, (opnds[4].u & 0x80) ? 'z' : '\0'); - else - vex_sprintf(xmnm, "%s%c", base, (opnds[3].u & 0x80) ? 't' : '\0'); - - return s390_disasm_aux(opnds, xmnm, p, rotate_mh); -} - - -/* Write out OPNDS. MH is a mask handler. It decides whether or not a - MASK operand is written and if so, massages the mask value as needed. */ -static HChar * -s390_disasm_aux(const s390_opnd *opnds, const HChar *xmnm, HChar *p, - Int (*mh)(UInt, UInt, UInt *)) -{ - vassert(opnds[0].kind == S390_OPND_MNM || - opnds[0].kind == S390_OPND_XMNM); - - Int write_separator = 0; // no separator after mnemonic - - for (UInt ix = 0; opnds[ix].kind != S390_OPND_DONE; ++ix) { - const s390_opnd *opnd = opnds + ix; - - switch (opnd->kind) { - case S390_OPND_MNM: - p += vex_sprintf(p, "%s", padmnm(opnd->mnm)); - *p++ = ' '; - break; - - case S390_OPND_XMNM: - p += vex_sprintf(p, "%s", padmnm(xmnm)); - *p++ = ' '; - break; - - case S390_OPND_GPR: - p += vex_sprintf(p, "%s", gpr_operand(opnd->regno)); - break; - - case S390_OPND_FPR: - p += vex_sprintf(p, "%s", fpr_operand(opnd->regno)); - break; - - case S390_OPND_AR: - p += vex_sprintf(p, "%s", ar_operand(opnd->regno)); - break; - - case S390_OPND_VR: - p += vex_sprintf(p, "%s", vr_operand(opnd->regno)); - break; - - case S390_OPND_MASK: { - UInt value; - if (mh && mh(ix, opnd->mask, &value)) - p += vex_sprintf(p, "%u", value); - else - write_separator = 0; - break; - } - - case S390_OPND_UINT: - p += vex_sprintf(p, "%u", opnd->u); - break; - - case S390_OPND_INT: - p += vex_sprintf(p, "%d", opnd->i); - break; - - case S390_OPND_PCREL: { - Long offset = opnd->pcrel; - - /* Convert # halfwords to # bytes */ - offset <<= 1; - - if (offset < 0) { - p += vex_sprintf(p, ".%lld", offset); - } else { - p += vex_sprintf(p, ".+%lld", offset); - } - break; - } - - case S390_OPND_SDXB: { - UInt d = opnd->d; - UInt x = opnd->x; - UInt b = opnd->b; - - p = dxb_operand(p, d, x, b, 1 /* signed_displacement */); - break; - } - - case S390_OPND_UDXB: { - UInt d = opnd->d; - UInt x = opnd->x; - UInt b = opnd->b; - - p = dxb_operand(p, d, x, b, 0 /* signed_displacement */); - break; - } - - case S390_OPND_UDLB: { - UInt d = opnd->d; - UInt l = opnd->l; - UInt b = opnd->b; - - p = udlb_operand(p, d, l, b); - break; - } - - case S390_OPND_UDVB: { - UInt d = opnd->d; - UInt v = opnd->v; - UInt b = opnd->b; - - p = dvb_operand(p, d, v, b, 0 /* signed_displacement */); - break; - } - - case S390_OPND_DONE: // silence GCC - vassert(0); - break; - } - - if (write_separator) - *p++ = ','; - write_separator = 1; - } - - if (p[-1] == ',') // remove trailing separator, if any - *--p = '\0'; - - return p; -} - - -void -s390_disasm(const s390_opnd *opnds) -{ - HChar buf[128]; /* holds the disassembled insn */ - HChar *p = buf; - - if (opnds[0].kind == S390_OPND_MNM) { - p = s390_disasm_aux(opnds, NULL, p, NULL); - } else if (opnds[0].kind == S390_OPND_XMNM) { - p = opnds[0].xmnm.handler(opnds, p); - } else { - vassert(0); - } - *p = '\0'; - - vassert(p < buf + sizeof buf); /* detect buffer overwrite */ - - /* Finally, write out the disassembled insn */ - vex_printf("%s\n", buf); -} - -/*---------------------------------------------------------------*/ -/*--- end s390_disasm.c ---*/ -/*---------------------------------------------------------------*/ diff --git a/VEX/priv/s390_disasm.h b/VEX/priv/s390_disasm.h index d3096fd47a..2606b2eeca 100644 --- a/VEX/priv/s390_disasm.h +++ b/VEX/priv/s390_disasm.h @@ -31,114 +31,7 @@ #include "libvex_basictypes.h" -/* The different kinds of operands in an asm insn */ -typedef enum { - S390_OPND_DONE, - S390_OPND_GPR, - S390_OPND_FPR, - S390_OPND_AR, - S390_OPND_VR, - S390_OPND_INT, - S390_OPND_UINT, - S390_OPND_PCREL, - S390_OPND_SDXB, - S390_OPND_UDXB, - S390_OPND_UDLB, - S390_OPND_UDVB, - S390_OPND_MNM, - S390_OPND_XMNM, - S390_OPND_MASK, // used for operands that modify the mnemonic -} opnd_t; - -typedef struct s390_opnd s390_opnd; - -struct s390_opnd { - opnd_t kind; // S390_OPND_.... - union { - const HChar *mnm; // MNM - UInt regno; // GPR, AR, FPR, VR - UInt mask; // MASK - Int pcrel; // PCREL - UInt u; // UINT - Int i; // INT - struct { // UDXB, SDXB, UDLB, UDVB - UInt d : 20; - union { - UInt x : 4; - UInt l : 8; - UInt v : 5; - }; - UInt b : 4; - }; - struct { - const HChar *base; - HChar *(*handler)(const s390_opnd *, HChar *); - } xmnm; - }; -}; - -/* Convenience macro to piece together a 20-bit displacement value. */ -#define D20(dh,dl) (((dh) << 12) | (dl)) - -/* Macros for operand construction */ -#define MNM(x) { S390_OPND_MNM, .mnm = (x) } -#define GPR(x) { S390_OPND_GPR, .regno = (x) } -#define FPR(x) { S390_OPND_FPR, .regno = (x) } -#define AR(x) { S390_OPND_AR, .regno = (x) } -#define VR(x) { S390_OPND_VR, .regno = (x) } -#define MASK(x) { S390_OPND_MASK, .mask = (x) } -#define UINT(x) { S390_OPND_UINT, .u = (x) } -#define INT(x) { S390_OPND_INT, .i = (x) } -#define PCREL(x) { S390_OPND_PCREL, .pcrel = (x) } -#define UDXB(_d,_x,_b) { S390_OPND_UDXB, .d = (_d), .x = (_x), .b = (_b) } -#define UDVB(_d,_v,_b) { S390_OPND_UDVB, .d = (_d), .v = (_v), .b = (_b) } -#define UDLB(_d,_l,_b) { S390_OPND_UDLB, .d = (_d), .l = (_l), .b = (_b) } -#define SDXB(dh,dl,_x,_b) \ - { S390_OPND_SDXB, .d = D20((dh), (dl)), .x = (_x), .b = (_b) } -#define XMNM(mnm,h) \ - { S390_OPND_XMNM, .xmnm.base = (mnm), .xmnm.handler = (h) } - -#define S390_DISASM(...) \ - s390_disasm((s390_opnd []){ __VA_ARGS__, { S390_OPND_DONE } }) - -void s390_disasm(const s390_opnd *); - -/* Handlers for extended mnemonics */ -HChar *bc_disasm(const s390_opnd *, HChar *); -HChar *bcr_disasm(const s390_opnd *, HChar *); -HChar *brc_disasm(const s390_opnd *, HChar *); -HChar *bic_disasm(const s390_opnd *, HChar *); -HChar *cls_disasm(const s390_opnd *, HChar *); -HChar *brcl_disasm(const s390_opnd *, HChar *); -HChar *cabt_disasm(const s390_opnd *, HChar *); -HChar *mask0_disasm(const s390_opnd *, HChar *); -HChar *vcdg_disasm(const s390_opnd *, HChar *); -HChar *vcgd_disasm(const s390_opnd *, HChar *); -HChar *vcgld_disasm(const s390_opnd *, HChar *); -HChar *vclgd_disasm(const s390_opnd *, HChar *); -HChar *vfi_disasm(const s390_opnd *, HChar *); -HChar *vfll_disasm(const s390_opnd *, HChar *); -HChar *vflr_disasm(const s390_opnd *, HChar *); -HChar *vfms_like_disasm(const s390_opnd *, HChar *); -HChar *vfpso_disasm(const s390_opnd *, HChar *); -HChar *vgbm_disasm(const s390_opnd *, HChar *); -HChar *vllez_disasm(const s390_opnd *, HChar *); -HChar *vllebrz_disasm(const s390_opnd *, HChar *); -HChar *vmsl_disasm(const s390_opnd *, HChar *); -HChar *vstebrf_disasm(const s390_opnd *, HChar *); -HChar *vstebrg_disasm(const s390_opnd *, HChar *); -HChar *vstrc_disasm(const s390_opnd *, HChar *); -HChar *va_like_disasm(const s390_opnd *, HChar *); -HChar *vch_like_disasm(const s390_opnd *, HChar *); -HChar *vfa_like_disasm(const s390_opnd *, HChar *); -HChar *wfc_like_disasm(const s390_opnd *, HChar *); -HChar *vfae_like_disasm(const s390_opnd *, HChar *); -HChar *vfce_like_disasm(const s390_opnd *, HChar *); -HChar *vfmix_like_disasm(const s390_opnd *, HChar *); -HChar *fp_convf_disasm(const s390_opnd *, HChar *); -HChar *fp_convt_disasm(const s390_opnd *, HChar *); -HChar *adtra_like_disasm(const s390_opnd *, HChar *); -HChar *rotate_disasm(const s390_opnd *, HChar *); +HChar *s390_disasm(const UChar *, Int); /*---------------------------------------------------------------*/ /*--- end s390_disasm.h ---*/ diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 0be6deb824..c7de6273ac 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -162,46 +162,24 @@ typedef #define VEX_S390X_MODEL_UNKNOWN 19 /* always last in list */ #define VEX_S390X_MODEL_MASK 0x3F -#define VEX_HWCAPS_S390X_LDISP (1<<6) /* Long-displacement facility */ -#define VEX_HWCAPS_S390X_EIMM (1<<7) /* Extended-immediate facility */ -#define VEX_HWCAPS_S390X_GIE (1<<8) /* General-instruction-extension facility */ -#define VEX_HWCAPS_S390X_DFP (1<<9) /* Decimal floating point facility */ -#define VEX_HWCAPS_S390X_FGX (1<<10) /* FPR-GR transfer facility */ -#define VEX_HWCAPS_S390X_ETF2 (1<<11) /* ETF2-enhancement facility */ -#define VEX_HWCAPS_S390X_STFLE (1<<12) /* STFLE facility */ -#define VEX_HWCAPS_S390X_ETF3 (1<<13) /* ETF3-enhancement facility */ -#define VEX_HWCAPS_S390X_STCKF (1<<14) /* STCKF facility */ -#define VEX_HWCAPS_S390X_FPEXT (1<<15) /* Floating point extension facility */ -#define VEX_HWCAPS_S390X_LSC (1<<16) /* Conditional load/store facility */ -#define VEX_HWCAPS_S390X_PFPO (1<<17) /* Perform floating point ops facility */ -#define VEX_HWCAPS_S390X_VX (1<<18) /* Vector facility */ -#define VEX_HWCAPS_S390X_MSA5 (1<<19) /* Message-security-assistance facility 5 */ -#define VEX_HWCAPS_S390X_MI2 (1<<20) /* Miscellaneous-instruction-extensions facility 2 */ -#define VEX_HWCAPS_S390X_LSC2 (1<<21) /* Conditional load/store facility2 */ -#define VEX_HWCAPS_S390X_VXE (1<<22) /* Vector-enhancements facility */ -#define VEX_HWCAPS_S390X_NNPA (1<<23) /* NNPA facility */ -#define VEX_HWCAPS_S390X_DFLT (1<<24) /* Deflate-conversion facility */ -#define VEX_HWCAPS_S390X_VXE2 (1<<25) /* Vector-enhancements facility 2 */ -#define VEX_HWCAPS_S390X_VXD (1<<26) /* Vector packed-decimal facility */ -#define VEX_HWCAPS_S390X_MSA (1<<27) /* Message-security assist */ -#define VEX_HWCAPS_S390X_MSA4 (1<<28) /* Message-security-assist extension 4 */ -#define VEX_HWCAPS_S390X_MSA8 (1<<29) /* Message-security-assist extension 8 */ -#define VEX_HWCAPS_S390X_MSA9 (1<<30) /* Message-security-assist extension 9 */ +#define VEX_HWCAPS_S390X_VX (1 << 6) /* Vector facility */ +#define VEX_HWCAPS_S390X_MSA5 (1 << 7) /* Message-security-assistance facility 5 */ +#define VEX_HWCAPS_S390X_MI2 (1 << 8) /* Miscellaneous-instruction-extensions facility 2 */ +#define VEX_HWCAPS_S390X_LSC2 (1 << 9) /* Conditional load/store facility2 */ +#define VEX_HWCAPS_S390X_VXE (1 << 10) /* Vector-enhancements facility */ +#define VEX_HWCAPS_S390X_NNPA (1 << 11) /* NNPA facility */ +#define VEX_HWCAPS_S390X_DFLT (1 << 12) /* Deflate-conversion facility */ +#define VEX_HWCAPS_S390X_VXE2 (1 << 13) /* Vector-enhancements facility 2 */ +#define VEX_HWCAPS_S390X_VXD (1 << 14) /* Vector packed-decimal facility */ +#define VEX_HWCAPS_S390X_MSA8 (1 << 15) /* Message-security-assist extension 8 */ +#define VEX_HWCAPS_S390X_MSA9 (1 << 16) /* Message-security-assist extension 9 */ +#define VEX_HWCAPS_S390X_MI3 (1 << 17) /* Miscellaneous-instruction-extensions facility 3 */ +#define VEX_HWCAPS_S390X_VXE3 (1 << 18) /* Vector-enhancements facility 3 */ +#define VEX_HWCAPS_S390X_MSA12 (1 << 19) /* Msg.-security-assist extension 12 */ +#define VEX_HWCAPS_S390X_MRMM (1 << 19) /* Minimum required machine model */ /* Special value representing all available s390x hwcaps */ -#define VEX_HWCAPS_S390X_ALL (VEX_HWCAPS_S390X_LDISP | \ - VEX_HWCAPS_S390X_EIMM | \ - VEX_HWCAPS_S390X_GIE | \ - VEX_HWCAPS_S390X_DFP | \ - VEX_HWCAPS_S390X_FGX | \ - VEX_HWCAPS_S390X_STFLE | \ - VEX_HWCAPS_S390X_STCKF | \ - VEX_HWCAPS_S390X_FPEXT | \ - VEX_HWCAPS_S390X_LSC | \ - VEX_HWCAPS_S390X_ETF3 | \ - VEX_HWCAPS_S390X_ETF2 | \ - VEX_HWCAPS_S390X_PFPO | \ - VEX_HWCAPS_S390X_VX | \ +#define VEX_HWCAPS_S390X_ALL (VEX_HWCAPS_S390X_VX | \ VEX_HWCAPS_S390X_MSA5 | \ VEX_HWCAPS_S390X_MI2 | \ VEX_HWCAPS_S390X_LSC2 | \ @@ -210,10 +188,12 @@ typedef VEX_HWCAPS_S390X_DFLT | \ VEX_HWCAPS_S390X_VXE2 | \ VEX_HWCAPS_S390X_VXD | \ - VEX_HWCAPS_S390X_MSA | \ - VEX_HWCAPS_S390X_MSA4 | \ VEX_HWCAPS_S390X_MSA8 | \ - VEX_HWCAPS_S390X_MSA9) + VEX_HWCAPS_S390X_MSA9 | \ + VEX_HWCAPS_S390X_MI3 | \ + VEX_HWCAPS_S390X_VXE3 | \ + VEX_HWCAPS_S390X_MSA12 | \ + VEX_HWCAPS_S390X_MRMM) #define VEX_HWCAPS_S390X(x) ((x) & ~VEX_S390X_MODEL_MASK) #define VEX_S390X_MODEL(x) ((x) & VEX_S390X_MODEL_MASK) @@ -609,11 +589,6 @@ extern void LibVEX_ShowAllocStats ( void ); /* Describe the guest state enough that the instrumentation functions can work. */ - -/* The max number of guest state chunks which we can describe as - always defined (for the benefit of Memcheck). */ -#define VEXGLO_N_ALWAYSDEFD 24 - typedef struct { /* Total size of the guest state, in bytes. Must be @@ -634,7 +609,7 @@ typedef struct { Int offset; Int size; - } alwaysDefd[VEXGLO_N_ALWAYSDEFD]; + } alwaysDefd[]; } VexGuestLayout; diff --git a/VEX/pub/libvex_basictypes.h b/VEX/pub/libvex_basictypes.h index 67bc1a9b2a..c694f8dce5 100644 --- a/VEX/pub/libvex_basictypes.h +++ b/VEX/pub/libvex_basictypes.h @@ -205,7 +205,6 @@ typedef unsigned long HWord; # error "Vex: Fatal: Can't establish the host architecture" #endif - #endif /* ndef __LIBVEX_BASICTYPES_H */ /*---------------------------------------------------------------*/ diff --git a/VEX/pub/libvex_emnote.h b/VEX/pub/libvex_emnote.h index 331c1b603f..b373f7678a 100644 --- a/VEX/pub/libvex_emnote.h +++ b/VEX/pub/libvex_emnote.h @@ -84,40 +84,16 @@ typedef EmWarn_PPC64_redir_overflow, EmWarn_PPC64_redir_underflow, - /* insn specifies a rounding mode other than "according to FPC" - which requires the floating point extension facility. But that - facility is not available on this host */ - EmWarn_S390X_fpext_rounding, - /* Various BFP insns have an M4 field containing the - IEEE-inexact-exception (XxC) control bit. That bit cannot me modelled + IEEE-inexact-exception (XxC) control bit. That bit cannot be modelled in VEX and is expected to be zero. */ EmWarn_S390X_XxC_not_zero, /* Various DFP insns have an M4 field containing the - IEEE-invalid-operation (XiC) control bit. That bit cannot me modelled + IEEE-invalid-operation (XiC) control bit. That bit cannot be modelled in VEX and is expected to be zero. */ EmWarn_S390X_XiC_not_zero, - /* stfle insn is not supported on this host */ - EmFail_S390X_stfle, - - /* stckf insn is not supported on this host */ - EmFail_S390X_stckf, - - /* ecag insn is not supported on this host */ - EmFail_S390X_ecag, - - /* pfpo insn is not supported on this host */ - EmFail_S390X_pfpo, - - /* DFP insns are not supported on this host */ - EmFail_S390X_DFP_insn, - - /* insn needs floating point extension facility which is not - available on this host */ - EmFail_S390X_fpext, - /* GPR 0 contains invalid rounding mode for PFPO instruction */ EmFail_S390X_invalid_PFPO_rounding_mode, @@ -151,14 +127,6 @@ typedef this host */ EmFail_S390X_vxd, - /* insn needs message-security assist which is not available on - this host */ - EmFail_S390X_msa, - - /* insn needs message-security-assist extension 4 which is not available - on this host */ - EmFail_S390X_msa4, - /* insn needs message-security-assist extension 8 which is not available on this host */ EmFail_S390X_msa8, @@ -167,6 +135,10 @@ typedef on this host */ EmFail_S390X_msa9, + /* insn needs vector-enhancements facility 3 which is not available on + this host */ + EmFail_S390X_vxe3, + EmNote_NUMBER } VexEmNote; diff --git a/VEX/pub/libvex_guest_amd64.h b/VEX/pub/libvex_guest_amd64.h index e96b6b0f3f..42a62131e8 100644 --- a/VEX/pub/libvex_guest_amd64.h +++ b/VEX/pub/libvex_guest_amd64.h @@ -80,9 +80,9 @@ typedef /* 176 */ ULong guest_DFLAG; /* 184 */ ULong guest_RIP; /* Bit 18 (AC) of eflags stored here, as either 0 or 1. */ - /* ... */ ULong guest_ACFLAG; + /* 192 */ ULong guest_ACFLAG; /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */ - /* 192 */ ULong guest_IDFLAG; + /* 200 */ ULong guest_IDFLAG; /* Probably a lot more stuff too. D,ID flags 16 128-bit SSE registers @@ -99,8 +99,8 @@ typedef consecutively in order that the SSE4.2 PCMP{E,I}STR{I,M} helpers can treat them as an array. YMM16 is a fake reg used as an intermediary in handling aforementioned insns. */ - /* 208 */ULong guest_SSEROUND; - /* 216 */U256 guest_YMM0; + /* 216 */ULong guest_SSEROUND; + /* 224 */U256 guest_YMM0; U256 guest_YMM1; U256 guest_YMM2; U256 guest_YMM3; @@ -131,10 +131,7 @@ typedef /* Emulation notes */ UInt guest_EMNOTE; - /* Used by Darwin and FreeBSD when setting the carry flag from - * ML_(do_syscall_for_client_WRK). Needed to determine how - * to restart interrupted syscalls. */ - UInt guest_SETC; + UInt pad2; /* Translation-invalidation area description. Not used on amd64 (there is no invalidate-icache insn), but needed so as to @@ -164,20 +161,20 @@ typedef of the %fs-const hack for amd64-linux/solaris). */ ULong guest_GS_CONST; - /* Needed for Darwin (but mandated for all guest architectures): - RIP at the last syscall insn (int 0x80/81/82, sysenter, - syscall). Used when backing up to restart a syscall that has - been interrupted by a signal. */ - ULong guest_IP_AT_SYSCALL; - /* Used on FreeBSD as part of a mechanism to allow signal handlers to use TLS. */ ULong guest_TLSBASE; + UInt padding1; + UInt padding2; + /* Add padding here to make it have an 16-aligned size */ } VexGuestAMD64State; +#if defined(__LP64__) +_Static_assert(sizeof(VexGuestAMD64State)%16 == 0, "sizeof VexGuestAMD64State is not a multiple of 16"); +#endif /*---------------------------------------------------------------*/ diff --git a/VEX/pub/libvex_guest_arm.h b/VEX/pub/libvex_guest_arm.h index a540f2b410..93cc13acb8 100644 --- a/VEX/pub/libvex_guest_arm.h +++ b/VEX/pub/libvex_guest_arm.h @@ -104,12 +104,8 @@ typedef replace-style ones. */ UInt guest_NRADDR; - /* Needed for Darwin (but mandated for all guest architectures): - program counter at the last syscall insn (int 0x80/81/82, - sysenter, syscall, svc). Used when backing up to restart a - syscall that has been interrupted by a signal. */ /* 124 */ - UInt guest_IP_AT_SYSCALL; + UInt padding1; /* VFP state. D0 .. D15 must be 8-aligned. */ /* 128 */ @@ -198,6 +194,7 @@ typedef } VexGuestARMState; +_Static_assert(sizeof(VexGuestARMState)%16 == 0, "sizeof VexGuestX86State is not a multiple of 16"); /*---------------------------------------------------------------*/ /*--- Utility functions for ARM guest stuff. ---*/ diff --git a/VEX/pub/libvex_guest_arm64.h b/VEX/pub/libvex_guest_arm64.h index 30317dae65..7e50acfbcd 100644 --- a/VEX/pub/libvex_guest_arm64.h +++ b/VEX/pub/libvex_guest_arm64.h @@ -144,12 +144,6 @@ typedef replace-style ones. */ ULong guest_NRADDR; - /* Needed for Darwin (but mandated for all guest architectures): - program counter at the last syscall insn (int 0x80/81/82, - sysenter, syscall, svc). Used when backing up to restart a - syscall that has been interrupted by a signal. */ - ULong guest_IP_AT_SYSCALL; - /* The complete FPCR. Default value seems to be zero. We ignore all bits except 23 and 22, which are the rounding mode. The guest is unconstrained in what values it can write @@ -168,17 +162,16 @@ typedef /* Used for FreeBSD syscall dispatching. */ ULong guest_SC_CLASS; - /* Used for FreeBSD client syscall when putting the carry flag - value into VEX. */ - UInt guest_SETC; - UInt pad_end_0; /* Padding to make it have an 16-aligned size */ - /* UInt pad_end_1; */ - /* ULong pad_end_2; */ + //UInt pad_end_1; } VexGuestARM64State; +#if defined(__LP64__) +_Static_assert((sizeof(VexGuestARM64State)%16)== 0, "sizeof VexGuestARM64State is not a multiple of 16"); +#endif + /*---------------------------------------------------------------*/ /*--- Utility functions for ARM64 guest stuff. ---*/ diff --git a/VEX/pub/libvex_guest_mips32.h b/VEX/pub/libvex_guest_mips32.h index c43ac2f225..d738fba346 100644 --- a/VEX/pub/libvex_guest_mips32.h +++ b/VEX/pub/libvex_guest_mips32.h @@ -188,11 +188,14 @@ typedef /* 1016 */ UInt guest_MSACSR; - /* 1020 */ UInt guest_IP_AT_SYSCALL; + /* 1020 */ UInt _padding3; /* 1024 */ ULong guest_LLdata64; - /* 1032 */ ULong _padding3; + /* 1032 */ ULong _padding4; } VexGuestMIPS32State; + +_Static_assert(sizeof(VexGuestMIPS32State)%16 == 0, "sizeof VexGuestMIPS32State is not a multiple of 16"); + /*---------------------------------------------------------------*/ /*--- Utility functions for MIPS32 guest stuff. ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/pub/libvex_guest_mips64.h b/VEX/pub/libvex_guest_mips64.h index 1ee2c18327..d057f31b67 100644 --- a/VEX/pub/libvex_guest_mips64.h +++ b/VEX/pub/libvex_guest_mips64.h @@ -184,11 +184,13 @@ typedef /* 1144 */ UInt guest_MSACSR; /* 1148 */ UInt _padding2; - /* 1152 */ ULong guest_IP_AT_SYSCALL; - /* 1160 */ ULong _padding3; } VexGuestMIPS64State; +#if defined(__LP64__) +_Static_assert(sizeof(VexGuestMIPS64State)%16 == 0, "sizeof VexGuestMIPS64State is not a multiple of 16"); +#endif + /*---------------------------------------------------------------*/ /*--- Utility functions for MIPS64 guest stuff. ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/pub/libvex_guest_ppc32.h b/VEX/pub/libvex_guest_ppc32.h index f0cdedacb6..a83722cf32 100644 --- a/VEX/pub/libvex_guest_ppc32.h +++ b/VEX/pub/libvex_guest_ppc32.h @@ -235,66 +235,65 @@ typedef /* 1220 */ UInt guest_REDIR_SP; /* 1224 */ UInt guest_REDIR_STACK[VEX_GUEST_PPC32_REDIR_STACK_SIZE]; - /* Needed for Darwin (but mandated for all guest architectures): - CIA at the last SC insn. Used when backing up to restart a - syscall that has been interrupted by a signal. */ - /* 134C */ UInt guest_IP_AT_SYSCALL; - /* SPRG3, which AIUI is readonly in user space. Needed for threading on AIX. */ - /* 1356 */ UInt guest_SPRG3_RO; - /* 1360 */ UInt padding1; - /* 1364 */ ULong guest_TFHAR; // Transaction Failure Handler Address Register - /* 1372 */ ULong guest_TEXASR; // Transaction EXception And Summary Register - /* 1380 */ ULong guest_TFIAR; // Transaction Failure Instruction Address Register - /* 1388 */ ULong guest_PPR; // Program Priority register - /* 1396 */ UInt guest_TEXASRU; // Transaction EXception And Summary Register Upper - /* 1400 */ UInt guest_PSPB; // Problem State Priority Boost register - /* 1404 */ ULong guest_DSCR; // Data Stream Control register + /* 1352 */ UInt guest_SPRG3_RO; + /* 1356 */ UInt padding1; + /* 1360 */ ULong guest_TFHAR; // Transaction Failure Handler Address Register + /* 1368 */ ULong guest_TEXASR; // Transaction EXception And Summary Register + /* 1376 */ ULong guest_TFIAR; // Transaction Failure Instruction Address Register + /* 1384 */ ULong guest_PPR; // Program Priority register + /* 1392 */ UInt guest_TEXASRU; // Transaction EXception And Summary Register Upper + /* 1396 */ UInt guest_PSPB; // Problem State Priority Boost register + /* 1400 */ ULong guest_DSCR; // Data Stream Control register /* ISA 3.1 Accumulators. There are eight accumulators each contains four 128-bit rows. Declare each acculator and row explicitly, then use a helper to map ACC[i][row] to the explicitly declared entry. Technically not supported in 32-bit mode but needs to be defined. */ - /* 1412 */ U128 guest_ACC_0_r0; - /* 1428 */ U128 guest_ACC_0_r1; - /* 1444 */ U128 guest_ACC_0_r2; - /* 1460 */ U128 guest_ACC_0_r3; - /* 1476 */ U128 guest_ACC_1_r0; - /* 1492 */ U128 guest_ACC_1_r1; - /* 1508 */ U128 guest_ACC_1_r2; - /* 1524 */ U128 guest_ACC_1_r3; - /* 1540 */ U128 guest_ACC_2_r0; - /* 1556 */ U128 guest_ACC_2_r1; - /* 1572 */ U128 guest_ACC_2_r2; - /* 1588 */ U128 guest_ACC_2_r3; - /* 1604 */ U128 guest_ACC_3_r0; - /* 1620 */ U128 guest_ACC_3_r1; - /* 1636 */ U128 guest_ACC_3_r2; - /* 1652 */ U128 guest_ACC_3_r3; - /* 1668 */ U128 guest_ACC_4_r0; - /* 1684 */ U128 guest_ACC_4_r1; - /* 1700 */ U128 guest_ACC_4_r2; - /* 1716 */ U128 guest_ACC_4_r3; - /* 1732 */ U128 guest_ACC_5_r0; - /* 1748 */ U128 guest_ACC_5_r1; - /* 1780 */ U128 guest_ACC_5_r2; - /* 1796 */ U128 guest_ACC_5_r3; - /* 1812 */ U128 guest_ACC_6_r0; - /* 1828 */ U128 guest_ACC_6_r1; - /* 1844 */ U128 guest_ACC_6_r2; - /* 1860 */ U128 guest_ACC_6_r3; - /* 1876 */ U128 guest_ACC_7_r0; - /* 1892 */ U128 guest_ACC_7_r1; - /* 1908 */ U128 guest_ACC_7_r2; - /* 1924 */ U128 guest_ACC_7_r3; + /* 1408 */ U128 guest_ACC_0_r0; + /* 1424 */ U128 guest_ACC_0_r1; + /* 1440 */ U128 guest_ACC_0_r2; + /* 1456 */ U128 guest_ACC_0_r3; + /* 1474 */ U128 guest_ACC_1_r0; + /* 1488 */ U128 guest_ACC_1_r1; + /* 1504 */ U128 guest_ACC_1_r2; + /* 1520 */ U128 guest_ACC_1_r3; + /* 1536 */ U128 guest_ACC_2_r0; + /* 1552 */ U128 guest_ACC_2_r1; + /* 1568 */ U128 guest_ACC_2_r2; + /* 1584 */ U128 guest_ACC_2_r3; + /* 1600 */ U128 guest_ACC_3_r0; + /* 1616 */ U128 guest_ACC_3_r1; + /* 1632 */ U128 guest_ACC_3_r2; + /* 1648 */ U128 guest_ACC_3_r3; + /* 1664 */ U128 guest_ACC_4_r0; + /* 1680 */ U128 guest_ACC_4_r1; + /* 1696 */ U128 guest_ACC_4_r2; + /* 1712 */ U128 guest_ACC_4_r3; + /* 1728 */ U128 guest_ACC_5_r0; + /* 1744 */ U128 guest_ACC_5_r1; + /* 1776 */ U128 guest_ACC_5_r2; + /* 1792 */ U128 guest_ACC_5_r3; + /* 1808 */ U128 guest_ACC_6_r0; + /* 1824 */ U128 guest_ACC_6_r1; + /* 1840 */ U128 guest_ACC_6_r2; + /* 1856 */ U128 guest_ACC_6_r3; + /* 1872 */ U128 guest_ACC_7_r0; + /* 1888 */ U128 guest_ACC_7_r1; + /* 1904 */ U128 guest_ACC_7_r2; + /* 1920 */ U128 guest_ACC_7_r3; /* Padding to make it have an 16-aligned size */ - /* 1940 */ UInt guest_syscall_flag; - /* 1944 * UInt padding2; */ + /* 1936 */ UInt guest_syscall_flag; + /* 1940 */ UInt padding2; + /* 1944 */ UInt padding3; + /* 1948 */ UInt padding4; + } VexGuestPPC32State; +_Static_assert(sizeof(VexGuestPPC32State)%16 == 0, "sizeof VexGuesPPC32State is not a multiple of 16"); /*---------------------------------------------------------------*/ /*--- Utility functions for PPC32 guest stuff. ---*/ diff --git a/VEX/pub/libvex_guest_ppc64.h b/VEX/pub/libvex_guest_ppc64.h index cea6679286..295e984d5e 100644 --- a/VEX/pub/libvex_guest_ppc64.h +++ b/VEX/pub/libvex_guest_ppc64.h @@ -276,21 +276,17 @@ typedef /* 1380 */ ULong guest_REDIR_SP; /* 1388 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZE]; - /* Needed for Darwin: CIA at the last SC insn. Used when backing up - to restart a syscall that has been interrupted by a signal. */ - /* 1648 */ ULong guest_IP_AT_SYSCALL; - /* SPRG3, which AIUI is readonly in user space. Needed for threading on AIX. */ - /* 1656 */ ULong guest_SPRG3_RO; + /* 1648 */ ULong guest_SPRG3_RO; - /* 1664 */ ULong guest_TFHAR; // Transaction Failure Handler Address Register - /* 1672 */ ULong guest_TEXASR; // Transaction EXception And Summary Register - /* 1680 */ ULong guest_TFIAR; // Transaction Failure Instruction Address Register - /* 1688 */ ULong guest_PPR; // Program Priority register - /* 1696 */ UInt guest_TEXASRU; // Transaction EXception And Summary Register Upper - /* 1700 */ UInt guest_PSPB; // Problem State Priority Boost register - /* 1704 */ ULong guest_DSCR; // Data Stream Control register + /* 1656 */ ULong guest_TFHAR; // Transaction Failure Handler Address Register + /* 1664 */ ULong guest_TEXASR; // Transaction EXception And Summary Register + /* 1672 */ ULong guest_TFIAR; // Transaction Failure Instruction Address Register + /* 1680 */ ULong guest_PPR; // Program Priority register + /* 1688 */ UInt guest_TEXASRU; // Transaction EXception And Summary Register Upper + /* 1692 */ UInt guest_PSPB; // Problem State Priority Boost register + /* 1696 */ ULong guest_DSCR; // Data Stream Control register /* Historical note, Initial ACC support was implemented to use a separate register file, but in practice (ISA 3.1) the hardware implementation @@ -302,48 +298,47 @@ typedef /* The guest_ACC_entries must be in order and sequential. The helper routines get_ACC_entry(), write_ACC_entry() calculate the offset of the ACC entry based on a address of guest_ACC_0_r0. */ - /* 1712 */ U128 guest_ACC_0_r0; - /* 1728 */ U128 guest_ACC_0_r1; - /* 1744 */ U128 guest_ACC_0_r2; - /* 1760 */ U128 guest_ACC_0_r3; - /* 1776 */ U128 guest_ACC_1_r0; - /* 1792 */ U128 guest_ACC_1_r1; - /* 1808 */ U128 guest_ACC_1_r2; - /* 1824 */ U128 guest_ACC_1_r3; - /* 1840 */ U128 guest_ACC_2_r0; - /* 1856 */ U128 guest_ACC_2_r1; - /* 1872 */ U128 guest_ACC_2_r2; - /* 1888 */ U128 guest_ACC_2_r3; - /* 1904 */ U128 guest_ACC_3_r0; - /* 1920 */ U128 guest_ACC_3_r1; - /* 1936 */ U128 guest_ACC_3_r2; - /* 1952 */ U128 guest_ACC_3_r3; - /* 1968 */ U128 guest_ACC_4_r0; - /* 1984 */ U128 guest_ACC_4_r1; - /* 2000 */ U128 guest_ACC_4_r2; - /* 2016 */ U128 guest_ACC_4_r3; - /* 2032 */ U128 guest_ACC_5_r0; - /* 2048 */ U128 guest_ACC_5_r1; - /* 2064 */ U128 guest_ACC_5_r2; - /* 2080 */ U128 guest_ACC_5_r3; - /* 2096 */ U128 guest_ACC_6_r0; - /* 2112 */ U128 guest_ACC_6_r1; - /* 2128 */ U128 guest_ACC_6_r2; - /* 2144 */ U128 guest_ACC_6_r3; - /* 2160 */ U128 guest_ACC_7_r0; - /* 2176 */ U128 guest_ACC_7_r1; - /* 2192 */ U128 guest_ACC_7_r2; - /* 2208 */ U128 guest_ACC_7_r3; - - /* 2224 */ UInt guest_syscall_flag; - /* 2228 */ UInt padding1; - /* 2232 */ UInt padding2; - /* 2236 */ UInt padding3; + /* 1704 */ U128 guest_ACC_0_r0; + /* 1720 */ U128 guest_ACC_0_r1; + /* 1736 */ U128 guest_ACC_0_r2; + /* 1752 */ U128 guest_ACC_0_r3; + /* 1768 */ U128 guest_ACC_1_r0; + /* 1784 */ U128 guest_ACC_1_r1; + /* 1800 */ U128 guest_ACC_1_r2; + /* 1816 */ U128 guest_ACC_1_r3; + /* 1832 */ U128 guest_ACC_2_r0; + /* 1848 */ U128 guest_ACC_2_r1; + /* 1864 */ U128 guest_ACC_2_r2; + /* 1880 */ U128 guest_ACC_2_r3; + /* 1896 */ U128 guest_ACC_3_r0; + /* 1912 */ U128 guest_ACC_3_r1; + /* 1928 */ U128 guest_ACC_3_r2; + /* 1944 */ U128 guest_ACC_3_r3; + /* 1960 */ U128 guest_ACC_4_r0; + /* 1976 */ U128 guest_ACC_4_r1; + /* 1992 */ U128 guest_ACC_4_r2; + /* 2008 */ U128 guest_ACC_4_r3; + /* 2024 */ U128 guest_ACC_5_r0; + /* 2040 */ U128 guest_ACC_5_r1; + /* 2056 */ U128 guest_ACC_5_r2; + /* 2072 */ U128 guest_ACC_5_r3; + /* 2088 */ U128 guest_ACC_6_r0; + /* 2104 */ U128 guest_ACC_6_r1; + /* 2120 */ U128 guest_ACC_6_r2; + /* 2136 */ U128 guest_ACC_6_r3; + /* 2152 */ U128 guest_ACC_7_r0; + /* 2168 */ U128 guest_ACC_7_r1; + /* 2184 */ U128 guest_ACC_7_r2; + /* 2200 */ U128 guest_ACC_7_r3; + + /* 2216 */ UInt guest_syscall_flag; /* Padding to make it have an 16-aligned size */ - /* 2222 UInt padding0; */ } VexGuestPPC64State; +#if defined(__LP64__) +_Static_assert((sizeof(VexGuestPPC64State)%16)== 0, "sizeof VexGuestPPC64State is not a multiple of 16"); +#endif /*---------------------------------------------------------------*/ /*--- Utility functions for PPC64 guest stuff. ---*/ diff --git a/VEX/pub/libvex_guest_s390x.h b/VEX/pub/libvex_guest_s390x.h index c805dc0c0a..7abb88d01b 100644 --- a/VEX/pub/libvex_guest_s390x.h +++ b/VEX/pub/libvex_guest_s390x.h @@ -157,26 +157,22 @@ typedef struct { /* 776 */ ULong guest_CMSTART; /* 784 */ ULong guest_CMLEN; - /* Used when backing up to restart a syscall that has - been interrupted by a signal. See also comment in - libvex_ir.h */ - /* 792 */ ULong guest_IP_AT_SYSCALL; - /* Emulation notes; see comments in libvex_emnote.h */ - /* 800 */ UInt guest_EMNOTE; + /* 792 */ UInt guest_EMNOTE; /* For translation chaining */ - /* 804 */ UInt host_EvC_COUNTER; - /* 808 */ ULong host_EvC_FAILADDR; + /* 796 */ UInt host_EvC_COUNTER; + /* 800 */ ULong host_EvC_FAILADDR; /*------------------------------------------------------------*/ /*--- Force alignment to 16 bytes ---*/ /*------------------------------------------------------------*/ - /* 816 */ UChar padding[0]; + /* 808 */ ULong padding; /* 816 */ /* This is the size of the guest state */ } VexGuestS390XState; +_Static_assert((sizeof(VexGuestS390XState)%16)== 0, "sizeof VexGuestS390XState is not a multiple of 16"); /*------------------------------------------------------------*/ /*--- Function prototypes ---*/ diff --git a/VEX/pub/libvex_guest_x86.h b/VEX/pub/libvex_guest_x86.h index 80916a2bab..cb6f35fc10 100644 --- a/VEX/pub/libvex_guest_x86.h +++ b/VEX/pub/libvex_guest_x86.h @@ -191,6 +191,7 @@ typedef UShort guest_FS; UShort guest_GS; UShort guest_SS; + UInt paddingSeg; /* LDT/GDT stuff. */ ULong guest_LDT; /* host addr, a VexGuestX86SegDescr* */ ULong guest_GDT; /* host addr, a VexGuestX86SegDescr* */ @@ -213,20 +214,16 @@ typedef /* Used for Darwin syscall dispatching. */ UInt guest_SC_CLASS; - /* Needed for Darwin (but mandated for all guest architectures): - EIP at the last syscall insn (int 0x80/81/82, sysenter, - syscall). Used when backing up to restart a syscall that has - been interrupted by a signal. */ - UInt guest_IP_AT_SYSCALL; - - UInt guest_SETC; /* Padding to make it have an 16-aligned size */ UInt padding1; UInt padding2; + UInt padding3; } VexGuestX86State; +_Static_assert(sizeof(VexGuestX86State)%16 == 0, "sizeof VexGuestX86State is not a multiple of 16"); + #define VEX_GUEST_X86_LDT_NENT /*64*/ 8192 /* use complete LDT */ #define VEX_GUEST_X86_GDT_NENT /*16*/ 8192 /* use complete GDT */ diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 3a1f92f45c..d2c77a07ff 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -2493,18 +2493,6 @@ extern Bool eqIRAtom ( const IRExpr*, const IRExpr* ); In the case of Ijk_EmFail, the exit is fatal (Vex-generated code cannot continue) and so the jump destination can be anything. - - Re Ijk_Sys_ (syscall jumps): the guest state must have a - pseudo-register guest_IP_AT_SYSCALL, which is the size of a guest - word. Front ends should set this to be the IP at the most recently - executed kernel-entering (system call) instruction. This makes it - very much easier (viz, actually possible at all) to back up the - guest to restart a syscall that has been interrupted by a signal. - - Re Ijk_Extension: the guest state must have the pseudo-register - guest_IP_AT_SYSCALL, which is also used for Ijk_Sys_*. Front ends - must set this to the current instruction address before jumping to - an extension handler. */ typedef enum { diff --git a/VEX/pub/libvex_s390x_common.h b/VEX/pub/libvex_s390x_common.h index 295e0c29b0..5fc0be9166 100644 --- a/VEX/pub/libvex_s390x_common.h +++ b/VEX/pub/libvex_s390x_common.h @@ -99,9 +99,6 @@ /* Number of arguments that can be passed in registers */ #define S390_NUM_GPRPARMS 5 -/* Number of double words needed to store all facility bits. */ -#define S390_NUM_FACILITY_DW 4 - #endif /* __LIBVEX_PUB_S390X_H */ /*--------------------------------------------------------------------*/ diff --git a/VEX/test/test-amd64.c b/VEX/test/test-amd64.c index bedc99e98f..981aa3ea03 100644 --- a/VEX/test/test-amd64.c +++ b/VEX/test/test-amd64.c @@ -1207,9 +1207,9 @@ void test_string(void) TEST_STRING(scas, ""); // REINSTATE: TEST_STRING(scas, "repz "); TEST_STRING(scas, "repnz "); - // REINSTATE: TEST_STRING(cmps, ""); + TEST_STRING(cmps, ""); TEST_STRING(cmps, "repz "); - // REINSTATE: TEST_STRING(cmps, "repnz "); + TEST_STRING(cmps, "repnz "); } /* VM86 test */ diff --git a/VEX/useful/Makefile-vex b/VEX/useful/Makefile-vex deleted file mode 100644 index 42d6d66eb4..0000000000 --- a/VEX/useful/Makefile-vex +++ /dev/null @@ -1,8 +0,0 @@ -# Crude makefile to build the "vex" executable from test_main.c - -vex: test_main.c test_main.h ../pub/*.h ../priv/*.c ../priv/*.h - (cd ..; ${MAKE} -f Makefile-gcc) - ${CC} -I../pub -o vex test_main.c ../libvex.a - -clean: - rm -f vex ../priv/*.o diff --git a/VEX/useful/test_main.c b/VEX/useful/test_main.c deleted file mode 100644 index 08513d9a0e..0000000000 --- a/VEX/useful/test_main.c +++ /dev/null @@ -1,2779 +0,0 @@ - -/*---------------------------------------------------------------*/ -/*--- begin test_main.c ---*/ -/*---------------------------------------------------------------*/ - -/* - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2004-2017 OpenWorks LLP - info@open-works.net - - 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 3 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, see . - - The GNU General Public License is contained in the file COPYING. - - Neither the names of the U.S. Department of Energy nor the - University of California nor the names of its contributors may be - used to endorse or promote products derived from this software - without prior written permission. -*/ - -#include -#include -#include -#include - -#include "libvex_basictypes.h" -#include "libvex.h" - -#include "test_main.h" - - -/*---------------------------------------------------------------*/ -/*--- Test ---*/ -/*---------------------------------------------------------------*/ - - -__attribute__ ((noreturn)) -static -void failure_exit ( void ) -{ - fprintf(stdout, "VEX did failure_exit. Bye.\n"); - exit(1); -} - -static -void log_bytes ( const HChar* bytes, SizeT nbytes ) -{ - fwrite ( bytes, 1, nbytes, stdout ); -} - -#define N_LINEBUF 10000 -static HChar linebuf[N_LINEBUF]; - -#define N_ORIGBUF 10000 -#define N_TRANSBUF 5000 - -static UChar origbuf[N_ORIGBUF]; -static UChar transbuf[N_TRANSBUF]; - -static Bool verbose = True; - -/* Forwards */ -#if 1 /* UNUSED */ -//static IRSB* ac_instrument ( IRSB*, VexGuestLayout*, IRType ); -static -IRSB* mc_instrument ( void* closureV, - IRSB* bb_in, VexGuestLayout* layout, - VexGuestExtents* vge, - IRType gWordTy, IRType hWordTy ); -#endif - -static Bool chase_into_not_ok ( void* opaque, Addr dst ) { - return False; -} -static UInt needs_self_check ( void *closureV, VexRegisterUpdates *pxControl, - const VexGuestExtents *vge ) { - return 0; -} - -int main ( int argc, char** argv ) -{ - FILE* f; - Int i; - UInt u, sum; - Addr32 orig_addr; - Int bb_number, n_bbs_done = 0; - Int orig_nbytes, trans_used; - VexTranslateResult tres; - VexControl vcon; - VexGuestExtents vge; - VexArchInfo vai_x86, vai_amd64, vai_ppc32, vai_arm, vai_mips32, vai_mips64, - vai_riscv64; - VexAbiInfo vbi; - VexTranslateArgs vta; - - if (argc != 2) { - fprintf(stderr, "usage: vex file.orig\n"); - exit(1); - } - f = fopen(argv[1], "r"); - if (!f) { - fprintf(stderr, "can't open `%s'\n", argv[1]); - exit(1); - } - - /* Run with default params. However, we can't allow bb chasing - since that causes the front end to get segfaults when it tries - to read code outside the initial BB we hand it. So when calling - LibVEX_Translate, send in a chase-into predicate that always - returns False. */ - LibVEX_default_VexControl ( &vcon ); - vcon.iropt_level = 2; - vcon.guest_max_insns = 60; - - LibVEX_Init ( &failure_exit, &log_bytes, - 1, /* debug_paranoia */ - &vcon ); - - - while (!feof(f)) { - - __attribute__((unused)) - char* unused1 = fgets(linebuf, N_LINEBUF,f); - if (linebuf[0] == 0) continue; - if (linebuf[0] != '.') continue; - - if (n_bbs_done == TEST_N_BBS) break; - n_bbs_done++; - - /* first line is: . bb-number bb-addr n-bytes */ - assert(3 == sscanf(&linebuf[1], " %d %x %d\n", - & bb_number, - & orig_addr, & orig_nbytes )); - assert(orig_nbytes >= 1); - assert(!feof(f)); - __attribute__((unused)) - char* unused2 = fgets(linebuf, N_LINEBUF,f); - assert(linebuf[0] == '.'); - - /* second line is: . byte byte byte etc */ - if (verbose) - printf("============ Basic Block %d, Done %d, " - "Start %x, nbytes %2d ============", - bb_number, n_bbs_done-1, orig_addr, orig_nbytes); - - /* thumb ITstate analysis needs to examine the 18 bytes - preceding the first instruction. So let's leave the first 18 - zeroed out. */ - memset(origbuf, 0, sizeof(origbuf)); - - assert(orig_nbytes >= 1 && orig_nbytes <= N_ORIGBUF); - for (i = 0; i < orig_nbytes; i++) { - assert(1 == sscanf(&linebuf[2 + 3*i], "%x", &u)); - origbuf[18+ i] = (UChar)u; - } - - /* FIXME: put sensible values into the .hwcaps fields */ - LibVEX_default_VexArchInfo(&vai_x86); - vai_x86.hwcaps = VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 - | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3; - vai_x86.endness = VexEndnessLE; - - LibVEX_default_VexArchInfo(&vai_amd64); - vai_amd64.hwcaps = 0; - vai_amd64.endness = VexEndnessLE; - - LibVEX_default_VexArchInfo(&vai_ppc32); - vai_ppc32.hwcaps = 0; - vai_ppc32.ppc_icache_line_szB = 128; - - LibVEX_default_VexArchInfo(&vai_arm); - vai_arm.hwcaps = VEX_HWCAPS_ARM_VFP3 | VEX_HWCAPS_ARM_NEON | 7; - - LibVEX_default_VexArchInfo(&vai_mips32); - vai_mips32.endness = VexEndnessLE; - vai_mips32.hwcaps = VEX_PRID_COMP_MIPS; - - LibVEX_default_VexArchInfo(&vai_mips64); - vai_mips64.endness = VexEndnessLE; - - LibVEX_default_VexArchInfo(&vai_riscv64); - vai_riscv64.hwcaps = 0; - vai_riscv64.endness = VexEndnessLE; - - LibVEX_default_VexAbiInfo(&vbi); - vbi.guest_stack_redzone_size = 128; - - /* ----- Set up args for LibVEX_Translate ----- */ - - vta.abiinfo_both = vbi; - vta.guest_bytes = &origbuf[18]; - vta.guest_bytes_addr = orig_addr; - vta.callback_opaque = NULL; - vta.chase_into_ok = chase_into_not_ok; - vta.guest_extents = &vge; - vta.host_bytes = transbuf; - vta.host_bytes_size = N_TRANSBUF; - vta.host_bytes_used = &trans_used; - -#if 0 /* ppc32 -> ppc32 */ - vta.arch_guest = VexArchPPC32; - vta.archinfo_guest = vai_ppc32; - vta.arch_host = VexArchPPC32; - vta.archinfo_host = vai_ppc32; -#endif -#if 0 /* amd64 -> amd64 */ - vta.arch_guest = VexArchAMD64; - vta.archinfo_guest = vai_amd64; - vta.arch_host = VexArchAMD64; - vta.archinfo_host = vai_amd64; -#endif -#if 0 /* x86 -> x86 */ - vta.arch_guest = VexArchX86; - vta.archinfo_guest = vai_x86; - vta.arch_host = VexArchX86; - vta.archinfo_host = vai_x86; -#endif -#if 1 /* x86 -> mips32 */ - vta.arch_guest = VexArchX86; - vta.archinfo_guest = vai_x86; - vta.arch_host = VexArchMIPS32; - vta.archinfo_host = vai_mips32; -#endif -#if 0 /* amd64 -> mips64 */ - vta.arch_guest = VexArchAMD64; - vta.archinfo_guest = vai_amd64; - vta.arch_host = VexArchMIPS64; - vta.archinfo_host = vai_mips64; -#endif -#if 0 /* arm -> arm */ - vta.arch_guest = VexArchARM; - vta.archinfo_guest = vai_arm; - vta.arch_host = VexArchARM; - vta.archinfo_host = vai_arm; - /* ARM/Thumb only hacks, that are needed to keep the ITstate - analyser in the front end happy. */ - vta.guest_bytes = &origbuf[18 +1]; - vta.guest_bytes_addr = (Addr) &origbuf[18 +1]; -#endif -#if 0 /* riscv64 -> riscv64 */ - vta.arch_guest = VexArchRISCV64; - vta.archinfo_guest = vai_riscv64; - vta.arch_host = VexArchRISCV64; - vta.archinfo_host = vai_riscv64; -#endif - -#if 1 /* no instrumentation */ - vta.instrument1 = NULL; - vta.instrument2 = NULL; -#endif -#if 0 /* addrcheck */ - vta.instrument1 = ac_instrument; - vta.instrument2 = NULL; -#endif -#if 0 /* memcheck */ - vta.instrument1 = mc_instrument; - vta.instrument2 = NULL; -#endif - vta.needs_self_check = needs_self_check; - vta.preamble_function = NULL; - vta.traceflags = TEST_FLAGS; - vta.addProfInc = False; - vta.sigill_diag = True; - - vta.disp_cp_chain_me_to_slowEP = (void*)0x12345678; - vta.disp_cp_chain_me_to_fastEP = (void*)0x12345679; - vta.disp_cp_xindir = (void*)0x1234567A; - vta.disp_cp_xassisted = (void*)0x1234567B; - - vta.finaltidy = NULL; - - for (i = 0; i < TEST_N_ITERS; i++) - tres = LibVEX_Translate ( &vta ); - - if (tres.status != VexTransOK) - printf("\ntres = %d\n", (Int)tres.status); - assert(tres.status == VexTransOK); - assert(tres.n_sc_extents == 0); - assert(vge.n_used == 1); - assert((UInt)(vge.len[0]) == orig_nbytes); - - sum = 0; - for (i = 0; i < trans_used; i++) - sum += (UInt)transbuf[i]; - printf ( " %6.2f ... %u\n", - (double)trans_used / (double)vge.len[0], sum ); - } - - fclose(f); - printf("\n"); - LibVEX_ShowAllocStats(); - - return 0; -} - -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// - -#if 0 /* UNUSED */ - -static -__attribute((noreturn)) -void panic ( HChar* s ) -{ - printf("\npanic: %s\n", s); - failure_exit(); -} - -static -IRSB* ac_instrument (IRSB* bb_in, VexGuestLayout* layout, IRType hWordTy ) -{ -/* Use this rather than eg. -1 because it's a UInt. */ -#define INVALID_DATA_SIZE 999999 - - Int i; - Int sz; - IRCallee* helper; - IRStmt* st; - IRExpr* data; - IRExpr* addr; - Bool needSz; - - /* Set up BB */ - IRSB* bb = emptyIRSB(); - bb->tyenv = dopyIRTypeEnv(bb_in->tyenv); - bb->next = dopyIRExpr(bb_in->next); - bb->jumpkind = bb_in->jumpkind; - - /* No loads to consider in ->next. */ - assert(isIRAtom(bb_in->next)); - - for (i = 0; i < bb_in->stmts_used; i++) { - st = bb_in->stmts[i]; - if (!st) continue; - - switch (st->tag) { - - case Ist_Tmp: - data = st->Ist.Tmp.data; - if (data->tag == Iex_LDle) { - addr = data->Iex.LDle.addr; - sz = sizeofIRType(data->Iex.LDle.ty); - needSz = False; - switch (sz) { - case 4: helper = mkIRCallee(1, "ac_helperc_LOAD4", - (void*)0x12345601); break; - case 2: helper = mkIRCallee(0, "ac_helperc_LOAD2", - (void*)0x12345602); break; - case 1: helper = mkIRCallee(1, "ac_helperc_LOAD1", - (void*)0x12345603); break; - default: helper = mkIRCallee(0, "ac_helperc_LOADN", - (void*)0x12345604); - needSz = True; break; - } - if (needSz) { - addStmtToIRSB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( helper->regparms, - helper->name, helper->addr, - mkIRExprVec_2(addr, mkIRExpr_HWord(sz))) - )); - } else { - addStmtToIRSB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( helper->regparms, - helper->name, helper->addr, - mkIRExprVec_1(addr) ) - )); - } - } - break; - - case Ist_STle: - data = st->Ist.STle.data; - addr = st->Ist.STle.addr; - assert(isIRAtom(data)); - assert(isIRAtom(addr)); - sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data)); - needSz = False; - switch (sz) { - case 4: helper = mkIRCallee(1, "ac_helperc_STORE4", - (void*)0x12345605); break; - case 2: helper = mkIRCallee(0, "ac_helperc_STORE2", - (void*)0x12345606); break; - case 1: helper = mkIRCallee(1, "ac_helperc_STORE1", - (void*)0x12345607); break; - default: helper = mkIRCallee(0, "ac_helperc_STOREN", - (void*)0x12345608); - needSz = True; break; - } - if (needSz) { - addStmtToIRSB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( helper->regparms, - helper->name, helper->addr, - mkIRExprVec_2(addr, mkIRExpr_HWord(sz))) - )); - } else { - addStmtToIRSB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( helper->regparms, - helper->name, helper->addr, - mkIRExprVec_1(addr) ) - )); - } - break; - - case Ist_Put: - assert(isIRAtom(st->Ist.Put.data)); - break; - - case Ist_PutI: - assert(isIRAtom(st->Ist.PutI.ix)); - assert(isIRAtom(st->Ist.PutI.data)); - break; - - case Ist_Exit: - assert(isIRAtom(st->Ist.Exit.guard)); - break; - - case Ist_Dirty: - /* If the call doesn't interact with memory, we ain't - interested. */ - if (st->Ist.Dirty.details->mFx == Ifx_None) - break; - goto unhandled; - - default: - unhandled: - printf("\n"); - ppIRStmt(st); - printf("\n"); - panic("addrcheck: unhandled IRStmt"); - } - - addStmtToIRSB( bb, dopyIRStmt(st)); - } - - return bb; -} -#endif /* UNUSED */ - -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// - -#if 1 /* UNUSED */ - -static -__attribute((noreturn)) -void panic ( HChar* s ) -{ - printf("\npanic: %s\n", s); - failure_exit(); -} - -#define tl_assert(xxx) assert(xxx) -#define VG_(xxxx) xxxx -#define tool_panic(zzz) panic(zzz) -#define MC_(zzzz) MC_##zzzz -#define TL_(zzzz) SK_##zzzz - - -static void MC_helperc_complain_undef ( void ); -static void MC_helperc_LOADV8 ( void ); -static void MC_helperc_LOADV4 ( void ); -static void MC_helperc_LOADV2 ( void ); -static void MC_helperc_LOADV1 ( void ); -static void MC_helperc_STOREV8( void ); -static void MC_helperc_STOREV4( void ); -static void MC_helperc_STOREV2( void ); -static void MC_helperc_STOREV1( void ); -static void MC_helperc_value_check0_fail( void ); -static void MC_helperc_value_check1_fail( void ); -static void MC_helperc_value_check4_fail( void ); - -static void MC_helperc_complain_undef ( void ) { } -static void MC_helperc_LOADV8 ( void ) { } -static void MC_helperc_LOADV4 ( void ) { } -static void MC_helperc_LOADV2 ( void ) { } -static void MC_helperc_LOADV1 ( void ) { } -static void MC_helperc_STOREV8( void ) { } -static void MC_helperc_STOREV4( void ) { } -static void MC_helperc_STOREV2( void ) { } -static void MC_helperc_STOREV1( void ) { } -static void MC_helperc_value_check0_fail( void ) { } -static void MC_helperc_value_check1_fail( void ) { } -static void MC_helperc_value_check4_fail( void ) { } - - -/*--------------------------------------------------------------------*/ -/*--- Instrument IR to perform memory checking operations. ---*/ -/*--- mc_translate.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2017 Julian Seward - jseward@acm.org - - 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 3 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, see . - - The GNU General Public License is contained in the file COPYING. -*/ - -//#include "mc_include.h" - - -/*------------------------------------------------------------*/ -/*--- Forward decls ---*/ -/*------------------------------------------------------------*/ - -struct _MCEnv; - -static IRType shadowType ( IRType ty ); -static IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e ); - - -/*------------------------------------------------------------*/ -/*--- Memcheck running state, and tmp management. ---*/ -/*------------------------------------------------------------*/ - -/* Carries around state during memcheck instrumentation. */ -typedef - struct _MCEnv { - /* MODIFIED: the bb being constructed. IRStmts are added. */ - IRSB* bb; - - /* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps - original temps to their current their current shadow temp. - Initially all entries are IRTemp_INVALID. Entries are added - lazily since many original temps are not used due to - optimisation prior to instrumentation. Note that floating - point original tmps are shadowed by integer tmps of the same - size, and Bit-typed original tmps are shadowed by the type - Ity_I8. See comment below. */ - IRTemp* tmpMap; - Int n_originalTmps; /* for range checking */ - - /* READONLY: the guest layout. This indicates which parts of - the guest state should be regarded as 'always defined'. */ - VexGuestLayout* layout; - /* READONLY: the host word type. Needed for constructing - arguments of type 'HWord' to be passed to helper functions. - Ity_I32 or Ity_I64 only. */ - IRType hWordTy; - } - MCEnv; - -/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on - demand), as they are encountered. This is for two reasons. - - (1) (less important reason): Many original tmps are unused due to - initial IR optimisation, and we do not want to spaces in tables - tracking them. - - Shadow IRTemps are therefore allocated on demand. mce.tmpMap is a - table indexed [0 .. n_types-1], which gives the current shadow for - each original tmp, or INVALID_IRTEMP if none is so far assigned. - It is necessary to support making multiple assignments to a shadow - -- specifically, after testing a shadow for definedness, it needs - to be made defined. But IR's SSA property disallows this. - - (2) (more important reason): Therefore, when a shadow needs to get - a new value, a new temporary is created, the value is assigned to - that, and the tmpMap is updated to reflect the new binding. - - A corollary is that if the tmpMap maps a given tmp to - INVALID_IRTEMP and we are hoping to read that shadow tmp, it means - there's a read-before-write error in the original tmps. The IR - sanity checker should catch all such anomalies, however. -*/ - -/* Find the tmp currently shadowing the given original tmp. If none - so far exists, allocate one. */ -static IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig ) -{ - tl_assert(orig < mce->n_originalTmps); - if (mce->tmpMap[orig] == IRTemp_INVALID) { - mce->tmpMap[orig] - = newIRTemp(mce->bb->tyenv, - shadowType(mce->bb->tyenv->types[orig])); - } - return mce->tmpMap[orig]; -} - -/* Allocate a new shadow for the given original tmp. This means any - previous shadow is abandoned. This is needed because it is - necessary to give a new value to a shadow once it has been tested - for undefinedness, but unfortunately IR's SSA property disallows - this. Instead we must abandon the old shadow, allocate a new one - and use that instead. */ -static void newShadowTmp ( MCEnv* mce, IRTemp orig ) -{ - tl_assert(orig < mce->n_originalTmps); - mce->tmpMap[orig] - = newIRTemp(mce->bb->tyenv, - shadowType(mce->bb->tyenv->types[orig])); -} - - -/*------------------------------------------------------------*/ -/*--- IRAtoms -- a subset of IRExprs ---*/ -/*------------------------------------------------------------*/ - -/* An atom is either an IRExpr_Const or an IRExpr_Tmp, as defined by - isIRAtom() in libvex_ir.h. Because this instrumenter expects flat - input, most of this code deals in atoms. Usefully, a value atom - always has a V-value which is also an atom: constants are shadowed - by constants, and temps are shadowed by the corresponding shadow - temporary. */ - -typedef IRExpr IRAtom; - -/* (used for sanity checks only): is this an atom which looks - like it's from original code? */ -static Bool isOriginalAtom ( MCEnv* mce, IRAtom* a1 ) -{ - if (a1->tag == Iex_Const) - return True; - if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp < mce->n_originalTmps) - return True; - return False; -} - -/* (used for sanity checks only): is this an atom which looks - like it's from shadow code? */ -static Bool isShadowAtom ( MCEnv* mce, IRAtom* a1 ) -{ - if (a1->tag == Iex_Const) - return True; - if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp >= mce->n_originalTmps) - return True; - return False; -} - -/* (used for sanity checks only): check that both args are atoms and - are identically-kinded. */ -static Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 ) -{ - if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp) - return True; - if (a1->tag == Iex_Const && a2->tag == Iex_Const) - return True; - return False; -} - - -/*------------------------------------------------------------*/ -/*--- Type management ---*/ -/*------------------------------------------------------------*/ - -/* Shadow state is always accessed using integer types. This returns - an integer type with the same size (as per sizeofIRType) as the - given type. The only valid shadow types are Bit, I8, I16, I32, - I64, V128. */ - -static IRType shadowType ( IRType ty ) -{ - switch (ty) { - case Ity_I1: - case Ity_I8: - case Ity_I16: - case Ity_I32: - case Ity_I64: return ty; - case Ity_F32: return Ity_I32; - case Ity_F64: return Ity_I64; - case Ity_V128: return Ity_V128; - default: ppIRType(ty); - VG_(tool_panic)("memcheck:shadowType"); - } -} - -/* Produce a 'defined' value of the given shadow type. Should only be - supplied shadow types (Bit/I8/I16/I32/UI64). */ -static IRExpr* definedOfType ( IRType ty ) { - switch (ty) { - case Ity_I1: return IRExpr_Const(IRConst_U1(False)); - case Ity_I8: return IRExpr_Const(IRConst_U8(0)); - case Ity_I16: return IRExpr_Const(IRConst_U16(0)); - case Ity_I32: return IRExpr_Const(IRConst_U32(0)); - case Ity_I64: return IRExpr_Const(IRConst_U64(0)); - case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000)); - default: VG_(tool_panic)("memcheck:definedOfType"); - } -} - - -/*------------------------------------------------------------*/ -/*--- Constructing IR fragments ---*/ -/*------------------------------------------------------------*/ - -/* assign value to tmp */ -#define assign(_bb,_tmp,_expr) \ - addStmtToIRSB((_bb), IRStmt_WrTmp((_tmp),(_expr))) - -/* add stmt to a bb */ -#define stmt(_bb,_stmt) \ - addStmtToIRSB((_bb), (_stmt)) - -/* build various kinds of expressions */ -#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2)) -#define unop(_op, _arg) IRExpr_Unop((_op),(_arg)) -#define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) -#define mkU16(_n) IRExpr_Const(IRConst_U16(_n)) -#define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) -#define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) -#define mkV128(_n) IRExpr_Const(IRConst_V128(_n)) -#define mkexpr(_tmp) IRExpr_RdTmp((_tmp)) - -/* bind the given expression to a new temporary, and return the - temporary. This effectively converts an arbitrary expression into - an atom. */ -static IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) { - IRTemp t = newIRTemp(mce->bb->tyenv, ty); - assign(mce->bb, t, e); - return mkexpr(t); -} - - -/*------------------------------------------------------------*/ -/*--- Constructing definedness primitive ops ---*/ -/*------------------------------------------------------------*/ - -/* --------- Defined-if-either-defined --------- */ - -static IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I8, binop(Iop_And8, a1, a2)); -} - -static IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I16, binop(Iop_And16, a1, a2)); -} - -static IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I32, binop(Iop_And32, a1, a2)); -} - -static IRAtom* mkDifD64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I64, binop(Iop_And64, a1, a2)); -} - -static IRAtom* mkDifDV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_V128, binop(Iop_AndV128, a1, a2)); -} - -/* --------- Undefined-if-either-undefined --------- */ - -static IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I8, binop(Iop_Or8, a1, a2)); -} - -static IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I16, binop(Iop_Or16, a1, a2)); -} - -static IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2)); -} - -static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2)); -} - -static IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - tl_assert(isShadowAtom(mce,a1)); - tl_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_V128, binop(Iop_OrV128, a1, a2)); -} - -static IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) { - switch (vty) { - case Ity_I8: return mkUifU8(mce, a1, a2); - case Ity_I16: return mkUifU16(mce, a1, a2); - case Ity_I32: return mkUifU32(mce, a1, a2); - case Ity_I64: return mkUifU64(mce, a1, a2); - case Ity_V128: return mkUifUV128(mce, a1, a2); - default: - VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n"); - VG_(tool_panic)("memcheck:mkUifU"); - } -} - -/* --------- The Left-family of operations. --------- */ - -static IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) { - tl_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I8, - binop(Iop_Or8, a1, - assignNew(mce, Ity_I8, - /* unop(Iop_Neg8, a1)))); */ - binop(Iop_Sub8, mkU8(0), a1) ))); -} - -static IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) { - tl_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I16, - binop(Iop_Or16, a1, - assignNew(mce, Ity_I16, - /* unop(Iop_Neg16, a1)))); */ - binop(Iop_Sub16, mkU16(0), a1) ))); -} - -static IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) { - tl_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I32, - binop(Iop_Or32, a1, - assignNew(mce, Ity_I32, - /* unop(Iop_Neg32, a1)))); */ - binop(Iop_Sub32, mkU32(0), a1) ))); -} - -/* --------- 'Improvement' functions for AND/OR. --------- */ - -/* ImproveAND(data, vbits) = data OR vbits. Defined (0) data 0s give - defined (0); all other -> undefined (1). -*/ -static IRAtom* mkImproveAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I8, binop(Iop_Or8, data, vbits)); -} - -static IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I16, binop(Iop_Or16, data, vbits)); -} - -static IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I32, binop(Iop_Or32, data, vbits)); -} - -static IRAtom* mkImproveAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I64, binop(Iop_Or64, data, vbits)); -} - -static IRAtom* mkImproveANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_V128, binop(Iop_OrV128, data, vbits)); -} - -/* ImproveOR(data, vbits) = ~data OR vbits. Defined (0) data 1s give - defined (0); all other -> undefined (1). -*/ -static IRAtom* mkImproveOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I8, - binop(Iop_Or8, - assignNew(mce, Ity_I8, unop(Iop_Not8, data)), - vbits) ); -} - -static IRAtom* mkImproveOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I16, - binop(Iop_Or16, - assignNew(mce, Ity_I16, unop(Iop_Not16, data)), - vbits) ); -} - -static IRAtom* mkImproveOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I32, - binop(Iop_Or32, - assignNew(mce, Ity_I32, unop(Iop_Not32, data)), - vbits) ); -} - -static IRAtom* mkImproveOR64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I64, - binop(Iop_Or64, - assignNew(mce, Ity_I64, unop(Iop_Not64, data)), - vbits) ); -} - -static IRAtom* mkImproveORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - tl_assert(isOriginalAtom(mce, data)); - tl_assert(isShadowAtom(mce, vbits)); - tl_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_V128, - binop(Iop_OrV128, - assignNew(mce, Ity_V128, unop(Iop_NotV128, data)), - vbits) ); -} - -/* --------- Pessimising casts. --------- */ - -static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) -{ - IRType ty; - IRAtom* tmp1; - /* Note, dst_ty is a shadow type, not an original type. */ - /* First of all, collapse vbits down to a single bit. */ - tl_assert(isShadowAtom(mce,vbits)); - ty = typeOfIRExpr(mce->bb->tyenv, vbits); - tmp1 = NULL; - switch (ty) { - case Ity_I1: - tmp1 = vbits; - break; - case Ity_I8: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE8, vbits, mkU8(0))); - break; - case Ity_I16: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE16, vbits, mkU16(0))); - break; - case Ity_I32: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE32, vbits, mkU32(0))); - break; - case Ity_I64: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE64, vbits, mkU64(0))); - break; - default: - VG_(tool_panic)("mkPCastTo(1)"); - } - tl_assert(tmp1); - /* Now widen up to the dst type. */ - switch (dst_ty) { - case Ity_I1: - return tmp1; - case Ity_I8: - return assignNew(mce, Ity_I8, unop(Iop_1Sto8, tmp1)); - case Ity_I16: - return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1)); - case Ity_I32: - return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1)); - case Ity_I64: - return assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1)); - case Ity_V128: - tmp1 = assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1)); - tmp1 = assignNew(mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1)); - return tmp1; - default: - ppIRType(dst_ty); - VG_(tool_panic)("mkPCastTo(2)"); - } -} - - -/*------------------------------------------------------------*/ -/*--- Emit a test and complaint if something is undefined. ---*/ -/*------------------------------------------------------------*/ - -/* Set the annotations on a dirty helper to indicate that the stack - pointer and instruction pointers might be read. This is the - behaviour of all 'emit-a-complaint' style functions we might - call. */ - -static void setHelperAnns ( MCEnv* mce, IRDirty* di ) { - di->nFxState = 2; - di->fxState[0].fx = Ifx_Read; - di->fxState[0].offset = mce->layout->offset_SP; - di->fxState[0].size = mce->layout->sizeof_SP; - di->fxState[1].fx = Ifx_Read; - di->fxState[1].offset = mce->layout->offset_IP; - di->fxState[1].size = mce->layout->sizeof_IP; -} - - -/* Check the supplied **original** atom for undefinedness, and emit a - complaint if so. Once that happens, mark it as defined. This is - possible because the atom is either a tmp or literal. If it's a - tmp, it will be shadowed by a tmp, and so we can set the shadow to - be defined. In fact as mentioned above, we will have to allocate a - new tmp to carry the new 'defined' shadow value, and update the - original->tmp mapping accordingly; we cannot simply assign a new - value to an existing shadow tmp as this breaks SSAness -- resulting - in the post-instrumentation sanity checker spluttering in disapproval. -*/ -static void complainIfUndefined ( MCEnv* mce, IRAtom* atom ) -{ - IRAtom* vatom; - IRType ty; - Int sz; - IRDirty* di; - IRAtom* cond; - - /* Since the original expression is atomic, there's no duplicated - work generated by making multiple V-expressions for it. So we - don't really care about the possibility that someone else may - also create a V-interpretion for it. */ - tl_assert(isOriginalAtom(mce, atom)); - vatom = expr2vbits( mce, atom ); - tl_assert(isShadowAtom(mce, vatom)); - tl_assert(sameKindedAtoms(atom, vatom)); - - ty = typeOfIRExpr(mce->bb->tyenv, vatom); - - /* sz is only used for constructing the error message */ - sz = ty==Ity_I1 ? 0 : sizeofIRType(ty); - - cond = mkPCastTo( mce, Ity_I1, vatom ); - /* cond will be 0 if all defined, and 1 if any not defined. */ - - switch (sz) { - case 0: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check0_fail)", - &MC_(helperc_value_check0_fail), - mkIRExprVec_0() - ); - break; - case 1: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check1_fail)", - &MC_(helperc_value_check1_fail), - mkIRExprVec_0() - ); - break; - case 4: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check4_fail)", - &MC_(helperc_value_check4_fail), - mkIRExprVec_0() - ); - break; - default: - di = unsafeIRDirty_0_N( 1/*regparms*/, - "MC_(helperc_complain_undef)", - &MC_(helperc_complain_undef), - mkIRExprVec_1( mkIRExpr_HWord( sz )) - ); - break; - } - di->guard = cond; - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di)); - - /* Set the shadow tmp to be defined. First, update the - orig->shadow tmp mapping to reflect the fact that this shadow is - getting a new value. */ - tl_assert(isIRAtom(vatom)); - /* sameKindedAtoms ... */ - if (vatom->tag == Iex_RdTmp) { - tl_assert(atom->tag == Iex_RdTmp); - newShadowTmp(mce, atom->Iex.RdTmp.tmp); - assign(mce->bb, findShadowTmp(mce, atom->Iex.RdTmp.tmp), - definedOfType(ty)); - } -} - - -/*------------------------------------------------------------*/ -/*--- Shadowing PUTs/GETs, and indexed variants thereof ---*/ -/*------------------------------------------------------------*/ - -/* Examine the always-defined sections declared in layout to see if - the (offset,size) section is within one. Note, is is an error to - partially fall into such a region: (offset,size) should either be - completely in such a region or completely not-in such a region. -*/ -static Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size ) -{ - Int minoffD, maxoffD, i; - Int minoff = offset; - Int maxoff = minoff + size - 1; - tl_assert((minoff & ~0xFFFF) == 0); - tl_assert((maxoff & ~0xFFFF) == 0); - - for (i = 0; i < mce->layout->n_alwaysDefd; i++) { - minoffD = mce->layout->alwaysDefd[i].offset; - maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1; - tl_assert((minoffD & ~0xFFFF) == 0); - tl_assert((maxoffD & ~0xFFFF) == 0); - - if (maxoff < minoffD || maxoffD < minoff) - continue; /* no overlap */ - if (minoff >= minoffD && maxoff <= maxoffD) - return True; /* completely contained in an always-defd section */ - - VG_(tool_panic)("memcheck:isAlwaysDefd:partial overlap"); - } - return False; /* could not find any containing section */ -} - - -/* Generate into bb suitable actions to shadow this Put. If the state - slice is marked 'always defined', do nothing. Otherwise, write the - supplied V bits to the shadow state. We can pass in either an - original atom or a V-atom, but not both. In the former case the - relevant V-bits are then generated from the original. -*/ -static -void do_shadow_PUT ( MCEnv* mce, Int offset, - IRAtom* atom, IRAtom* vatom ) -{ - IRType ty; - if (atom) { - tl_assert(!vatom); - tl_assert(isOriginalAtom(mce, atom)); - vatom = expr2vbits( mce, atom ); - } else { - tl_assert(vatom); - tl_assert(isShadowAtom(mce, vatom)); - } - - ty = typeOfIRExpr(mce->bb->tyenv, vatom); - tl_assert(ty != Ity_I1); - if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { - /* later: no ... */ - /* emit code to emit a complaint if any of the vbits are 1. */ - /* complainIfUndefined(mce, atom); */ - } else { - /* Do a plain shadow Put. */ - stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) ); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GETI (passed in in pieces). -*/ -static -void do_shadow_PUTI ( MCEnv* mce, - IRRegArray* descr, IRAtom* ix, Int bias, IRAtom* atom ) -{ - IRAtom* vatom; - IRType ty, tyS; - Int arrSize;; - - tl_assert(isOriginalAtom(mce,atom)); - vatom = expr2vbits( mce, atom ); - tl_assert(sameKindedAtoms(atom, vatom)); - ty = descr->elemTy; - tyS = shadowType(ty); - arrSize = descr->nElems * sizeofIRType(ty); - tl_assert(ty != Ity_I1); - tl_assert(isOriginalAtom(mce,ix)); - complainIfUndefined(mce,ix); - if (isAlwaysDefd(mce, descr->base, arrSize)) { - /* later: no ... */ - /* emit code to emit a complaint if any of the vbits are 1. */ - /* complainIfUndefined(mce, atom); */ - } else { - /* Do a cloned version of the Put that refers to the shadow - area. */ - IRRegArray* new_descr - = mkIRRegArray( descr->base + mce->layout->total_sizeB, - tyS, descr->nElems); - stmt( mce->bb, IRStmt_PutI( mkIRPutI( new_descr, ix, bias, vatom ) )); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GET (passed in in pieces). -*/ -static -IRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty ) -{ - IRType tyS = shadowType(ty); - tl_assert(ty != Ity_I1); - if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { - /* Always defined, return all zeroes of the relevant type */ - return definedOfType(tyS); - } else { - /* return a cloned version of the Get that refers to the shadow - area. */ - return IRExpr_Get( offset + mce->layout->total_sizeB, tyS ); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GETI (passed in in pieces). -*/ -static -IRExpr* shadow_GETI ( MCEnv* mce, IRRegArray* descr, IRAtom* ix, Int bias ) -{ - IRType ty = descr->elemTy; - IRType tyS = shadowType(ty); - Int arrSize = descr->nElems * sizeofIRType(ty); - tl_assert(ty != Ity_I1); - tl_assert(isOriginalAtom(mce,ix)); - complainIfUndefined(mce,ix); - if (isAlwaysDefd(mce, descr->base, arrSize)) { - /* Always defined, return all zeroes of the relevant type */ - return definedOfType(tyS); - } else { - /* return a cloned version of the Get that refers to the shadow - area. */ - IRRegArray* new_descr - = mkIRRegArray( descr->base + mce->layout->total_sizeB, - tyS, descr->nElems); - return IRExpr_GetI( new_descr, ix, bias ); - } -} - - -/*------------------------------------------------------------*/ -/*--- Generating approximations for unknown operations, ---*/ -/*--- using lazy-propagate semantics ---*/ -/*------------------------------------------------------------*/ - -/* Lazy propagation of undefinedness from two values, resulting in the - specified shadow type. -*/ -static -IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 ) -{ - /* force everything via 32-bit intermediaries. */ - IRAtom* at; - tl_assert(isShadowAtom(mce,va1)); - tl_assert(isShadowAtom(mce,va2)); - at = mkPCastTo(mce, Ity_I32, va1); - at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2)); - at = mkPCastTo(mce, finalVty, at); - return at; -} - - -/* Do the lazy propagation game from a null-terminated vector of - atoms. This is presumably the arguments to a helper call, so the - IRCallee info is also supplied in order that we can know which - arguments should be ignored (via the .mcx_mask field). -*/ -static -IRAtom* mkLazyN ( MCEnv* mce, - IRAtom** exprvec, IRType finalVtype, IRCallee* cee ) -{ - Int i; - IRAtom* here; - IRAtom* curr = definedOfType(Ity_I32); - for (i = 0; exprvec[i]; i++) { - tl_assert(i < 32); - tl_assert(isOriginalAtom(mce, exprvec[i])); - /* Only take notice of this arg if the callee's mc-exclusion - mask does not say it is to be excluded. */ - if (cee->mcx_mask & (1<name, i); - } else { - /* calculate the arg's definedness, and pessimistically merge - it in. */ - here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, exprvec[i]) ); - curr = mkUifU32(mce, here, curr); - } - } - return mkPCastTo(mce, finalVtype, curr ); -} - - -/*------------------------------------------------------------*/ -/*--- Generating expensive sequences for exact carry-chain ---*/ -/*--- propagation in add/sub and related operations. ---*/ -/*------------------------------------------------------------*/ - -static -__attribute__((unused)) -IRAtom* expensiveAdd32 ( MCEnv* mce, IRAtom* qaa, IRAtom* qbb, - IRAtom* aa, IRAtom* bb ) -{ - IRAtom *a_min, *b_min, *a_max, *b_max; - IRType ty; - IROp opAND, opOR, opXOR, opNOT, opADD; - - tl_assert(isShadowAtom(mce,qaa)); - tl_assert(isShadowAtom(mce,qbb)); - tl_assert(isOriginalAtom(mce,aa)); - tl_assert(isOriginalAtom(mce,bb)); - tl_assert(sameKindedAtoms(qaa,aa)); - tl_assert(sameKindedAtoms(qbb,bb)); - - ty = Ity_I32; - opAND = Iop_And32; - opOR = Iop_Or32; - opXOR = Iop_Xor32; - opNOT = Iop_Not32; - opADD = Iop_Add32; - - // a_min = aa & ~qaa - a_min = assignNew(mce,ty, - binop(opAND, aa, - assignNew(mce,ty, unop(opNOT, qaa)))); - - // b_min = bb & ~qbb - b_min = assignNew(mce,ty, - binop(opAND, bb, - assignNew(mce,ty, unop(opNOT, qbb)))); - - // a_max = aa | qaa - a_max = assignNew(mce,ty, binop(opOR, aa, qaa)); - - // b_max = bb | qbb - b_max = assignNew(mce,ty, binop(opOR, bb, qbb)); - - // result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max)) - return - assignNew(mce,ty, - binop( opOR, - assignNew(mce,ty, binop(opOR, qaa, qbb)), - assignNew(mce,ty, - binop(opXOR, assignNew(mce,ty, binop(opADD, a_min, b_min)), - assignNew(mce,ty, binop(opADD, a_max, b_max)) - ) - ) - ) - ); -} - - -/*------------------------------------------------------------*/ -/*--- Helpers for dealing with vector primops. ---*/ -/*------------------------------------------------------------*/ - -/* Vector pessimisation -- pessimise within each lane individually. */ - -static IRAtom* mkPCast8x16 ( MCEnv* mce, IRAtom* at ) -{ - return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ8x16, at)); -} - -static IRAtom* mkPCast16x8 ( MCEnv* mce, IRAtom* at ) -{ - return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ16x8, at)); -} - -static IRAtom* mkPCast32x4 ( MCEnv* mce, IRAtom* at ) -{ - return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ32x4, at)); -} - -static IRAtom* mkPCast64x2 ( MCEnv* mce, IRAtom* at ) -{ - return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ64x2, at)); -} - -static IRAtom* mkPCast128x1 ( MCEnv* mce, IRAtom* at ) -{ - return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ128x1, at)); -} - -/* Here's a simple scheme capable of handling ops derived from SSE1 - code and while only generating ops that can be efficiently - implemented in SSE1. */ - -/* All-lanes versions are straightforward: - - binary32Fx4(x,y) ==> PCast32x4(UifUV128(x#,y#)) - - unary32Fx4(x,y) ==> PCast32x4(x#) - - Lowest-lane-only versions are more complex: - - binary32F0x4(x,y) ==> SetV128lo32( - x#, - PCast32(V128to32(UifUV128(x#,y#))) - ) - - This is perhaps not so obvious. In particular, it's faster to - do a V128-bit UifU and then take the bottom 32 bits than the more - obvious scheme of taking the bottom 32 bits of each operand - and doing a 32-bit UifU. Basically since UifU is fast and - chopping lanes off vector values is slow. - - Finally: - - unary32F0x4(x) ==> SetV128lo32( - x#, - PCast32(V128to32(x#)) - ) - - Where: - - PCast32(v#) = 1Sto32(CmpNE32(v#,0)) - PCast32x4(v#) = CmpNEZ32x4(v#) -*/ - -static -IRAtom* binary32Fx4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - tl_assert(isShadowAtom(mce, vatomY)); - at = mkUifUV128(mce, vatomX, vatomY); - at = assignNew(mce, Ity_V128, mkPCast32x4(mce, at)); - return at; -} - -static -IRAtom* unary32Fx4 ( MCEnv* mce, IRAtom* vatomX ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - at = assignNew(mce, Ity_V128, mkPCast32x4(mce, vatomX)); - return at; -} - -static -IRAtom* binary32F0x4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - tl_assert(isShadowAtom(mce, vatomY)); - at = mkUifUV128(mce, vatomX, vatomY); - at = assignNew(mce, Ity_I32, unop(Iop_V128to32, at)); - at = mkPCastTo(mce, Ity_I32, at); - at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at)); - return at; -} - -static -IRAtom* unary32F0x4 ( MCEnv* mce, IRAtom* vatomX ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - at = assignNew(mce, Ity_I32, unop(Iop_V128to32, vatomX)); - at = mkPCastTo(mce, Ity_I32, at); - at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at)); - return at; -} - -/* --- ... and ... 64Fx2 versions of the same ... --- */ - -static -IRAtom* binary64Fx2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - tl_assert(isShadowAtom(mce, vatomY)); - at = mkUifUV128(mce, vatomX, vatomY); - at = assignNew(mce, Ity_V128, mkPCast64x2(mce, at)); - return at; -} - -static -IRAtom* unary64Fx2 ( MCEnv* mce, IRAtom* vatomX ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - at = assignNew(mce, Ity_V128, mkPCast64x2(mce, vatomX)); - return at; -} - -static -IRAtom* binary64F0x2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - tl_assert(isShadowAtom(mce, vatomY)); - at = mkUifUV128(mce, vatomX, vatomY); - at = assignNew(mce, Ity_I64, unop(Iop_V128to64, at)); - at = mkPCastTo(mce, Ity_I64, at); - at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at)); - return at; -} - -static -IRAtom* unary64F0x2 ( MCEnv* mce, IRAtom* vatomX ) -{ - IRAtom* at; - tl_assert(isShadowAtom(mce, vatomX)); - at = assignNew(mce, Ity_I64, unop(Iop_V128to64, vatomX)); - at = mkPCastTo(mce, Ity_I64, at); - at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at)); - return at; -} - -/* --- --- Vector saturated narrowing --- --- */ - -/* This is quite subtle. What to do is simple: - - Let the original narrowing op be QNarrowW{S,U}xN. Produce: - - the-narrowing-op( PCastWxN(vatom1), PCastWxN(vatom2)) - - Why this is right is not so simple. Consider a lane in the args, - vatom1 or 2, doesn't matter. - - After the PCast, that lane is all 0s (defined) or all - 1s(undefined). - - Both signed and unsigned saturating narrowing of all 0s produces - all 0s, which is what we want. - - The all-1s case is more complex. Unsigned narrowing interprets an - all-1s input as the largest unsigned integer, and so produces all - 1s as a result since that is the largest unsigned value at the - smaller width. - - Signed narrowing interprets all 1s as -1. Fortunately, -1 narrows - to -1, so we still wind up with all 1s at the smaller width. - - So: In short, pessimise the args, then apply the original narrowing - op. -*/ -static -IRAtom* vectorNarrowV128 ( MCEnv* mce, IROp narrow_op, - IRAtom* vatom1, IRAtom* vatom2) -{ - IRAtom *at1, *at2, *at3; - IRAtom* (*pcast)( MCEnv*, IRAtom* ); - switch (narrow_op) { - case Iop_QNarrowBin32Sto16Sx8: pcast = mkPCast32x4; break; - case Iop_QNarrowBin16Sto8Sx16: pcast = mkPCast16x8; break; - case Iop_QNarrowBin16Sto8Ux16: pcast = mkPCast16x8; break; - default: VG_(tool_panic)("vectorNarrowV128"); - } - tl_assert(isShadowAtom(mce,vatom1)); - tl_assert(isShadowAtom(mce,vatom2)); - at1 = assignNew(mce, Ity_V128, pcast(mce, vatom1)); - at2 = assignNew(mce, Ity_V128, pcast(mce, vatom2)); - at3 = assignNew(mce, Ity_V128, binop(narrow_op, at1, at2)); - return at3; -} - - -/* --- --- Vector integer arithmetic --- --- */ - -/* Simple ... UifU the args and per-lane pessimise the results. */ -static -IRAtom* binary8Ix16 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) -{ - IRAtom* at; - at = mkUifUV128(mce, vatom1, vatom2); - at = mkPCast8x16(mce, at); - return at; -} - -static -IRAtom* binary16Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) -{ - IRAtom* at; - at = mkUifUV128(mce, vatom1, vatom2); - at = mkPCast16x8(mce, at); - return at; -} - -static -IRAtom* binary32Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) -{ - IRAtom* at; - at = mkUifUV128(mce, vatom1, vatom2); - at = mkPCast32x4(mce, at); - return at; -} - -static -IRAtom* binary64Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) -{ - IRAtom* at; - at = mkUifUV128(mce, vatom1, vatom2); - at = mkPCast64x2(mce, at); - return at; -} - -static -IRAtom* binary128Ix1 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) -{ - IRAtom* at; - at = mkUifUV128(mce, vatom1, vatom2); - at = mkPCast128x1(mce, at); - return at; -} - -/*------------------------------------------------------------*/ -/*--- Generate shadow values from all kinds of IRExprs. ---*/ -/*------------------------------------------------------------*/ - -static -IRAtom* expr2vbits_Binop ( MCEnv* mce, - IROp op, - IRAtom* atom1, IRAtom* atom2 ) -{ - IRType and_or_ty; - IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*); - IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*); - IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*); - - IRAtom* vatom1 = expr2vbits( mce, atom1 ); - IRAtom* vatom2 = expr2vbits( mce, atom2 ); - - tl_assert(isOriginalAtom(mce,atom1)); - tl_assert(isOriginalAtom(mce,atom2)); - tl_assert(isShadowAtom(mce,vatom1)); - tl_assert(isShadowAtom(mce,vatom2)); - tl_assert(sameKindedAtoms(atom1,vatom1)); - tl_assert(sameKindedAtoms(atom2,vatom2)); - switch (op) { - - /* V128-bit SIMD (SSE2-esque) */ - - case Iop_ShrN16x8: - case Iop_ShrN32x4: - case Iop_ShrN64x2: - case Iop_SarN16x8: - case Iop_SarN32x4: - case Iop_ShlN16x8: - case Iop_ShlN32x4: - case Iop_ShlN64x2: - /* Same scheme as with all other shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_V128, binop(op, vatom1, atom2)); - - case Iop_QSub8Ux16: - case Iop_QSub8Sx16: - case Iop_Sub8x16: - case Iop_MulHi8Sx16: - case Iop_MulHi8Ux16: - case Iop_Min8Ux16: - case Iop_Max8Ux16: - case Iop_CmpGT8Sx16: - case Iop_CmpEQ8x16: - case Iop_Avg8Ux16: - case Iop_QAdd8Ux16: - case Iop_QAdd8Sx16: - case Iop_Add8x16: - return binary8Ix16(mce, vatom1, vatom2); - - case Iop_QSub16Ux8: - case Iop_QSub16Sx8: - case Iop_Sub16x8: - case Iop_Mul16x8: - case Iop_MulHi16Sx8: - case Iop_MulHi16Ux8: - case Iop_Min16Sx8: - case Iop_Max16Sx8: - case Iop_CmpGT16Sx8: - case Iop_CmpEQ16x8: - case Iop_Avg16Ux8: - case Iop_QAdd16Ux8: - case Iop_QAdd16Sx8: - case Iop_Add16x8: - return binary16Ix8(mce, vatom1, vatom2); - - case Iop_Sub32x4: - case Iop_QSub32Sx4: - case Iop_QSub32Ux4: - case Iop_CmpGT32Sx4: - case Iop_CmpEQ32x4: - case Iop_Add32x4: - case Iop_QAdd32Ux4: - case Iop_QAdd32Sx4: - return binary32Ix4(mce, vatom1, vatom2); - - case Iop_Sub64x2: - case Iop_QSub64Ux2: - case Iop_QSub64Sx2: - case Iop_Avg64Ux2: - case Iop_Avg64Sx2: - case Iop_Add64x2: - case Iop_QAdd64Ux2: - case Iop_QAdd64Sx2: - return binary64Ix2(mce, vatom1, vatom2); - - case Iop_Add128x1: - case Iop_Sub128x1: - case Iop_CmpNEZ128x1: - return binary128Ix1(mce, vatom1, vatom2); - - case Iop_QNarrowBin32Sto16Sx8: - case Iop_QNarrowBin16Sto8Sx16: - case Iop_QNarrowBin16Sto8Ux16: - return vectorNarrowV128(mce, op, vatom1, vatom2); - - case Iop_Sub64Fx2: - case Iop_Mul64Fx2: - case Iop_Min64Fx2: - case Iop_Max64Fx2: - case Iop_Div64Fx2: - case Iop_CmpLT64Fx2: - case Iop_CmpLE64Fx2: - case Iop_CmpEQ64Fx2: - case Iop_Add64Fx2: - return binary64Fx2(mce, vatom1, vatom2); - - case Iop_Sub64F0x2: - case Iop_Mul64F0x2: - case Iop_Min64F0x2: - case Iop_Max64F0x2: - case Iop_Div64F0x2: - case Iop_CmpLT64F0x2: - case Iop_CmpLE64F0x2: - case Iop_CmpEQ64F0x2: - case Iop_Add64F0x2: - return binary64F0x2(mce, vatom1, vatom2); - - /* V128-bit SIMD (SSE1-esque) */ - - case Iop_Sub32Fx4: - case Iop_Mul32Fx4: - case Iop_Min32Fx4: - case Iop_Max32Fx4: - case Iop_Div32Fx4: - case Iop_CmpLT32Fx4: - case Iop_CmpLE32Fx4: - case Iop_CmpEQ32Fx4: - case Iop_Add32Fx4: - return binary32Fx4(mce, vatom1, vatom2); - - case Iop_Sub32F0x4: - case Iop_Mul32F0x4: - case Iop_Min32F0x4: - case Iop_Max32F0x4: - case Iop_Div32F0x4: - case Iop_CmpLT32F0x4: - case Iop_CmpLE32F0x4: - case Iop_CmpEQ32F0x4: - case Iop_Add32F0x4: - return binary32F0x4(mce, vatom1, vatom2); - - /* V128-bit data-steering */ - case Iop_SetV128lo32: - case Iop_SetV128lo64: - case Iop_64HLtoV128: - case Iop_InterleaveLO64x2: - case Iop_InterleaveLO32x4: - case Iop_InterleaveLO16x8: - case Iop_InterleaveLO8x16: - case Iop_InterleaveHI64x2: - case Iop_InterleaveHI32x4: - case Iop_InterleaveHI16x8: - case Iop_InterleaveHI8x16: - return assignNew(mce, Ity_V128, binop(op, vatom1, vatom2)); - - /* Scalar floating point */ - - // case Iop_RoundF64: - case Iop_F64toI64S: - case Iop_I64StoF64: - /* First arg is I32 (rounding mode), second is F64 or I64 - (data). */ - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_PRemC3210F64: case Iop_PRem1C3210F64: - /* Takes two F64 args. */ - case Iop_F64toI32S: - case Iop_F64toF32: - /* First arg is I32 (rounding mode), second is F64 (data). */ - return mkLazy2(mce, Ity_I32, vatom1, vatom2); - - case Iop_F64toI16S: - /* First arg is I32 (rounding mode), second is F64 (data). */ - return mkLazy2(mce, Ity_I16, vatom1, vatom2); - - case Iop_ScaleF64: - case Iop_Yl2xF64: - case Iop_Yl2xp1F64: - case Iop_PRemF64: - case Iop_AtanF64: - case Iop_AddF64: - case Iop_DivF64: - case Iop_SubF64: - case Iop_MulF64: - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_CmpF64: - return mkLazy2(mce, Ity_I32, vatom1, vatom2); - - /* non-FP after here */ - - case Iop_DivModU64to32: - case Iop_DivModS64to32: - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_16HLto32: - return assignNew(mce, Ity_I32, binop(op, vatom1, vatom2)); - case Iop_32HLto64: - return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2)); - - case Iop_MullS32: - case Iop_MullU32: { - IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); - IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32); - return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32)); - } - - case Iop_MullS16: - case Iop_MullU16: { - IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); - IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16); - return assignNew(mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16)); - } - - case Iop_MullS8: - case Iop_MullU8: { - IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); - IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8); - return assignNew(mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8)); - } - - case Iop_Add32: -# if 0 - return expensiveAdd32(mce, vatom1,vatom2, atom1,atom2); -# endif - case Iop_Sub32: - case Iop_Mul32: - return mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); - - case Iop_Mul16: - case Iop_Add16: - case Iop_Sub16: - return mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); - - case Iop_Sub8: - case Iop_Add8: - return mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); - - case Iop_CmpLE32S: case Iop_CmpLE32U: - case Iop_CmpLT32U: case Iop_CmpLT32S: - case Iop_CmpEQ32: case Iop_CmpNE32: - return mkPCastTo(mce, Ity_I1, mkUifU32(mce, vatom1,vatom2)); - - case Iop_CmpEQ16: case Iop_CmpNE16: - return mkPCastTo(mce, Ity_I1, mkUifU16(mce, vatom1,vatom2)); - - case Iop_CmpEQ8: case Iop_CmpNE8: - return mkPCastTo(mce, Ity_I1, mkUifU8(mce, vatom1,vatom2)); - - case Iop_Shl32: case Iop_Shr32: case Iop_Sar32: - /* Complain if the shift amount is undefined. Then simply - shift the first arg's V bits by the real shift amount. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I32, binop(op, vatom1, atom2)); - - case Iop_Shl16: case Iop_Shr16: case Iop_Sar16: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I16, binop(op, vatom1, atom2)); - - case Iop_Shl8: case Iop_Shr8: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I8, binop(op, vatom1, atom2)); - - case Iop_Shl64: case Iop_Shr64: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I64, binop(op, vatom1, atom2)); - - case Iop_AndV128: - uifu = mkUifUV128; difd = mkDifDV128; - and_or_ty = Ity_V128; improve = mkImproveANDV128; goto do_And_Or; - case Iop_And64: - uifu = mkUifU64; difd = mkDifD64; - and_or_ty = Ity_I64; improve = mkImproveAND64; goto do_And_Or; - case Iop_And32: - uifu = mkUifU32; difd = mkDifD32; - and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or; - case Iop_And16: - uifu = mkUifU16; difd = mkDifD16; - and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or; - case Iop_And8: - uifu = mkUifU8; difd = mkDifD8; - and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or; - - case Iop_OrV128: - uifu = mkUifUV128; difd = mkDifDV128; - and_or_ty = Ity_V128; improve = mkImproveORV128; goto do_And_Or; - case Iop_Or64: - uifu = mkUifU64; difd = mkDifD64; - and_or_ty = Ity_I64; improve = mkImproveOR64; goto do_And_Or; - case Iop_Or32: - uifu = mkUifU32; difd = mkDifD32; - and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or; - case Iop_Or16: - uifu = mkUifU16; difd = mkDifD16; - and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or; - case Iop_Or8: - uifu = mkUifU8; difd = mkDifD8; - and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or; - - do_And_Or: - return - assignNew( - mce, - and_or_ty, - difd(mce, uifu(mce, vatom1, vatom2), - difd(mce, improve(mce, atom1, vatom1), - improve(mce, atom2, vatom2) ) ) ); - - case Iop_Xor8: - return mkUifU8(mce, vatom1, vatom2); - case Iop_Xor16: - return mkUifU16(mce, vatom1, vatom2); - case Iop_Xor32: - return mkUifU32(mce, vatom1, vatom2); - case Iop_Xor64: - return mkUifU64(mce, vatom1, vatom2); - case Iop_XorV128: - return mkUifUV128(mce, vatom1, vatom2); - - default: - ppIROp(op); - VG_(tool_panic)("memcheck:expr2vbits_Binop"); - } -} - - -static -IRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom ) -{ - IRAtom* vatom = expr2vbits( mce, atom ); - tl_assert(isOriginalAtom(mce,atom)); - switch (op) { - - case Iop_Sqrt64Fx2: - return unary64Fx2(mce, vatom); - - case Iop_Sqrt64F0x2: - return unary64F0x2(mce, vatom); - - case Iop_Sqrt32Fx4: - case Iop_RecipEst32Fx4: - return unary32Fx4(mce, vatom); - - case Iop_Sqrt32F0x4: - case Iop_RSqrtEst32F0x4: - case Iop_RecipEst32F0x4: - return unary32F0x4(mce, vatom); - - case Iop_32UtoV128: - case Iop_64UtoV128: - return assignNew(mce, Ity_V128, unop(op, vatom)); - - case Iop_F32toF64: - case Iop_I32StoF64: - case Iop_NegF64: - case Iop_SinF64: - case Iop_CosF64: - case Iop_TanF64: - case Iop_SqrtF64: - case Iop_AbsF64: - case Iop_2xm1F64: - return mkPCastTo(mce, Ity_I64, vatom); - - case Iop_32Sto64: - case Iop_32Uto64: - case Iop_V128to64: - case Iop_V128HIto64: - return assignNew(mce, Ity_I64, unop(op, vatom)); - - case Iop_64to32: - case Iop_64HIto32: - case Iop_1Uto32: - case Iop_8Uto32: - case Iop_16Uto32: - case Iop_16Sto32: - case Iop_8Sto32: - return assignNew(mce, Ity_I32, unop(op, vatom)); - - case Iop_8Sto16: - case Iop_8Uto16: - case Iop_32to16: - case Iop_32HIto16: - return assignNew(mce, Ity_I16, unop(op, vatom)); - - case Iop_1Uto8: - case Iop_16to8: - case Iop_32to8: - return assignNew(mce, Ity_I8, unop(op, vatom)); - - case Iop_32to1: - return assignNew(mce, Ity_I1, unop(Iop_32to1, vatom)); - - case Iop_ReinterpF64asI64: - case Iop_ReinterpI64asF64: - case Iop_ReinterpI32asF32: - case Iop_NotV128: - case Iop_Not64: - case Iop_Not32: - case Iop_Not16: - case Iop_Not8: - case Iop_Not1: - return vatom; - - default: - ppIROp(op); - VG_(tool_panic)("memcheck:expr2vbits_Unop"); - } -} - - -/* Worker function; do not call directly. */ -static -IRAtom* expr2vbits_LDle_WRK ( MCEnv* mce, IRType ty, IRAtom* addr, UInt bias ) -{ - void* helper; - HChar* hname; - IRDirty* di; - IRTemp datavbits; - IRAtom* addrAct; - - tl_assert(isOriginalAtom(mce,addr)); - - /* First, emit a definedness test for the address. This also sets - the address (shadow) to 'defined' following the test. */ - complainIfUndefined( mce, addr ); - - /* Now cook up a call to the relevant helper function, to read the - data V bits from shadow memory. */ - ty = shadowType(ty); - switch (ty) { - case Ity_I64: helper = &MC_(helperc_LOADV8); - hname = "MC_(helperc_LOADV8)"; - break; - case Ity_I32: helper = &MC_(helperc_LOADV4); - hname = "MC_(helperc_LOADV4)"; - break; - case Ity_I16: helper = &MC_(helperc_LOADV2); - hname = "MC_(helperc_LOADV2)"; - break; - case Ity_I8: helper = &MC_(helperc_LOADV1); - hname = "MC_(helperc_LOADV1)"; - break; - default: ppIRType(ty); - VG_(tool_panic)("memcheck:do_shadow_LDle"); - } - - /* Generate the actual address into addrAct. */ - if (bias == 0) { - addrAct = addr; - } else { - IROp mkAdd; - IRAtom* eBias; - IRType tyAddr = mce->hWordTy; - tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); - mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; - eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); - addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) ); - } - - /* We need to have a place to park the V bits we're just about to - read. */ - datavbits = newIRTemp(mce->bb->tyenv, ty); - di = unsafeIRDirty_1_N( datavbits, - 1/*regparms*/, hname, helper, - mkIRExprVec_1( addrAct )); - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di) ); - - return mkexpr(datavbits); -} - - -static -IRAtom* expr2vbits_LDle ( MCEnv* mce, IRType ty, IRAtom* addr, UInt bias ) -{ - IRAtom *v64hi, *v64lo; - switch (shadowType(ty)) { - case Ity_I8: - case Ity_I16: - case Ity_I32: - case Ity_I64: - return expr2vbits_LDle_WRK(mce, ty, addr, bias); - case Ity_V128: - v64lo = expr2vbits_LDle_WRK(mce, Ity_I64, addr, bias); - v64hi = expr2vbits_LDle_WRK(mce, Ity_I64, addr, bias+8); - return assignNew( mce, - Ity_V128, - binop(Iop_64HLtoV128, v64hi, v64lo)); - default: - VG_(tool_panic)("expr2vbits_LDle"); - } -} - - -static -IRAtom* expr2vbits_ITE ( MCEnv* mce, - IRAtom* cond, IRAtom* iftrue, IRAtom* iffalse ) -{ - IRAtom *vbitsC, *vbits0, *vbits1; - IRType ty; - /* Given ITE(cond,iftrue,iffalse), generate - ITE(cond,iftrue#,iffalse#) `UifU` PCast(cond#) - That is, steer the V bits like the originals, but trash the - result if the steering value is undefined. This gives - lazy propagation. */ - tl_assert(isOriginalAtom(mce, cond)); - tl_assert(isOriginalAtom(mce, iftrue)); - tl_assert(isOriginalAtom(mce, iffalse)); - - vbitsC = expr2vbits(mce, cond); - vbits0 = expr2vbits(mce, iffalse); - vbits1 = expr2vbits(mce, iftrue); - ty = typeOfIRExpr(mce->bb->tyenv, vbits0); - - return - mkUifU(mce, ty, assignNew(mce, ty, IRExpr_ITE(cond, vbits1, vbits0)), - mkPCastTo(mce, ty, vbitsC) ); -} - -/* --------- This is the main expression-handling function. --------- */ - -static -IRExpr* expr2vbits ( MCEnv* mce, IRExpr* e ) -{ - switch (e->tag) { - - case Iex_Get: - return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty ); - - case Iex_GetI: - return shadow_GETI( mce, e->Iex.GetI.descr, - e->Iex.GetI.ix, e->Iex.GetI.bias ); - - case Iex_RdTmp: - return IRExpr_RdTmp( findShadowTmp(mce, e->Iex.RdTmp.tmp) ); - - case Iex_Const: - return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e))); - - case Iex_Binop: - return expr2vbits_Binop( - mce, - e->Iex.Binop.op, - e->Iex.Binop.arg1, e->Iex.Binop.arg2 - ); - - case Iex_Unop: - return expr2vbits_Unop( mce, e->Iex.Unop.op, e->Iex.Unop.arg ); - - case Iex_Load: - return expr2vbits_LDle( mce, e->Iex.Load.ty, - e->Iex.Load.addr, 0/*addr bias*/ ); - - case Iex_CCall: - return mkLazyN( mce, e->Iex.CCall.args, - e->Iex.CCall.retty, - e->Iex.CCall.cee ); - - case Iex_ITE: - return expr2vbits_ITE( mce, e->Iex.ITE.cond, e->Iex.ITE.iftrue, - e->Iex.ITE.iffalse); - - default: - VG_(printf)("\n"); - ppIRExpr(e); - VG_(printf)("\n"); - VG_(tool_panic)("memcheck: expr2vbits"); - } -} - -/*------------------------------------------------------------*/ -/*--- Generate shadow stmts from all kinds of IRStmts. ---*/ -/*------------------------------------------------------------*/ - -/* Widen a value to the host word size. */ - -static -IRExpr* zwidenToHostWord ( MCEnv* mce, IRAtom* vatom ) -{ - IRType ty, tyH; - - /* vatom is vbits-value and as such can only have a shadow type. */ - tl_assert(isShadowAtom(mce,vatom)); - - ty = typeOfIRExpr(mce->bb->tyenv, vatom); - tyH = mce->hWordTy; - - if (tyH == Ity_I32) { - switch (ty) { - case Ity_I32: return vatom; - case Ity_I16: return assignNew(mce, tyH, unop(Iop_16Uto32, vatom)); - case Ity_I8: return assignNew(mce, tyH, unop(Iop_8Uto32, vatom)); - default: goto unhandled; - } - } else { - goto unhandled; - } - unhandled: - VG_(printf)("\nty = "); ppIRType(ty); VG_(printf)("\n"); - VG_(tool_panic)("zwidenToHostWord"); -} - - -/* Generate a shadow store. addr is always the original address atom. - You can pass in either originals or V-bits for the data atom, but - obviously not both. */ - -static -void do_shadow_STle ( MCEnv* mce, - IRAtom* addr, UInt bias, - IRAtom* data, IRAtom* vdata ) -{ - IROp mkAdd; - IRType ty, tyAddr; - IRDirty *di, *diLo64, *diHi64; - IRAtom *addrAct, *addrLo64, *addrHi64; - IRAtom *vdataLo64, *vdataHi64; - IRAtom *eBias, *eBias0, *eBias8; - void* helper = NULL; - HChar* hname = NULL; - - tyAddr = mce->hWordTy; - mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; - tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); - - di = diLo64 = diHi64 = NULL; - eBias = eBias0 = eBias8 = NULL; - addrAct = addrLo64 = addrHi64 = NULL; - vdataLo64 = vdataHi64 = NULL; - - if (data) { - tl_assert(!vdata); - tl_assert(isOriginalAtom(mce, data)); - tl_assert(bias == 0); - vdata = expr2vbits( mce, data ); - } else { - tl_assert(vdata); - } - - tl_assert(isOriginalAtom(mce,addr)); - tl_assert(isShadowAtom(mce,vdata)); - - ty = typeOfIRExpr(mce->bb->tyenv, vdata); - - /* First, emit a definedness test for the address. This also sets - the address (shadow) to 'defined' following the test. */ - complainIfUndefined( mce, addr ); - - /* Now decide which helper function to call to write the data V - bits into shadow memory. */ - switch (ty) { - case Ity_V128: /* we'll use the helper twice */ - case Ity_I64: helper = &MC_(helperc_STOREV8); - hname = "MC_(helperc_STOREV8)"; - break; - case Ity_I32: helper = &MC_(helperc_STOREV4); - hname = "MC_(helperc_STOREV4)"; - break; - case Ity_I16: helper = &MC_(helperc_STOREV2); - hname = "MC_(helperc_STOREV2)"; - break; - case Ity_I8: helper = &MC_(helperc_STOREV1); - hname = "MC_(helperc_STOREV1)"; - break; - default: VG_(tool_panic)("memcheck:do_shadow_STle"); - } - - if (ty == Ity_V128) { - - /* V128-bit case */ - /* See comment in next clause re 64-bit regparms */ - eBias0 = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); - addrLo64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias0) ); - vdataLo64 = assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata)); - diLo64 = unsafeIRDirty_0_N( - 1/*regparms*/, hname, helper, - mkIRExprVec_2( addrLo64, vdataLo64 )); - - eBias8 = tyAddr==Ity_I32 ? mkU32(bias+8) : mkU64(bias+8); - addrHi64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias8) ); - vdataHi64 = assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata)); - diHi64 = unsafeIRDirty_0_N( - 1/*regparms*/, hname, helper, - mkIRExprVec_2( addrHi64, vdataHi64 )); - - setHelperAnns( mce, diLo64 ); - setHelperAnns( mce, diHi64 ); - stmt( mce->bb, IRStmt_Dirty(diLo64) ); - stmt( mce->bb, IRStmt_Dirty(diHi64) ); - - } else { - - /* 8/16/32/64-bit cases */ - /* Generate the actual address into addrAct. */ - if (bias == 0) { - addrAct = addr; - } else { - eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); - addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) ); - } - - if (ty == Ity_I64) { - /* We can't do this with regparm 2 on 32-bit platforms, since - the back ends aren't clever enough to handle 64-bit - regparm args. Therefore be different. */ - di = unsafeIRDirty_0_N( - 1/*regparms*/, hname, helper, - mkIRExprVec_2( addrAct, vdata )); - } else { - di = unsafeIRDirty_0_N( - 2/*regparms*/, hname, helper, - mkIRExprVec_2( addrAct, - zwidenToHostWord( mce, vdata ))); - } - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di) ); - } - -} - - -/* Do lazy pessimistic propagation through a dirty helper call, by - looking at the annotations on it. This is the most complex part of - Memcheck. */ - -static IRType szToITy ( Int n ) -{ - switch (n) { - case 1: return Ity_I8; - case 2: return Ity_I16; - case 4: return Ity_I32; - case 8: return Ity_I64; - default: VG_(tool_panic)("szToITy(memcheck)"); - } -} - -static -void do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) -{ - Int i, n, offset, toDo, gSz, gOff; - IRAtom *src, *here, *curr; - IRType tyAddr, tySrc, tyDst; - IRTemp dst; - - /* First check the guard. */ - complainIfUndefined(mce, d->guard); - - /* Now round up all inputs and PCast over them. */ - curr = definedOfType(Ity_I32); - - /* Inputs: unmasked args */ - for (i = 0; d->args[i]; i++) { - if (d->cee->mcx_mask & (1<args[i]) ); - curr = mkUifU32(mce, here, curr); - } - } - - /* Inputs: guest state that we read. */ - for (i = 0; i < d->nFxState; i++) { - tl_assert(d->fxState[i].fx != Ifx_None); - if (d->fxState[i].fx == Ifx_Write) - continue; - - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) { - if (0) - VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", - d->fxState[i].offset, d->fxState[i].size ); - continue; - } - - /* This state element is read or modified. So we need to - consider it. If larger than 8 bytes, deal with it in 8-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - if (gSz == 0) break; - n = gSz <= 8 ? gSz : 8; - /* update 'curr' with UifU of the state slice - gOff .. gOff+n-1 */ - tySrc = szToITy( n ); - src = assignNew( mce, tySrc, - shadow_GET(mce, gOff, tySrc ) ); - here = mkPCastTo( mce, Ity_I32, src ); - curr = mkUifU32(mce, here, curr); - gSz -= n; - gOff += n; - } - - } - - /* Inputs: memory. First set up some info needed regardless of - whether we're doing reads or writes. */ - tyAddr = Ity_INVALID; - - if (d->mFx != Ifx_None) { - /* Because we may do multiple shadow loads/stores from the same - base address, it's best to do a single test of its - definedness right now. Post-instrumentation optimisation - should remove all but this test. */ - tl_assert(d->mAddr); - complainIfUndefined(mce, d->mAddr); - - tyAddr = typeOfIRExpr(mce->bb->tyenv, d->mAddr); - tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64); - tl_assert(tyAddr == mce->hWordTy); /* not really right */ - } - - /* Deal with memory inputs (reads or modifies) */ - if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) { - offset = 0; - toDo = d->mSize; - /* chew off 32-bit chunks */ - while (toDo >= 4) { - here = mkPCastTo( - mce, Ity_I32, - expr2vbits_LDle ( mce, Ity_I32, - d->mAddr, d->mSize - toDo ) - ); - curr = mkUifU32(mce, here, curr); - toDo -= 4; - } - /* chew off 16-bit chunks */ - while (toDo >= 2) { - here = mkPCastTo( - mce, Ity_I32, - expr2vbits_LDle ( mce, Ity_I16, - d->mAddr, d->mSize - toDo ) - ); - curr = mkUifU32(mce, here, curr); - toDo -= 2; - } - tl_assert(toDo == 0); /* also need to handle 1-byte excess */ - } - - /* Whew! So curr is a 32-bit V-value summarising pessimistically - all the inputs to the helper. Now we need to re-distribute the - results to all destinations. */ - - /* Outputs: the destination temporary, if there is one. */ - if (d->tmp != IRTemp_INVALID) { - dst = findShadowTmp(mce, d->tmp); - tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp); - assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) ); - } - - /* Outputs: guest state that we write or modify. */ - for (i = 0; i < d->nFxState; i++) { - tl_assert(d->fxState[i].fx != Ifx_None); - if (d->fxState[i].fx == Ifx_Read) - continue; - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) - continue; - /* This state element is written or modified. So we need to - consider it. If larger than 8 bytes, deal with it in 8-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - if (gSz == 0) break; - n = gSz <= 8 ? gSz : 8; - /* Write suitably-casted 'curr' to the state slice - gOff .. gOff+n-1 */ - tyDst = szToITy( n ); - do_shadow_PUT( mce, gOff, - NULL, /* original atom */ - mkPCastTo( mce, tyDst, curr ) ); - gSz -= n; - gOff += n; - } - } - - /* Outputs: memory that we write or modify. */ - if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) { - offset = 0; - toDo = d->mSize; - /* chew off 32-bit chunks */ - while (toDo >= 4) { - do_shadow_STle( mce, d->mAddr, d->mSize - toDo, - NULL, /* original data */ - mkPCastTo( mce, Ity_I32, curr ) ); - toDo -= 4; - } - /* chew off 16-bit chunks */ - while (toDo >= 2) { - do_shadow_STle( mce, d->mAddr, d->mSize - toDo, - NULL, /* original data */ - mkPCastTo( mce, Ity_I16, curr ) ); - toDo -= 2; - } - tl_assert(toDo == 0); /* also need to handle 1-byte excess */ - } - -} - - -/*------------------------------------------------------------*/ -/*--- Memcheck main ---*/ -/*------------------------------------------------------------*/ - -static Bool isBogusAtom ( IRAtom* at ) -{ - ULong n = 0; - IRConst* con; - tl_assert(isIRAtom(at)); - if (at->tag == Iex_RdTmp) - return False; - tl_assert(at->tag == Iex_Const); - con = at->Iex.Const.con; - switch (con->tag) { - case Ico_U8: n = (ULong)con->Ico.U8; break; - case Ico_U16: n = (ULong)con->Ico.U16; break; - case Ico_U32: n = (ULong)con->Ico.U32; break; - case Ico_U64: n = (ULong)con->Ico.U64; break; - default: ppIRExpr(at); tl_assert(0); - } - /* VG_(printf)("%llx\n", n); */ - return (n == 0xFEFEFEFF - || n == 0x80808080 - || n == 0x1010101 - || n == 1010100); -} - -__attribute__((unused)) -static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st ) -{ - Int i; - IRExpr* e; - switch (st->tag) { - case Ist_WrTmp: - e = st->Ist.WrTmp.data; - switch (e->tag) { - case Iex_Get: - case Iex_RdTmp: - return False; - case Iex_Unop: - return isBogusAtom(e->Iex.Unop.arg); - case Iex_Binop: - return isBogusAtom(e->Iex.Binop.arg1) - || isBogusAtom(e->Iex.Binop.arg2); - case Iex_ITE: - return isBogusAtom(e->Iex.ITE.cond) - || isBogusAtom(e->Iex.ITE.iftrue) - || isBogusAtom(e->Iex.ITE.iffalse); - case Iex_Load: - return isBogusAtom(e->Iex.Load.addr); - case Iex_CCall: - for (i = 0; e->Iex.CCall.args[i]; i++) - if (isBogusAtom(e->Iex.CCall.args[i])) - return True; - return False; - default: - goto unhandled; - } - case Ist_Put: - return isBogusAtom(st->Ist.Put.data); - case Ist_Store: - return isBogusAtom(st->Ist.Store.addr) - || isBogusAtom(st->Ist.Store.data); - case Ist_Exit: - return isBogusAtom(st->Ist.Exit.guard); - default: - unhandled: - ppIRStmt(st); - VG_(tool_panic)("hasBogusLiterals"); - } -} - -IRSB* mc_instrument ( void* closureV, - IRSB* bb_in, VexGuestLayout* layout, - VexGuestExtents* vge, - IRType gWordTy, IRType hWordTy ) -{ - Bool verboze = False; //True; - - /* Bool hasBogusLiterals = False; */ - - Int i, j, first_stmt; - IRStmt* st; - MCEnv mce; - - /* Set up BB */ - IRSB* bb = emptyIRSB(); - bb->tyenv = deepCopyIRTypeEnv(bb_in->tyenv); - bb->next = deepCopyIRExpr(bb_in->next); - bb->jumpkind = bb_in->jumpkind; - - /* Set up the running environment. Only .bb is modified as we go - along. */ - mce.bb = bb; - mce.layout = layout; - mce.n_originalTmps = bb->tyenv->types_used; - mce.hWordTy = hWordTy; - mce.tmpMap = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp)); - for (i = 0; i < mce.n_originalTmps; i++) - mce.tmpMap[i] = IRTemp_INVALID; - - /* Iterate over the stmts. */ - - for (i = 0; i < bb_in->stmts_used; i++) { - st = bb_in->stmts[i]; - if (!st) continue; - - tl_assert(isFlatIRStmt(st)); - - /* - if (!hasBogusLiterals) { - hasBogusLiterals = checkForBogusLiterals(st); - if (hasBogusLiterals) { - VG_(printf)("bogus: "); - ppIRStmt(st); - VG_(printf)("\n"); - } - } - */ - first_stmt = bb->stmts_used; - - if (verboze) { - ppIRStmt(st); - VG_(printf)("\n\n"); - } - - switch (st->tag) { - - case Ist_WrTmp: - assign( bb, findShadowTmp(&mce, st->Ist.WrTmp.tmp), - expr2vbits( &mce, st->Ist.WrTmp.data) ); - break; - - case Ist_Put: - do_shadow_PUT( &mce, - st->Ist.Put.offset, - st->Ist.Put.data, - NULL /* shadow atom */ ); - break; - - case Ist_PutI: - do_shadow_PUTI( &mce, - st->Ist.PutI.details->descr, - st->Ist.PutI.details->ix, - st->Ist.PutI.details->bias, - st->Ist.PutI.details->data ); - break; - - case Ist_Store: - do_shadow_STle( &mce, st->Ist.Store.addr, 0/* addr bias */, - st->Ist.Store.data, - NULL /* shadow data */ ); - break; - - case Ist_Exit: - /* if (!hasBogusLiterals) */ - complainIfUndefined( &mce, st->Ist.Exit.guard ); - break; - - case Ist_Dirty: - do_shadow_Dirty( &mce, st->Ist.Dirty.details ); - break; - - case Ist_IMark: - case Ist_NoOp: - break; - - default: - VG_(printf)("\n"); - ppIRStmt(st); - VG_(printf)("\n"); - VG_(tool_panic)("memcheck: unhandled IRStmt"); - - } /* switch (st->tag) */ - - if (verboze) { - for (j = first_stmt; j < bb->stmts_used; j++) { - VG_(printf)(" "); - ppIRStmt(bb->stmts[j]); - VG_(printf)("\n"); - } - VG_(printf)("\n"); - } - - addStmtToIRSB(bb, st); - - } - - /* Now we need to complain if the jump target is undefined. */ - first_stmt = bb->stmts_used; - - if (verboze) { - VG_(printf)("bb->next = "); - ppIRExpr(bb->next); - VG_(printf)("\n\n"); - } - - complainIfUndefined( &mce, bb->next ); - - if (verboze) { - for (j = first_stmt; j < bb->stmts_used; j++) { - VG_(printf)(" "); - ppIRStmt(bb->stmts[j]); - VG_(printf)("\n"); - } - VG_(printf)("\n"); - } - - return bb; -} -#endif /* UNUSED */ - -/*--------------------------------------------------------------------*/ -/*--- end test_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/useful/test_main.h b/VEX/useful/test_main.h deleted file mode 100644 index 720900f9ba..0000000000 --- a/VEX/useful/test_main.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* Copy this file (test_main.h.in) to test_main.h, and edit */ - -/* DEBUG RUN, ON V */ -#if 1 -#define TEST_N_ITERS 1 -#define TEST_N_BBS 1 -#define TEST_FLAGS (1<<7)|(0<<6)|(1<<3)|(0<<2)|(0<<1)|(0<<0) -#endif - -/* CHECKING RUN, ON V */ -#if 0 -#define TEST_N_ITERS 1 -#define TEST_N_BBS 100000 -#define TEST_FLAGS 0 -#endif - -/* PROFILING RUN, NATIVE */ -#if 0 -#define TEST_N_ITERS 100 -#define TEST_N_BBS 1000 -#define TEST_FLAGS 0 -#endif - -/* PROFILING RUN, REDUCED WORKLOAD */ -#if 0 -#define TEST_N_ITERS 3 -#define TEST_N_BBS 1000 -#define TEST_FLAGS 0 -#endif - diff --git a/VEX/useful/test_main.h.base b/VEX/useful/test_main.h.base deleted file mode 100644 index 218b323c6e..0000000000 --- a/VEX/useful/test_main.h.base +++ /dev/null @@ -1,31 +0,0 @@ - -/* Copy this file (test_main.h.in) to test_main.h, and edit */ - -/* DEBUG RUN, ON V */ -#if 1 -#define TEST_N_ITERS 1 -#define TEST_N_BBS 1 -#define TEST_FLAGS (1<<7) -#endif - -/* CHECKING RUN, ON V */ -#if 0 -#define TEST_N_ITERS 1 -#define TEST_N_BBS 100000 -#define TEST_FLAGS 0 -#endif - -/* PROFILING RUN, NATIVE */ -#if 0 -#define TEST_N_ITERS 100 -#define TEST_N_BBS 1000 -#define TEST_FLAGS 0 -#endif - -/* PROFILING RUN, REDUCED WORKLOAD */ -#if 0 -#define TEST_N_ITERS 3 -#define TEST_N_BBS 1000 -#define TEST_FLAGS 0 -#endif - diff --git a/auxprogs/Makefile.am b/auxprogs/Makefile.am index b68cbac05a..f5be90eb19 100644 --- a/auxprogs/Makefile.am +++ b/auxprogs/Makefile.am @@ -21,7 +21,8 @@ LTP_FILTERS = \ filters/select03 \ filters/munmap01 -LTP_PATCHES = +LTP_PATCHES = \ + ltp-patches/openat2.patch EXTRA_DIST = \ docs/valgrind-listener-manpage.xml \ @@ -171,8 +172,8 @@ endif endif # Linux Test Project -LTP_VERSION=20250930 -LTP_SHA256_SUM=048fa4d69ddbe8a94aa15da9bdc85713ab07a0abbc3de2b8bdd9757644aef1e4 +LTP_VERSION=20260130 +LTP_SHA256_SUM=5effc9d3eb3f5cd45d47e8ac3d78f59cb8f3f73c8598a2f182ef5b40ddfff311 LTP_TAR_NAME=ltp-full-$(LTP_VERSION).tar.xz LTP_URL=https://github.com/linux-test-project/ltp/releases/download/$(LTP_VERSION)/$(LTP_TAR_NAME) LTP_TAR=$(AUX_CHECK_DIR)/$(LTP_TAR_NAME) diff --git a/auxprogs/getoff.c b/auxprogs/getoff.c index 30d9cded1d..73e48e77ae 100644 --- a/auxprogs/getoff.c +++ b/auxprogs/getoff.c @@ -148,7 +148,7 @@ int main (int argc, char** argv) dummy_link_map[off] = off; if (dlinfo ((void*)dummy_link_map, RTLD_DI_TLS_MODID, &modid_offset) == 0) { - assert(modid_offset >= 0 && modid_offset < MAX_LINKMAP_WORDS); + assert(modid_offset < MAX_LINKMAP_WORDS); fprintf(outputfile, "lm_modid_offset 0x%zx\n", modid_offset*sizeof(size_t)); } else { diff --git a/auxprogs/ltp-patches/README b/auxprogs/ltp-patches/README index 89df4bff10..18fb5edd36 100644 --- a/auxprogs/ltp-patches/README +++ b/auxprogs/ltp-patches/README @@ -1,5 +1,5 @@ This directory contains LTP patches that are not included in the official LTP tarball. After a new version of LTP is adopted for Valgrind testing, this patch set should be reviewed and cleaned up. Patch filenames are expected to have the -.patch suffix. +.patch suffix. Patches are also listed in ../Makefile.am. diff --git a/auxprogs/ltp-patches/openat2.patch b/auxprogs/ltp-patches/openat2.patch new file mode 100644 index 0000000000..74375ccc6f --- /dev/null +++ b/auxprogs/ltp-patches/openat2.patch @@ -0,0 +1,73 @@ +commit 767b3e519e85095dfee3a47d15a373a403fe3dab +Author: Li Wang +Date: Tue Feb 3 10:43:19 2026 +0800 + + openat2: define _GNU_SOURCE and include + + On Fedora Rawhide (glibc 2.43+), libc exposes openat2() and struct open_how, + so our configure script defines HAVE_OPENAT2 and the fallback definition in + lapi/openat2.h gets skipped. But openat20*.c never included (and + lacked _GNU_SOURCE), so the libc-provided prototype and struct stayed hidden, + so compilation failed: + + # uname -r + 6.18.0-65.fc44.x86_64 + + # rpm -qf /usr/include/fcntl.h + glibc-devel-2.43-1.fc44.x86_64 + + # nm -D /usr/lib64/libc.so.6 | grep -w openat2 + 00000000000eb890 W openat2@@GLIBC_2.43 + + # make -C testcase/kernel/syscalls/openat2 + openat201.c:27:62: error: invalid application of ‘sizeof’ to incomplete type ‘struct open_how’ + 27 | {&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, 0, &how, sizeof(*how)}, + + Define _GNU_SOURCE and include in openat2 tests to make the + prototype available and fix the build. + + Signed-off-by: Li Wang + Reviewed-by: Petr Vorel + +diff --git a/testcases/kernel/syscalls/openat2/openat201.c b/testcases/kernel/syscalls/openat2/openat201.c +index ecd63b150..40ac2f6d9 100644 +--- a/testcases/kernel/syscalls/openat2/openat201.c ++++ b/testcases/kernel/syscalls/openat2/openat201.c +@@ -4,6 +4,9 @@ + * + * Basic openat2() test. + */ ++#define _GNU_SOURCE ++#include ++ + #include "tst_test.h" + #include "lapi/openat2.h" + +diff --git a/testcases/kernel/syscalls/openat2/openat202.c b/testcases/kernel/syscalls/openat2/openat202.c +index 6d1b5a67c..329c6a4a5 100644 +--- a/testcases/kernel/syscalls/openat2/openat202.c ++++ b/testcases/kernel/syscalls/openat2/openat202.c +@@ -4,6 +4,9 @@ + * + * openat2() tests with various resolve flags. + */ ++#define _GNU_SOURCE ++#include ++ + #include "tst_test.h" + #include "lapi/openat2.h" + +diff --git a/testcases/kernel/syscalls/openat2/openat203.c b/testcases/kernel/syscalls/openat2/openat203.c +index 6ac49ef4c..cd0c00d75 100644 +--- a/testcases/kernel/syscalls/openat2/openat203.c ++++ b/testcases/kernel/syscalls/openat2/openat203.c +@@ -4,6 +4,9 @@ + * + * Basic openat2() test to check various failures. + */ ++#define _GNU_SOURCE ++#include ++ + #include "tst_test.h" + #include "lapi/openat2.h" + diff --git a/auxprogs/s390-check-opcodes.pl b/auxprogs/s390-check-opcodes.pl index 4e0d2c6ac1..0feec276e5 100755 --- a/auxprogs/s390-check-opcodes.pl +++ b/auxprogs/s390-check-opcodes.pl @@ -2,7 +2,6 @@ use strict; use warnings; -use Getopt::Long; #------------------------------------------------------------------ # This script assists in updating s390-opcodes.csv @@ -16,17 +15,15 @@ my $csv_file; my $opc_file; my $toir_file; -my $check_formats = 0; -my $usage = "usage: s390-check-opcodes [--check-formats] s390-opcodes.csv " +my $usage = "usage: s390-check-opcodes s390-opcodes.csv " . "s390-opc.txt guest_s390_toIR.c\n"; -GetOptions("check-formats" => \$check_formats) || die $usage; - my $num_arg = $#ARGV + 1; if ($num_arg == 0) { my $cwd = `pwd`; my ($basedir) = $cwd =~ m|(.*)/valgrind/|; + die $usage if (! defined $basedir); $csv_file = "$basedir/valgrind/docs/internals/s390-opcodes.csv"; $opc_file = "$basedir/binutils-gdb/opcodes/s390-opc.txt"; $toir_file = "$basedir/valgrind/VEX/priv/guest_s390_toIR.c"; @@ -39,12 +36,10 @@ } my %opc_desc = (); -my %opc_format = (); my %csv_desc = (); my %csv_implemented = (); my %toir_implemented = (); my %toir_decoded = (); -my %toir_format = (); my %known_arch = map {($_ => 1)} qw(g5 z900 z990 z9-109 z9-ec z10 z196 zEC12 z13 arch12 arch13 arch14 arch15); @@ -261,9 +256,6 @@ $opc_desc{$mnemonic} = $description; } - if (! exists $opc_format{$mnemonic}) { - $opc_format{$mnemonic} = $format; - } if ($description =~ /,/) { print "warning: description of $mnemonic contains comma\n"; } @@ -325,9 +317,6 @@ my $mnemonic = lc $1; $toir_implemented{$mnemonic} = 1; } - if ($line =~ /^..*s390_format_([A-Z_]+)[ ]*\([ ]*s390_irgen_([A-Z]+)/) { - $toir_format{lc $2} = $1; - } } close(TOIR); @@ -385,22 +374,5 @@ } } -#---------------------------------------------------- -# 5) Cross-check opcode formats -#---------------------------------------------------- -if ($check_formats) { - foreach my $opc (keys %toir_format) { - if (! exists $opc_format{$opc}) { - print "*** format $toir_format{$opc} does not exist in s390-opc.txt\n"; - } else { - if ($opc_format{$opc} ne $toir_format{$opc}) { - print "*** format for opcode $opc differs:\n"; - print " binutils: $opc_format{$opc}\n"; - print " toIR: $toir_format{$opc}\n"; - } - } - } -} - print "there are " . int(keys %toir_implemented) . " implemented opcodes\n"; exit 0 diff --git a/auxprogs/s390-runone b/auxprogs/s390-runone index 94eff03744..4d4c07633f 100755 --- a/auxprogs/s390-runone +++ b/auxprogs/s390-runone @@ -79,7 +79,7 @@ sub main { GetOptions("template|t" => sub { $template = 1; $build = 0; }, "build|b" => sub { $template = 0; $build = 1; }, "help|h" => \$help, - "insn|i=s" => \$insn, + "insn|i=s" => sub { $template = 1; $insn = $_[1]; }, "arch|a=s" => \$arch, "cc=s" => \$cc ) or usage(); diff --git a/auxprogs/update-demangler b/auxprogs/update-demangler index 3ac0c04ea0..2f13f4bba1 100755 --- a/auxprogs/update-demangler +++ b/auxprogs/update-demangler @@ -17,8 +17,8 @@ set -e #--------------------------------------------------------------------- # You need to modify these revision numbers for your update. -old_gcc_revision=94bea5dd6c9a06ddb6244be1e5196ff5fbe2b186 # the revision of the previous update -new_gcc_revision=7921bb4afcb7a3be8e10e63b10acfc2bfa477cae # the revision for this update +old_gcc_revision=7921bb4afcb7a3be8e10e63b10acfc2bfa477cae # the revision of the previous update +new_gcc_revision=a8290fb163443276c3df6b20024c6874f93c560c # the revision for this update # Unless the organization of demangler related files has changed, no # changes below this line should be necessary. diff --git a/cachegrind/cg_arch.c b/cachegrind/cg_arch.c index f877f95c7a..ea95aa7f15 100644 --- a/cachegrind/cg_arch.c +++ b/cachegrind/cg_arch.c @@ -435,34 +435,10 @@ configure_caches(cache_t *I1c, cache_t *D1c, cache_t *LLc, *LLc = (cache_t) { 262144, 8, 64 }; #elif defined(VGA_s390x) - // - // Here is the cache data from older machine models: - // - // I1 D1 I/D L2 - // z900 256k/256/4 256k/256/4 16MB - // z800 256k/256/4 256k/256/4 8MB - // z990 256k/256/4 256k/256/4 32MB - // z890 256k/256/4 256k/256/4 32MB - // z9 256k/256/4 256k/256/4 40MB - // - // Sources: - // (1) IBM System z9 109 Technical Introduction - // www.redbooks.ibm.com/redbooks/pdfs/sg246669.pdf - // (2) The microarchitecture of the IBM eServer z900 processor - // IBM Journal of Research and Development - // Volume 46, Number 4/5, pp 381-395, July/September 2002 - // (3) The IBM eServer z990 microprocessor - // IBM Journal of Research and Development - // Volume 48, Number 3/4, pp 295-309, May/July 2004 - // (4) Charles Webb, IBM - // - // L2 data is unfortunately incomplete. Otherwise, we could support - // machines without the ECAG insn by looking at VEX_S390X_MODEL(hwcaps). - - // Default cache configuration is z10-EC (Source: ECAG insn) - *I1c = (cache_t) { 65536, 4, 256 }; - *D1c = (cache_t) { 131072, 8, 256 }; - *LLc = (cache_t) { 50331648, 24, 256 }; + + // Should never get here as the min. required machine model can + // query cache information via the ECAG insn. + tl_assert(0); #elif defined(VGA_mips32) || defined(VGA_nanomips) diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index ee3e91c6ff..d7ef751333 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -1862,7 +1862,7 @@ static void cg_pre_clo_init(void) VG_(details_version) (NULL); VG_(details_description) ("a high-precision tracing profiler"); VG_(details_copyright_author)( - "Copyright (C) 2002-2024, and GNU GPL'd, by Nicholas Nethercote et al."); + "Copyright (C) 2002-2025, and GNU GPL'd, by Nicholas Nethercote et al."); VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 500 ); diff --git a/cachegrind/tests/Makefile.am b/cachegrind/tests/Makefile.am index 33242dfb9d..443a346ba3 100644 --- a/cachegrind/tests/Makefile.am +++ b/cachegrind/tests/Makefile.am @@ -36,12 +36,13 @@ EXTRA_DIST = \ ann2-basic.rs ann2-more-recent-than-cgout.rs \ ann2-negatives.rs ann2-past-the-end.rs \ chdir.vgtest chdir.stderr.exp \ - clreq.vgtest clreq.stderr.exp \ + clreq.vgtest \ clreq2a.vgtest clreq2a.stderr.exp \ clreq2b.vgtest clreq2b.stderr.exp \ clreq3.vgtest clreq3.stderr.exp \ dlclose.vgtest dlclose.stderr.exp dlclose.stdout.exp \ notpower2.vgtest notpower2.stderr.exp \ + replaces_malloc_client_req.vgtest replaces_malloc_client_req.stdout.exp \ test.c a.c \ wrap5.vgtest wrap5.stderr.exp wrap5.stdout.exp diff --git a/cachegrind/tests/clreq.stderr.exp b/cachegrind/tests/clreq.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cachegrind/tests/replaces_malloc_client_req.stdout.exp b/cachegrind/tests/replaces_malloc_client_req.stdout.exp new file mode 100644 index 0000000000..cc0cd1170a --- /dev/null +++ b/cachegrind/tests/replaces_malloc_client_req.stdout.exp @@ -0,0 +1,4 @@ +Tool replaces malloc? 0 +The name of the tool is cachegrind actual length 11 +Queried tool len 11 +The name of the tool [truncated] is cach actual length 11 diff --git a/cachegrind/tests/replaces_malloc_client_req.vgtest b/cachegrind/tests/replaces_malloc_client_req.vgtest new file mode 100644 index 0000000000..5f7299dd2f --- /dev/null +++ b/cachegrind/tests/replaces_malloc_client_req.vgtest @@ -0,0 +1,2 @@ +prog: ../../memcheck/tests/replaces_malloc_client_req +vgopts: -q diff --git a/cachegrind/tests/x86/Makefile.am b/cachegrind/tests/x86/Makefile.am index 1d141efc4a..a68f4c2711 100644 --- a/cachegrind/tests/x86/Makefile.am +++ b/cachegrind/tests/x86/Makefile.am @@ -15,3 +15,6 @@ AM_CXXFLAGS += @FLAG_M32@ $(FLAG_MMMX) $(FLAG_MSSE) AM_CCASFLAGS += @FLAG_M32@ fpu_28_108_SOURCES = fpu-28-108.S + +# Avoid linker warnings +fpu_28_108_LDFLAGS = @LDFLAG_NO_PIE@ diff --git a/cachegrind/tests/x86/fpu-28-108.S b/cachegrind/tests/x86/fpu-28-108.S index 54b2da6500..7f99387ff8 100644 --- a/cachegrind/tests/x86/fpu-28-108.S +++ b/cachegrind/tests/x86/fpu-28-108.S @@ -24,3 +24,8 @@ VG_SYM_ASM(main): movl $0, %eax ret +#if !defined(VGO_darwin) + .section .note.GNU-stack,"",@progbits +#endif + + diff --git a/callgrind/bbcc.c b/callgrind/bbcc.c index 47149c62f1..910d494194 100644 --- a/callgrind/bbcc.c +++ b/callgrind/bbcc.c @@ -179,7 +179,7 @@ BBCC* lookup_bbcc(BB* bb, Context* cxt) } CLG_DEBUG(2," lookup_bbcc(BB %#lx, Cxt %u, fn '%s'): %p (tid %u)\n", - bb_addr(bb), cxt->base_number, cxt->fn[0]->name, + bb_addr(bb), cxt->base_number, cxt->fn[0]->name, bbcc, bbcc ? bbcc->tid : 0); CLG_DEBUGIF(2) diff --git a/callgrind/dump.c b/callgrind/dump.c index 09a4a21529..155bd5d330 100644 --- a/callgrind/dump.c +++ b/callgrind/dump.c @@ -197,7 +197,7 @@ static void print_fn(VgFile *fp, const HChar* tag, const fn_node* fn) VG_(fprintf)(fp, "%s\n", fn->name); } -static void print_mangled_fn(VgFile *fp, const HChar* tag, +static void print_mangled_fn(VgFile *fp, const HChar* tag, Context* cxt, int rec_index) { int i; @@ -235,7 +235,7 @@ static void print_mangled_fn(VgFile *fp, const HChar* tag, if (rec_index >0) VG_(fprintf)(fp, "'%d", rec_index +1); for(i=1;isize;i++) - VG_(fprintf)(fp, "'(%u)", + VG_(fprintf)(fp, "'(%u)", cxt->fn[i]->pure_cxt->base_number); VG_(fprintf)(fp, "\n"); @@ -291,7 +291,7 @@ static Bool print_fn_pos(VgFile *fp, FnPos* last, BBCC* bbcc) last->cxt = 0; /* reprint context */ res = True; } - + if (last->cxt != bbcc->cxt) { fn_node* last_from = (last->cxt && last->cxt->size >1) ? last->cxt->fn[1] : 0; @@ -346,7 +346,7 @@ static Bool print_fn_pos(VgFile *fp, FnPos* last, BBCC* bbcc) last->cxt = bbcc->cxt; CLG_DEBUG(2, "- print_fn_pos: %s\n", res ? "changed" : ""); - + return res; } @@ -381,7 +381,7 @@ Bool get_debug_pos(BBCC* bbcc, Addr addr, AddrPos* p) Bool found_file_line; int cachepos = addr % DEBUG_CACHE_SIZE; - + if (debug_cache_addr[cachepos] == addr) { p->line = debug_cache_line[cachepos]; p->file = debug_cache_file[cachepos]; @@ -476,7 +476,7 @@ static void copy_apos(AddrPos* dst, AddrPos* src) dst->bb_addr = src->bb_addr; dst->file = src->file; dst->line = src->line; -} +} /* copy file position and init cost */ static void init_fcost(AddrCost* c, Addr addr, Addr bbaddr, file_node* file) @@ -554,7 +554,7 @@ void fprint_pos(VgFile *fp, const AddrPos* curr, const AddrPos* last) else { if (CLG_(clo).dump_instr) { int diff = curr->addr - last->addr; - if ( CLG_(clo).compress_pos && (last->addr >0) && + if ( CLG_(clo).compress_pos && (last->addr >0) && (diff > -100) && (diff < 100)) { if (diff >0) VG_(fprintf)(fp, "+%d ", diff); @@ -569,7 +569,7 @@ void fprint_pos(VgFile *fp, const AddrPos* curr, const AddrPos* last) if (CLG_(clo).dump_bb) { int diff = curr->bb_addr - last->bb_addr; - if ( CLG_(clo).compress_pos && (last->bb_addr >0) && + if ( CLG_(clo).compress_pos && (last->bb_addr >0) && (diff > -100) && (diff < 100)) { if (diff >0) VG_(fprintf)(fp, "+%d ", diff); @@ -584,7 +584,7 @@ void fprint_pos(VgFile *fp, const AddrPos* curr, const AddrPos* last) if (CLG_(clo).dump_line) { int diff = curr->line - last->line; - if ( CLG_(clo).compress_pos && (last->line >0) && + if ( CLG_(clo).compress_pos && (last->line >0) && (diff > -100) && (diff < 100)) { if (diff >0) @@ -627,7 +627,7 @@ static void fprint_fcost(VgFile *fp, AddrCost* c, AddrPos* last) c->p.file->name, c->p.line, c->p.bb_addr, c->p.addr); CLG_(print_cost)(-5, CLG_(sets).full, c->cost); } - + fprint_pos(fp, &(c->p), last); copy_apos( last, &(c->p) ); /* update last to current position */ @@ -654,17 +654,17 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, CLG_ASSERT(jcc->to !=0); CLG_ASSERT(jcc->from !=0); - + if (!get_debug_pos(jcc->to, bb_addr(jcc->to->bb), &target)) { /* if we don't have debug info, don't switch to file "???" */ target.file = last->file; } if ((jcc->jmpkind == jk_CondJump) || (jcc->jmpkind == jk_Jump)) { - + /* this is a JCC for a followed conditional or boring jump. */ CLG_ASSERT(CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost)); - + /* objects among jumps should be the same. * Otherwise this jump would have been changed to a call * (see setup_bbcc) @@ -683,7 +683,7 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, if (last->file != target.file) { print_file(fp, "jfi=", target.file); } - + if (jcc->from->cxt != jcc->to->cxt) { if (CLG_(clo).mangle_names) print_mangled_fn(fp, "jfn", @@ -691,7 +691,7 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, else print_fn(fp, "jfn", jcc->to->cxt->fn[0]); } - + if (jcc->jmpkind == jk_CondJump) { /* format: jcnd=/ */ VG_(fprintf)(fp, "jcnd=%llu/%llu ", @@ -702,7 +702,7 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, VG_(fprintf)(fp, "jump=%llu ", jcc->call_counter); } - + fprint_pos(fp, &target, last); VG_(fprintf)(fp, "\n"); fprint_pos(fp, curr, last); @@ -714,7 +714,7 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, file = jcc->to->cxt->fn[0]->file; obj = jcc->to->bb->obj; - + /* object of called position different to object of this function?*/ if (jcc->from->cxt->fn[0]->file->obj != obj) { print_obj(fp, "cob=", obj); @@ -731,7 +731,7 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last, print_fn(fp, "cfn", jcc->to->cxt->fn[0]); if (!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost)) { - VG_(fprintf)(fp, "calls=%llu ", + VG_(fprintf)(fp, "calls=%llu ", jcc->call_counter); fprint_pos(fp, &target, last); @@ -804,7 +804,7 @@ static jCC* sort_jcc_list(jCC* head) { * Print all costs of a BBCC: * - FCCs of instructions * - JCCs of the unique jump of this BB - * returns True if something was written + * returns True if something was written */ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) { @@ -843,22 +843,22 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) if (CLG_(clo).dump_bbs || CLG_(clo).dump_instr || (newCost->p.line != currCost->p.line) || (newCost->p.file != currCost->p.file)) { - + if (!CLG_(is_zero_cost)( CLG_(sets).full, currCost->cost )) { something_written = True; - + /* Output file position and inline function markers */ fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc); fprint_fcost(fp, currCost, last); } - + /* switch buffers */ currSum = 1 - currSum; currCost = &(ccSum[currSum]); newCost = &(ccSum[1-currSum]); } - + /* add line cost to current cost sum */ (*CLG_(cachesim).add_icost)(currCost->cost, bbcc, instr_info, ecounter); @@ -870,7 +870,7 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) (!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost ))) jcc_count++; - if (jcc_count>0) { + if (jcc_count>0) { if (!CLG_(is_zero_cost)( CLG_(sets).full, currCost->cost )) { /* no need to switch buffers, as position is the same */ fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc); @@ -897,7 +897,7 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) jmp++; } } - + /* jCCs at end? If yes, dump cumulated line info first */ jcc_count = 0; for(jcc=bbcc->jmp[jmp].jcc_list; jcc; jcc=jcc->next_from) { @@ -906,21 +906,21 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) (!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost ))) jcc_count++; } - + if ( (bbcc->skipped && - !CLG_(is_zero_cost)(CLG_(sets).full, bbcc->skipped)) || + !CLG_(is_zero_cost)(CLG_(sets).full, bbcc->skipped)) || (jcc_count>0) ) { - + if (!CLG_(is_zero_cost)( CLG_(sets).full, currCost->cost )) { /* no need to switch buffers, as position is the same */ fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc); fprint_fcost(fp, currCost, last); } - + get_debug_pos(bbcc, bb_jmpaddr(bb), &(currCost->p)); fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc); something_written = True; - + /* first, print skipped costs for calls */ if (bbcc->skipped && !CLG_(is_zero_cost)( CLG_(sets).full, bbcc->skipped )) { @@ -939,7 +939,7 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) CLG_ASSERT(jcc->jmp == jmp); if ( ((jcc->jmpkind != jk_Call) && (jcc->call_counter >0)) || (!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost ))) - + fprint_jcc(fp, jcc, &(currCost->p), last, ecounter); } } @@ -948,25 +948,25 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last) if (CLG_(clo).dump_bbs || CLG_(clo).dump_bb) { if (!CLG_(is_zero_cost)( CLG_(sets).full, currCost->cost )) { something_written = True; - + fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc); fprint_fcost(fp, currCost, last); } if (CLG_(clo).dump_bbs) VG_(fprintf)(fp, "\n"); - + /* when every cost was immediately written, we must have done so, * as this function is only called when there's cost in a BBCC */ CLG_ASSERT(something_written); } - + bbcc->ecounter_sum = 0; for(i=0; i<=bbcc->bb->cjmp_count; i++) bbcc->jmp[i].ecounter = 0; bbcc->ret_counter = 0; - + CLG_DEBUG(1, "- fprint_bbcc: JCCs %d\n", jcc_count); - + return something_written; } @@ -1072,7 +1072,7 @@ static void CLG_(qsort)(BBCC **a, int n, int (*cmp)(BBCC**,BBCC**)) for (pm = a; pm < a+n; pm++) { VG_(printf)(" %3ld BB %#lx, ", pm - qsort_start + 0L, - bb_addr((*pm)->bb)); + bb_addr((*pm)->bb)); CLG_(print_cxt)(9, (*pm)->cxt, (*pm)->rec_index); } } @@ -1100,14 +1100,14 @@ static void CLG_(qsort)(BBCC **a, int n, int (*cmp)(BBCC**,BBCC**)) while ((pb <= pc) && ((r=cmp(pb, pv)) <= 0)) { if (r==0) { /* same as pivot, to start */ - swap(pa,pb); pa++; + swap(pa,pb); pa++; } pb ++; } while ((pb <= pc) && ((r=cmp(pc, pv)) >= 0)) { if (r==0) { /* same as pivot, to end */ - swap(pc,pd); pd--; + swap(pc,pd); pd--; } pc --; } @@ -1122,7 +1122,7 @@ static void CLG_(qsort)(BBCC **a, int n, int (*cmp)(BBCC**,BBCC**)) /* put pivot from start into middle */ if ((s = pa-a)>0) { for(r=0;r0) { for(r=0;r0) { for(r=0;rbb)); @@ -1188,18 +1188,18 @@ static void cs_addCount(thread_info* ti) /* add BBCCs with active call in call stack of current thread. * update cost sums for active calls */ - + for(i = 0; i < CLG_(current_call_stack).sp; i++) { call_entry* e = &(CLG_(current_call_stack).entry[i]); if (e->jcc == 0) continue; - + CLG_(add_diff_cost_lz)( CLG_(sets).full, &(e->jcc->cost), e->enter_cost, CLG_(current_state).cost); bbcc = e->jcc->from; CLG_DEBUG(1, " [%2d] (tid %u), added active: %s\n", i,CLG_(current_tid),bbcc->cxt->fn[0]->name); - + if (bbcc->ecounter_sum>0 || bbcc->ret_counter>0) { /* already counted */ continue; @@ -1216,13 +1216,13 @@ static void cs_addPtr(thread_info* ti) /* add BBCCs with active call in call stack of current thread. * update cost sums for active calls */ - + for(i = 0; i < CLG_(current_call_stack).sp; i++) { call_entry* e = &(CLG_(current_call_stack).entry[i]); if (e->jcc == 0) continue; bbcc = e->jcc->from; - + if (bbcc->ecounter_sum>0 || bbcc->ret_counter>0) { /* already counted */ continue; @@ -1236,7 +1236,7 @@ static void cs_addPtr(thread_info* ti) /** * Put all BBCCs with costs into a sorted array. - * The returned arrays ends with a null pointer. + * The returned arrays ends with a null pointer. * Must be freed after dumping. */ static @@ -1245,7 +1245,7 @@ BBCC** prepare_dump(void) BBCC **array; prepare_count = 0; - + /* if we do not separate among threads, this gives all */ /* count number of BBCCs with >0 executions */ CLG_(forall_bbccs)(hash_addCount); @@ -1262,7 +1262,7 @@ BBCC** prepare_dump(void) /* allocate bbcc array, insert BBCCs and sort */ prepare_ptr = array = (BBCC**) CLG_MALLOC("cl.dump.pd.1", - (prepare_count+1) * sizeof(BBCC*)); + (prepare_count+1) * sizeof(BBCC*)); CLG_(forall_bbccs)(hash_addPtr); @@ -1376,7 +1376,7 @@ static VgFile *new_dumpfile(thread_info* ti, const HChar* trigger) if (!CLG_(clo).combine_dumps) { i = VG_(sprintf)(filename, "%s", out_file); - + if (trigger) i += VG_(sprintf)(filename+i, ".%d", out_counter); @@ -1484,7 +1484,7 @@ static VgFile *new_dumpfile(thread_info* ti, const HChar* trigger) if (fnc->dump_at_enter) { VG_(fprintf)(fp, "desc: Option: --fn-dump-at-enter=%s\n", fnc->name); - } + } if (fnc->dump_at_leave) { VG_(fprintf)(fp, "desc: Option: --fn-dump-at-leave=%s\n", fnc->name); @@ -1492,11 +1492,11 @@ static VgFile *new_dumpfile(thread_info* ti, const HChar* trigger) if (fnc->separate_callers != CLG_(clo).separate_callers) { VG_(fprintf)(fp, "desc: Option: --separate-callers%d=%s\n", fnc->separate_callers, fnc->name); - } + } if (fnc->separate_recursions != CLG_(clo).separate_recursions) { VG_(fprintf)(fp, "desc: Option: --separate-recs%d=%s\n", fnc->separate_recursions, fnc->name); - } + } fnc = fnc->next; } } @@ -1575,7 +1575,7 @@ static void close_dumpfile(VgFile *fp) fprint_cost_ln(fp, "totals: ", CLG_(dumpmap), dump_total_cost); //fprint_fcc_ln(fp, "summary: ", &dump_total_fcc); - CLG_(add_cost_lz)(CLG_(sets).full, + CLG_(add_cost_lz)(CLG_(sets).full, &CLG_(total_cost), dump_total_cost); VG_(fclose)(fp); @@ -1649,7 +1649,7 @@ static void print_bbccs_of_thread(thread_info* ti) while(1) { /* on context/function change, print old cost buffer before */ - if (lastFnPos.cxt && ((*p==0) || + if (lastFnPos.cxt && ((*p==0) || (lastFnPos.cxt != (*p)->cxt) || (lastFnPos.rec_index != (*p)->rec_index))) { if (!CLG_(is_zero_cost)( CLG_(sets).full, ccSum[currSum].cost )) { @@ -1658,18 +1658,18 @@ static void print_bbccs_of_thread(thread_info* ti) lastFnPos.cxt->fn[0]->file, 0); fprint_fcost(print_fp, &ccSum[currSum], &lastAPos); } - + if (ccSum[currSum].p.file != lastFnPos.cxt->fn[0]->file) { /* switch back to file of function */ print_file(print_fp, "fe=", lastFnPos.cxt->fn[0]->file); } VG_(fprintf)(print_fp, "\n"); } - + if (*p == 0) break; - + if (print_fn_pos(print_fp, &lastFnPos, *p)) { - + /* new function */ init_apos(&lastAPos, 0, 0, (*p)->cxt->fn[0]->file); init_fcost(&ccSum[0], 0, 0, 0); @@ -1677,31 +1677,31 @@ static void print_bbccs_of_thread(thread_info* ti) currSum = 0; last_inline_fn = 0; /* reset inline function tracking */ } - + if (CLG_(clo).dump_bbs) { /* FIXME: Specify Object of BB if different to object of fn */ int i; ULong ecounter = (*p)->ecounter_sum; VG_(fprintf)(print_fp, "bb=%#lx ", (UWord)(*p)->bb->offset); for(i = 0; i<(*p)->bb->cjmp_count;i++) { - VG_(fprintf)(print_fp, "%u %llu ", + VG_(fprintf)(print_fp, "%u %llu ", (*p)->bb->jmp[i].instr, ecounter); ecounter -= (*p)->jmp[i].ecounter; } - VG_(fprintf)(print_fp, "%u %llu\n", + VG_(fprintf)(print_fp, "%u %llu\n", (*p)->bb->instr_count, ecounter); } - + fprint_bbcc(print_fp, *p, &lastAPos); - + p++; } close_dumpfile(print_fp); VG_(free)(array); - + /* set counters of last dump */ CLG_(copy_cost)( CLG_(sets).full, ti->lastdump_cost, CLG_(current_state).cost ); @@ -1858,7 +1858,7 @@ void CLG_(init_dumps)(void) return; } thisPID = currentPID; - + if (!CLG_(clo).out_format) CLG_(clo).out_format = DEFAULT_OUTFORMAT; @@ -1876,20 +1876,20 @@ void CLG_(init_dumps)(void) /* allocate space big enough for final filenames */ filename = (HChar*) CLG_MALLOC("cl.dump.init_dumps.2", VG_(strlen)(out_file)+32); - + /* Make sure the output base file can be written. * This is used for the dump at program termination. * We stop with an error here if we can not create the * file: This is probably because of missing rights, * and trace parts wouldn't be allowed to be written, too. - */ + */ VG_(strcpy)(filename, out_file); res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_TRUNC, 0); - if (sr_isError(res)) { + if (sr_isError(res)) { res = VG_(open)(filename, VKI_O_CREAT|VKI_O_WRONLY, VKI_S_IRUSR|VKI_S_IWUSR); if (sr_isError(res)) { - file_err(); + file_err(); } } if (!sr_isError(res)) VG_(close)( (Int)sr_Res(res) ); diff --git a/callgrind/global.h b/callgrind/global.h index 174672972c..97a22bf252 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -104,10 +104,10 @@ struct _CommandLineOptions { Bool dump_instr; Bool dump_bb; Bool dump_bbs; /* Dump basic block information? */ - + /* Dump generation options */ ULong dump_every_bb; /* Dump every xxx BBs. */ - + /* Collection options */ Bool separate_threads; /* Separate threads in dump? */ Int separate_callers; /* Separate dependent on how many callers? */ @@ -162,7 +162,7 @@ struct _Statistics { ULong bb_executions; Int context_counter; - Int bb_retranslations; + Int bb_retranslations; Int distinct_objs; Int distinct_files; @@ -262,7 +262,7 @@ struct _jCC { }; -/* +/* * Info for one instruction of a basic block. */ typedef struct _InstrInfo InstrInfo; @@ -316,12 +316,12 @@ struct _BB { VgSectKind sect_kind; /* section of this BB, e.g. PLT */ UInt instr_count; - + /* filled by CLG_(get_fn_node) if debug info is available */ fn_node* fn; /* debug info for this BB */ UInt line; Bool is_entry; /* True if this BB is a function entry */ - + BBCC* bbcc_list; /* BBCCs for same BB (see next_bbcc in BBCC) */ BBCC* last_bbcc; /* Temporary: Cached for faster access (LRU) */ @@ -395,19 +395,19 @@ struct _BBCC { * across recycled valgrind ThreadId slots. * Only for lookup/assertion purposes. */ UInt rec_index; /* Recursion index in rec->bbcc for this bbcc */ - BBCC** rec_array; /* Variable sized array of pointers to + BBCC** rec_array; /* Variable sized array of pointers to * recursion BBCCs. Shared. */ ULong ret_counter; /* how often returned from jccs of this bbcc; * used to check if a dump for this BBCC is needed */ - + BBCC* next_bbcc; /* Chain of BBCCs for same BB */ BBCC* lru_next_bbcc; /* BBCC executed next the last time */ - + jCC* lru_from_jcc; /* Temporary: Cached for faster access (LRU) */ jCC* lru_to_jcc; /* Temporary: Cached for faster access (LRU) */ - FullCost skipped; /* cost for skipped functions called from + FullCost skipped; /* cost for skipped functions called from * jmp_addr. Allocated lazy */ - + BBCC* next; /* entry chain in hash */ ULong* cost; /* start of 64bit costs for this BBCC */ ULong ecounter_sum; /* execution counter for first instruction of BB */ @@ -482,7 +482,7 @@ struct _obj_node { * * is 0 if the function called is not skipped (usual case). * Otherwise, it is the last non-skipped BBCC. This one gets all - * the calls to non-skipped functions and all costs in skipped + * the calls to non-skipped functions and all costs in skipped * instructions. */ struct _call_entry { @@ -514,14 +514,14 @@ struct _exec_state { /* the signum of the handler, 0 for main thread context */ Int sig; - + /* the old call stack pointer at entering the signal handler */ Int orig_sp; - + FullCost cost; Bool collect; Context* cxt; - + /* number of conditional jumps passed in last BB */ Int jmps_passed; BBCC* bbcc; /* last BB executed */ @@ -541,7 +541,7 @@ typedef struct _cxt_hash cxt_hash; struct _cxt_hash { UInt size, entries; Context** table; -}; +}; /* Thread specific state structures, i.e. parts of a thread state. * There are variables for the current state of each part, @@ -590,7 +590,7 @@ struct _exec_stack { exec_state* entry[MAX_SIGHANDLERS]; }; -/* Thread State +/* Thread State * * This structure stores thread specific info while a thread is *not* * running. See function switch_thread() for save/restore on thread switch. @@ -676,7 +676,7 @@ struct cachesim_if void (*printstat)(Int,Int,Int); void (*add_icost)(SimCost, BBCC*, InstrInfo*, ULong); void (*finish)(void); - + void (*log_1I0D)(InstrInfo*) VG_REGPARM(1); void (*log_2I0D)(InstrInfo*, InstrInfo*) VG_REGPARM(2); void (*log_3I0D)(InstrInfo*, InstrInfo*, InstrInfo*) VG_REGPARM(3); diff --git a/callgrind/main.c b/callgrind/main.c index 54ecb178ba..69af08255f 100644 --- a/callgrind/main.c +++ b/callgrind/main.c @@ -706,8 +706,8 @@ void addEvent_D_guarded ( ClgState* clgs, InstrInfo* inode, ea, mkIRExpr_HWord( datasize ) ); regparms = 3; di = unsafeIRDirty_0_N( - regparms, - helperName, VG_(fnptr_to_fnentry)( helperAddr ), + regparms, + helperName, VG_(fnptr_to_fnentry)( helperAddr ), argv ); di->guard = guard; addStmtToIRSB( clgs->sbOut, IRStmt_Dirty(di) ); @@ -914,7 +914,7 @@ void addConstMemStoreStmt( IRSB* bbOut, UWord addr, UInt val, IRType hWordTy) IRConst_U32( addr ) : IRConst_U64( addr )), IRExpr_Const(IRConst_U32(val)) )); -} +} /* add helper call to setup_bbcc, with pointer to BB struct as argument @@ -999,7 +999,7 @@ IRSB* CLG_(instrument)( VgCallbackClosure* closure, CLG_ASSERT(Ist_IMark == st->tag); origAddr = st->Ist.IMark.addr + st->Ist.IMark.delta; - CLG_ASSERT(origAddr == st->Ist.IMark.addr + CLG_ASSERT(origAddr == st->Ist.IMark.addr + st->Ist.IMark.delta); // XXX: check no overflow /* Get BB struct (creating if necessary). @@ -1424,7 +1424,7 @@ static void zero_thread_cost(thread_info* t) if (!CLG_(current_call_stack).entry[i].jcc) continue; /* reset call counters to current for active calls */ - CLG_(copy_cost)( CLG_(sets).full, + CLG_(copy_cost)( CLG_(sets).full, CLG_(current_call_stack).entry[i].enter_cost, CLG_(current_state).cost ); CLG_(current_call_stack).entry[i].jcc->call_counter = 0; @@ -1433,7 +1433,7 @@ static void zero_thread_cost(thread_info* t) CLG_(forall_bbccs)(CLG_(zero_bbcc)); /* set counter for last dump */ - CLG_(copy_cost)( CLG_(sets).full, + CLG_(copy_cost)( CLG_(sets).full, t->lastdump_cost, CLG_(current_state).cost ); } @@ -1525,18 +1525,18 @@ static void dump_state_of_thread_togdb(thread_info* ti) ce = CLG_(get_call_entry)(i); /* if this frame is skipped, we don't have counters */ if (!ce->jcc) continue; - + from = ce->jcc->from; VG_(gdb_printf)("function-%d-%d: %s\n",t, i, from->cxt->fn[0]->name); VG_(gdb_printf)("calls-%d-%d: %llu\n",t, i, ce->jcc->call_counter); - + /* FIXME: EventSets! */ CLG_(copy_cost)( CLG_(sets).full, sum, ce->jcc->cost ); CLG_(copy_cost)( CLG_(sets).full, tmp, ce->enter_cost ); CLG_(add_diff_cost)( CLG_(sets).full, sum, ce->enter_cost, CLG_(current_state).cost ); CLG_(copy_cost)( CLG_(sets).full, ce->enter_cost, tmp ); - + mcost = CLG_(mappingcost_as_string)(CLG_(dumpmap), sum); VG_(gdb_printf)("events-%d-%d: %s\n",t, i, mcost); VG_(free)(mcost); @@ -1571,7 +1571,7 @@ static void dump_state_togdb(void) VG_(free)(evmap); /* "part:" line (number of last part. Is 0 at start */ VG_(gdb_printf)("part: %d\n", CLG_(get_dump_counter)()); - + /* threads */ th = CLG_(get_threads)(); VG_(gdb_printf)("threads:"); @@ -1584,7 +1584,7 @@ static void dump_state_togdb(void) CLG_(forall_threads)(dump_state_of_thread_togdb); } - + static void print_monitor_help ( void ) { VG_(gdb_printf) ("\n"); @@ -1610,7 +1610,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, const HChar *req) VG_(strcpy) (s, req); wcmd = VG_(strtok_r) (s, " ", &ssaveptr); - switch (VG_(keyword_id) ("help dump zero status instrumentation", + switch (VG_(keyword_id) ("help dump zero status instrumentation", wcmd, kwd_report_duplicated_matches)) { case -2: /* multiple matches */ return True; @@ -1660,7 +1660,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, const HChar *req) return True; } - default: + default: tl_assert(0); return False; } @@ -1674,7 +1674,7 @@ Bool CLG_(handle_client_request)(ThreadId tid, UWord *args, UWord *ret) return False; switch(args[0]) { - case VG_USERREQ__DUMP_STATS: + case VG_USERREQ__DUMP_STATS: CLG_(dump_profile)("Client Request", True); *ret = 0; /* meaningless */ break; @@ -2020,7 +2020,7 @@ void finish(void) CLG_(dump_profile)(0, False); if (VG_(clo_verbosity) == 0) return; - + if (VG_(clo_stats)) { VG_(message)(Vg_DebugMsg, "\n"); clg_print_stats(); @@ -2110,7 +2110,7 @@ void CLG_(post_clo_init)(void) CLG_DEBUG(1, " Using user specified value for " "--vex-iropt-register-updates\n"); } else { - CLG_DEBUG(1, + CLG_DEBUG(1, " Using default --vex-iropt-register-updates=" "sp-at-mem-access\n"); } @@ -2140,13 +2140,13 @@ void CLG_(post_clo_init)(void) CLG_DEBUG(1, " Using user specified value for " "--px-file-backed\n"); } else { - CLG_DEBUG(1, + CLG_DEBUG(1, " Using default --px-file-backed=" "sp-at-mem-access\n"); } if (VG_(clo_vex_control).iropt_unroll_thresh != 0) { - VG_(message)(Vg_UserMsg, + VG_(message)(Vg_UserMsg, "callgrind only works with --vex-iropt-unroll-thresh=0\n" "=> resetting it back to 0\n"); VG_(clo_vex_control).iropt_unroll_thresh = 0; // cannot be overridden. @@ -2157,7 +2157,7 @@ void CLG_(post_clo_init)(void) "=> resetting it back to 'no'\n"); VG_(clo_vex_control).guest_chase = False; // cannot be overridden. } - + CLG_DEBUG(1, " dump threads: %s\n", CLG_(clo).separate_threads ? "Yes":"No"); CLG_DEBUG(1, " call sep. : %d\n", CLG_(clo).separate_callers); CLG_DEBUG(1, " rec. sep. : %d\n", CLG_(clo).separate_recursions); diff --git a/configure.ac b/configure.ac index d67b72134d..1ee25ba622 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ ##------------------------------------------------------------## -# +# # The multiple-architecture stuff in this file is pretty # cryptic. Read docs/internals/multiple-architectures.txt # for at least a partial explanation of what is going on. @@ -16,15 +16,15 @@ AC_PREREQ(2.69) # Also set the (expected/last) release date here. # Do not forget to rerun ./autogen.sh m4_define([v_major_ver], [3]) -m4_define([v_minor_ver], [26]) -m4_define([v_micro_ver], [0]) +m4_define([v_minor_ver], [27]) +m4_define([v_micro_ver], [1]) m4_define([v_suffix_ver], []) m4_define([v_suffix_ver], m4_esyscmd_s([sed -n '1s/.*-[0-9]*\(codspeed[0-9]*\).*/\1/p' debian/changelog])) m4_if(m4_bregexp(v_suffix_ver, [^codspeed[0-9]+$]), [-1], [m4_fatal([invalid codspeed suffix ']v_suffix_ver[' extracted from debian/changelog])]) -m4_define([v_rel_date], ["5 Nov 2025"]) +m4_define([v_rel_date], ["20 May 2026"]) m4_define([v_version], m4_if(v_suffix_ver, [], [v_major_ver.v_minor_ver.v_micro_ver], @@ -99,7 +99,9 @@ AC_ARG_VAR([LTO_AR],[Archiver command for link time optimisation]) AC_PATH_PROG(PERL, perl) # figure out where gdb lives -AC_PATH_PROG(GDB, gdb, "/no/gdb/was/found/at/configure/time") +# MacPorts uses ggdb +AC_ARG_VAR([GDB], [Path to the GNU Debugger]) +AC_PATH_PROGS([GDB], [gdb ggdb], ["/no/gdb/was/found/at/configure/time"]) AC_DEFINE_UNQUOTED(GDB_PATH, "$GDB", [path to GDB]) # figure out how to compile assembler sources @@ -125,39 +127,21 @@ rm $tmpfile # We don't want gcc < 3.0 AC_MSG_CHECKING([for a supported version of gcc]) -# Obtain the compiler version. -# -# A few examples of how the ${CC} --version output looks like: -# -# ######## gcc variants ######## -# Arch Linux: i686-pc-linux-gnu-gcc (GCC) 4.6.2 -# Debian Linux: gcc (Debian 4.3.2-1.1) 4.3.2 -# openSUSE: gcc (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585] -# Exherbo Linux: x86_64-pc-linux-gnu-gcc (Exherbo gcc-4.6.2) 4.6.2 -# MontaVista Linux for ARM: arm-none-linux-gnueabi-gcc (Sourcery G++ Lite 2009q1-203) 4.3.3 -# OS/X 10.6: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3) -# OS/X 10.7: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00) -# -# ######## clang variants ######## -# Clang: clang version 2.9 (tags/RELEASE_29/final) -# Apple clang: Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn) -# FreeBSD clang: FreeBSD clang version 3.1 (branches/release_31 156863) 20120523 -# -# ######## Apple LLVM variants ######## -# Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) -# Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn) -# [ if test "x`${CC} --version | $SED -n -e 's/.*\Apple \(LLVM\) version.*clang.*/\1/p'`" = "xLLVM" ; then is_clang="applellvm" gcc_version=`${CC} --version | $SED -n -e 's/.*LLVM version \([0-9.]*\).*$/\1/p'` +elif test "x`${CC} --version | $SED -n -e 's/.*\Apple \(clang\) version.*clang.*/\1/p'`" = "xclang" ; +then + is_clang="applellvm" + gcc_version=`${CC} --version | $SED -n -e 's/.*clang version \([0-9.]*\).*$/\1/p'` elif test "x`${CC} --version | $SED -n -e 's/.*\(clang\) version.*/\1/p'`" = "xclang" ; then is_clang="clang" # Don't use -dumpversion with clang: it will always produce "4.2.1". gcc_version=`${CC} --version | $SED -n -e 's/.*clang version \([0-9.]*\).*$/\1/p'` -elif test "x`${CC} --version | $SED -n -e 's/icc.*\(ICC\).*/\1/p'`" = "xICC" ; +elif test "x`${CC} --version | $SED -n -e 's/icc.*\(ICC\).*/\1/p'`" = "xICC" ; then is_clang="icc" gcc_version=`${CC} -dumpversion 2>/dev/null` @@ -172,6 +156,82 @@ fi AM_CONDITIONAL(COMPILER_IS_CLANG, test $is_clang = clang -o $is_clang = applellvm) AM_CONDITIONAL(COMPILER_IS_ICC, test $is_clang = icc) +AC_CANONICAL_HOST + +# macOS: Detect the Xcode SDK path and inject it in different tools +case $host_os in + *darwin*) + AC_ARG_WITH([darwin-platform], + [ --with-darwin-platform=PLAT Specify which Darwin platform we are compiling for (macOS, iOS, etc)], + [ + # TODO: some kind of case-insensitive check? + if test "x$withval" = "xmacOS"; then + darwin_platform="macosx" + elif test "x$withval" = "xmacos"; then + darwin_platform="macosx" + elif test "x$withval" = "xiOS"; then + darwin_platform="iphoneos" + elif test "x$withval" = "xios"; then + darwin_platform="iphoneos" + else + darwin_platform="$withval" + fi + ], + [ + darwin_platform="macosx" + ]) + + AC_ARG_WITH([darwin-version], + [ --with-darwin-version=VERS Specify which version of Darwin you are targetting (useful for cross-compilation, depends on the darwin-platform)], + [ + darwin_version="$withval" + ], + [ + darwin_version="" + ]) + + AC_ARG_VAR([DEVELOPER_DIR],[Overrides the active developer directory (used in gcc, xcrun, etc)]) + AC_CHECK_PROG([XCRUN], [xcrun], [yes], [no]) + + AC_MSG_CHECKING([for Xcode SDK]) + AC_ARG_WITH([xcode-path], + [ --with-xcode-path=PATH Specify path for Xcode SDK], + [ + # Set defaults in case `xcrun` fails + xcodedir="$withval" + xcodedir_inc="$xcodedir/usr/include" + xcodedir_lib="$xcodedir/usr/lib" + # Defining DEVELOPER_DIR will override which version of gcc, xcrun, etc is being used + export DEVELOPER_DIR="$xcodedir" + ], + [ + # Use system defaults, in case `xcrun` fails + xcodedir="active developer directory" + xcodedir_inc="/usr/include" + xcodedir_lib="/usr/lib" + ]) + + darwin_sdk="$darwin_platform$darwin_version" + if test "x$XCRUN" != "xno"; then + if test "x$darwin_version" != "x"; then + if test x`xcrun --sdk $darwin_sdk --show-sdk-version` != x$darwin_version; then + AC_MSG_ERROR([Couldn't find SDK for $darwin_sdk version $darwin_version (check 'xcodebuild -showsdks' for available ones)]) + fi + fi + + xcrundir=`xcrun --sdk $darwin_sdk --show-sdk-path` + if test ! -z "$xcrundir"; then + xcodedir="$xcrundir" + xcodedir_inc="$xcodedir/usr/include" + xcodedir_lib="$xcodedir/usr/lib" + fi + else + AC_MSG_WARN([Couldn't find xcrun, most Xcode-related autodetection will be disabled and the build might fail]) + fi + AC_MSG_RESULT([$xcodedir]) + ;; +esac + # Note: m4 arguments are quoted with [ and ] so square brackets in shell # statements have to be quoted. case "${is_clang}-${gcc_version}" in @@ -201,8 +261,6 @@ esac # configure-time, and distinguishes them from the VGA_*/VGO_*/VGP_* # variables used when compiling C files. -AC_CANONICAL_HOST - AC_MSG_CHECKING([for a supported CPU]) # ARCH_MAX reflects the most that this CPU can do: for example if it @@ -224,12 +282,12 @@ AC_MSG_CHECKING([for a supported CPU]) VGCONF_PLATFORM_ARM_ARCH= case "${host_cpu}" in - i?86) + i?86) AC_MSG_RESULT([ok (${host_cpu})]) ARCH_MAX="x86" ;; - x86_64|amd64) + x86_64|amd64) AC_MSG_RESULT([ok (${host_cpu})]) ARCH_MAX="amd64" ;; @@ -314,7 +372,7 @@ case "${host_cpu}" in ARCH_MAX="riscv64" ;; - *) + *) AC_MSG_RESULT([no (${host_cpu})]) AC_MSG_ERROR([Unsupported host architecture. Sorry]) ;; @@ -337,14 +395,14 @@ CODSPEED_ONLY64BIT_DEFAULT # Check if a 64-bit only build has been requested AC_CACHE_CHECK([for a 64-bit only build], vg_cv_only64bit, - [AC_ARG_ENABLE(only64bit, + [AC_ARG_ENABLE(only64bit, [ --enable-only64bit do a 64-bit only build], [vg_cv_only64bit=$enableval], [vg_cv_only64bit=no])]) # Check if a 32-bit only build has been requested AC_CACHE_CHECK([for a 32-bit only build], vg_cv_only32bit, - [AC_ARG_ENABLE(only32bit, + [AC_ARG_ENABLE(only32bit, [ --enable-only32bit do a 32-bit only build], [vg_cv_only32bit=$enableval], [vg_cv_only32bit=no])]) @@ -376,7 +434,7 @@ case "${host_os}" in kernel=`uname -r` case "${kernel}" in - 0.*|1.*|2.0.*|2.1.*|2.2.*|2.3.*|2.4.*|2.5.*) + 0.*|1.*|2.0.*|2.1.*|2.2.*|2.3.*|2.4.*|2.5.*) AC_MSG_RESULT([unsupported (${kernel})]) AC_MSG_ERROR([Valgrind needs a Linux kernel >= 2.6]) ;; @@ -398,95 +456,221 @@ case "${host_os}" in *darwin*) AC_MSG_RESULT([ok (${host_os})]) VGCONF_OS="darwin" - AC_DEFINE([DARWIN_10_5], 100500, [DARWIN_VERS value for Mac OS X 10.5]) - AC_DEFINE([DARWIN_10_6], 100600, [DARWIN_VERS value for Mac OS X 10.6]) - AC_DEFINE([DARWIN_10_7], 100700, [DARWIN_VERS value for Mac OS X 10.7]) - AC_DEFINE([DARWIN_10_8], 100800, [DARWIN_VERS value for Mac OS X 10.8]) - AC_DEFINE([DARWIN_10_9], 100900, [DARWIN_VERS value for Mac OS X 10.9]) - AC_DEFINE([DARWIN_10_10], 101000, [DARWIN_VERS value for Mac OS X 10.10]) - AC_DEFINE([DARWIN_10_11], 101100, [DARWIN_VERS value for Mac OS X 10.11]) - AC_DEFINE([DARWIN_10_12], 101200, [DARWIN_VERS value for macOS 10.12]) - AC_DEFINE([DARWIN_10_13], 101300, [DARWIN_VERS value for macOS 10.13]) - - AC_MSG_CHECKING([for the kernel version]) - kernel=`uname -r` - - # Nb: for Darwin we set DEFAULT_SUPP here. That's because Darwin - # has only one relevant version, the OS version. The `uname` check - # is a good way to get that version (i.e. "Darwin 9.6.0" is Mac OS - # X 10.5.6, and "Darwin 10.x" is Mac OS X 10.6.x Snow Leopard, - # and possibly "Darwin 11.x" is Mac OS X 10.7.x Lion), - # and we don't know of an macros similar to __GLIBC__ to get that info. - # - # XXX: `uname -r` won't do the right thing for cross-compiles, but - # that's not a problem yet. - # - # jseward 21 Sept 2011: I seriously doubt whether V 3.7.0 will work - # on OS X 10.5.x; I haven't tested yet, and only plan to test 3.7.0 - # on 10.6.8 and 10.7.1. Although tempted to delete the configure - # time support for 10.5 (the 9.* pattern just below), I'll leave it - # in for now, just in case anybody wants to give it a try. But I'm - # assuming that 3.7.0 is a Snow Leopard and Lion-only release. + + AC_DEFUN([AC_ADD_DARWIN_VERS],[ + $1=$2 + AC_DEFINE_UNQUOTED([$1], [$$1], [DARWIN_VERS value for $3]) + AC_SUBST($1) + ]) + AC_ADD_DARWIN_VERS([DARWIN_10_5], 100500, [DARWIN_VERS value for Mac OS X 10.5]) + AC_ADD_DARWIN_VERS([DARWIN_10_6], 100600, [DARWIN_VERS value for Mac OS X 10.6 / iOS 4]) + AC_ADD_DARWIN_VERS([DARWIN_10_7], 100700, [DARWIN_VERS value for Mac OS X 10.7 / iOS 5]) + AC_ADD_DARWIN_VERS([DARWIN_10_8], 100800, [DARWIN_VERS value for Mac OS X 10.8 / iOS 6]) + AC_ADD_DARWIN_VERS([DARWIN_10_9], 100900, [DARWIN_VERS value for Mac OS X 10.9 / iOS 7]) + AC_ADD_DARWIN_VERS([DARWIN_10_10], 101000, [DARWIN_VERS value for Mac OS X 10.10 / iOS 8]) + AC_ADD_DARWIN_VERS([DARWIN_10_11], 101100, [DARWIN_VERS value for Mac OS X 10.11 / iOS 9]) + AC_ADD_DARWIN_VERS([DARWIN_10_12], 101200, [DARWIN_VERS value for macOS 10.12 / iOS 10]) + AC_ADD_DARWIN_VERS([DARWIN_10_13], 101300, [DARWIN_VERS value for macOS 10.13 / iOS 11]) + AC_ADD_DARWIN_VERS([DARWIN_10_14], 101400, [DARWIN_VERS value for macOS 10.14 / iOS 12]) + AC_ADD_DARWIN_VERS([DARWIN_10_15], 101500, [DARWIN_VERS value for macOS 10.15 / iOS 13]) + AC_ADD_DARWIN_VERS([DARWIN_11_00], 110000, [DARWIN_VERS value for macOS 11.0 / iOS 14]) + AC_ADD_DARWIN_VERS([DARWIN_12_00], 120000, [DARWIN_VERS value for macOS 12.0 / iOS 15]) + AC_ADD_DARWIN_VERS([DARWIN_13_00], 130000, [DARWIN_VERS value for macOS 13.0 / iOS 16]) + AC_ADD_DARWIN_VERS([DARWIN_14_00], 140000, [DARWIN_VERS value for macOS 14.0 / iOS 17]) + AC_ADD_DARWIN_VERS([DARWIN_15_00], 150000, [DARWIN_VERS value for macOS 15.0 / iOS 18]) + AC_ADD_DARWIN_VERS([DARWIN_15_04], 150400, [DARWIN_VERS value for macOS 15.4]) + AC_ADD_DARWIN_VERS([DARWIN_26_00], 260000, [DARWIN_VERS value for macOS / iOS 26]) + + AC_DEFINE([SDK_10_XX], 101200, [SDK_VERS value for Xcode SDK earlier than macOS 10.13 / iOS 11]) + AC_DEFINE([SDK_10_13], 101300, [SDK_VERS value for Xcode SDK macOS 10.13 / iOS 11]) + AC_DEFINE([SDK_10_14], 101400, [SDK_VERS value for Xcode SDK macOS 10.14 / iOS 12]) + AC_DEFINE([SDK_10_14_6], 101406, [SDK_VERS value for Xcode SDK macOS 10.14.6 / iOS 12]) + AC_DEFINE([SDK_10_15], 101500, [SDK_VERS value for Xcode SDK macOS 10.15 / iOS 13]) + AC_DEFINE([SDK_11_0], 110000, [SDK_VERS value for Xcode SDK macOS 11.0 / iOS 14]) + AC_DEFINE([SDK_12_0], 120000, [SDK_VERS value for Xcode SDK macOS 12.0 / iOS 15]) + AC_DEFINE([SDK_13_0], 130000, [SDK_VERS value for Xcode SDK macOS 13.0 / iOS 16]) + AC_DEFINE([SDK_14_0], 140000, [SDK_VERS value for Xcode SDK macOS 14.0 / iOS 17]) + AC_DEFINE([SDK_15_0], 150000, [SDK_VERS value for Xcode SDK macOS 15.0 / iOS 18]) + AC_DEFINE([SDK_26_0], 260000, [SDK_VERS value for Xcode SDK macOS / iOS 26]) + + # Substitute the Xcode include path detected earlier + AC_SUBST(SDK_INC_DIR, [$xcodedir_inc]) + AC_SUBST(SDK_LIB_DIR, [$xcodedir_lib]) + + AC_MSG_CHECKING([for the Darwin platform]) + case "${darwin_platform}" in + macosx) + ;; + iphoneos) + ;; + *) + AC_MSG_RESULT([unsupported Darwin platform (${darwin_platform})]) + AC_MSG_ERROR([Valgrind works on macOS (macosx) and iOS (iphoneos)]) + esac + AC_MSG_RESULT([ok (${darwin_platform})]) + + AC_MSG_CHECKING([for the kernel version]) + kernel=$darwin_version + if test "x$kernel" = "x"; then + if test "${host_cpu}" != "${build_cpu}"; then + AC_MSG_WARN([You are cross-compiling without specifying the target\'s darwin-version, valgrind might not work.]) + fi + kernel=`uname -r` + fi + + DARWIN_DRD_SUPP="darwin-drd.supp" + case "${kernel}" in - 9.*) - AC_MSG_RESULT([Darwin 9.x (${kernel}) / Mac OS X 10.5 Leopard]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_5, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin9.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin9-drd.supp ${DEFAULT_SUPP}" - ;; - 10.*) - AC_MSG_RESULT([Darwin 10.x (${kernel}) / Mac OS X 10.6 Snow Leopard]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_6, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin10.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + 1[2-6].*) + DEFAULT_SUPP="$srcdir/darwin-legacy.supp ${DEFAULT_SUPP}" ;; - 11.*) - AC_MSG_RESULT([Darwin 11.x (${kernel}) / Mac OS X 10.7 Lion]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_7, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin11.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + *) + DEFAULT_SUPP="$srcdir/darwin.supp ${DEFAULT_SUPP}" ;; + esac + + + case "${kernel}" in 12.*) AC_MSG_RESULT([Darwin 12.x (${kernel}) / Mac OS X 10.8 Mountain Lion]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_8, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin12.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_8 ;; 13.*) AC_MSG_RESULT([Darwin 13.x (${kernel}) / Mac OS X 10.9 Mavericks]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_9, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin13.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_9 ;; 14.*) AC_MSG_RESULT([Darwin 14.x (${kernel}) / Mac OS X 10.10 Yosemite]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_10, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin14.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_10 ;; 15.*) AC_MSG_RESULT([Darwin 15.x (${kernel}) / Mac OS X 10.11 El Capitan]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_11, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin15.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_11 ;; 16.*) AC_MSG_RESULT([Darwin 16.x (${kernel}) / macOS 10.12 Sierra]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_12, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin16.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_12 ;; 17.*) AC_MSG_RESULT([Darwin 17.x (${kernel}) / macOS 10.13 High Sierra]) - AC_DEFINE([DARWIN_VERS], DARWIN_10_13, [Darwin / Mac OS X version]) - DEFAULT_SUPP="$srcdir/darwin17.supp ${DEFAULT_SUPP}" - DEFAULT_SUPP="$srcdir/darwin10-drd.supp ${DEFAULT_SUPP}" + DARWIN_VERS=$DARWIN_10_13 ;; - *) - AC_MSG_RESULT([unsupported (${kernel})]) - AC_MSG_ERROR([Valgrind works on Darwin 10.x, 11.x, 12.x, 13.x, 14.x, 15.x, 16.x and 17.x (Mac OS X 10.6/7/8/9/10/11 and macOS 10.12/13)]) + 18.*) + AC_MSG_RESULT([Darwin 18.x (${kernel}) / macOS 10.14 Mojave]) + DARWIN_VERS=$DARWIN_10_14 + ;; + 19.*) + AC_MSG_RESULT([Darwin 19.x (${kernel}) / macOS 10.15 Catalina]) + DARWIN_VERS=$DARWIN_10_15 + ;; + 20.*) + AC_MSG_RESULT([Darwin 20.x (${kernel}) / macOS 11 Big Sur]) + DARWIN_VERS=$DARWIN_11_00 + ;; + 21.*) + AC_MSG_RESULT([Darwin 21.x (${kernel}) / macOS 12 Monterey]) + DARWIN_VERS=$DARWIN_12_00 + ;; + 22.*) + AC_MSG_RESULT([Darwin 22.x (${kernel}) / macOS 13 Ventura]) + DARWIN_VERS=$DARWIN_13_00 + ;; + *) + AC_MSG_RESULT([unsupported (${darwin_platform} ${kernel})]) + AC_MSG_ERROR([Valgrind works on Darwin 12.x-19.x (Mac OS X 10.8-10.11, macOS 10.12-10.15)]) ;; esac + + AC_DEFINE_UNQUOTED([DARWIN_VERS], $DARWIN_VERS, [Darwin / Mac OS X / macOS / iOS version]) + AC_SUBST(DARWIN_VERS) + DEFAULT_SUPP="$srcdir/${DARWIN_DRD_SUPP} ${DEFAULT_SUPP} $srcdir/darwin-helgrind.supp" + + AC_MSG_CHECKING([for the the minimum macOS SDK version]) + case "${darwin_platform}" in + macosx) + DARWIN_MIN_SDK="10.6" + ld_os_min_vers_arg="-macosx_version_min ${DARWIN_MIN_SDK}" + clang_os_min_vers_arg="-mmacosx-version-min=${DARWIN_MIN_SDK}" + if test $DARWIN_VERS -ge $DARWIN_11_00; then + if test $ARCH_MAX = "arm64"; then + # arm64 is only supported on macOS 11.0 and later + # this means that when you use a lower version it automatically caps it to 11.0 + DARWIN_MIN_SDK="11.0" + else + DARWIN_MIN_SDK="10.8" + fi + + # they changed the names around 11.0 + ld_os_min_vers_arg="-macos_version_min ${DARWIN_MIN_SDK}" + clang_os_min_vers_arg="-mmacos-version-min=${DARWIN_MIN_SDK}" + fi + ;; + iphoneos) + IPHONE_MIN_SDK=4 + clang_os_min_vers_arg="-miphoneos-version-min=${IPHONE_MIN_SDK}" + ld_os_min_vers_arg="-miphoneos-version-min=${IPHONE_MIN_SDK}" + ;; + *) + AC_MSG_RESULT([unsupported Darwin platform (${darwin_platform})]) + AC_MSG_ERROR([Valgrind works on macOS (macosx) and iOS (iphoneos)]) + esac + AC_MSG_RESULT([ok (${clang_os_min_vers_arg} ${ld_os_min_vers_arg})]) + + # Ensure clang receive the right minimum version argument + AC_SUBST(CLANG_OS_MIN_VERS_ARG, [$clang_os_min_vers_arg]) + AC_SUBST(LD_OS_MIN_VERS_ARG, [$ld_os_min_vers_arg]) + + AC_MSG_CHECKING([for the Xcode SDK version]) + sdkversion="legacy" + if test "x$XCRUN" != "xno"; then + sdkversion=`xcrun --sdk $darwin_sdk --show-sdk-version` + fi + case "${darwin_platform}-${sdkversion}" in + macosx-10.13*|iphoneos-11.*) + AC_DEFINE([SDK_VERS], SDK_10_13, [SDK version]) + ;; + macosx-10.14.6) + AC_DEFINE([SDK_VERS], SDK_10_14_6, [SDK version]) + ;; + macosx-10.14*|iphoneos-12.*) + AC_DEFINE([SDK_VERS], SDK_10_14, [SDK version]) + ;; + macosx-10.15*|iphoneos-13.*) + AC_DEFINE([SDK_VERS], SDK_10_15, [SDK version]) + ;; + macosx-11.*|iphoneos-14.*) + AC_DEFINE([SDK_VERS], SDK_11_0, [SDK version]) + ;; + macosx-12.*|iphoneos-15.*) + AC_DEFINE([SDK_VERS], SDK_12_0, [SDK version]) + ;; + macosx-13.*|iphoneos-16.*) + AC_DEFINE([SDK_VERS], SDK_13_0, [SDK version]) + ;; + macosx-14.*|iphoneos-17.*) + AC_DEFINE([SDK_VERS], SDK_14_0, [SDK version]) + ;; + macosx-15.*|iphoneos-18.*) + AC_DEFINE([SDK_VERS], SDK_15_0, [SDK version]) + ;; + *-26.*) + AC_DEFINE([SDK_VERS], SDK_26_0, [SDK version]) + ;; + legacy) + AC_DEFINE([SDK_VERS], SDK_10_XX, [SDK version]) + ;; + macosx-10.5*|macosx-10.6*|macosx-10.7*|macosx-10.8*|macosx-10.9*|macosx-10.10*|macosx-10.11*|macosx-10.12*) + AC_DEFINE([SDK_VERS], SDK_10_XX, [SDK version]) + ;; + iphoneos-4.*|iphoneos-5.*|iphoneos-6.*|iphoneos-7.*|iphoneos-8.*|iphoneos-9.*|iphoneos-10.*) + AC_DEFINE([SDK_VERS], SDK_10_XX, [SDK version]) + ;; + *) + AC_MSG_RESULT([unsupported (${sdkversion})]) + AC_MSG_ERROR([Valgrind works on Darwin 10.x-25.x (Mac OS X 10.6-10.11, macOS 10.12-15.0, iOS 4-18 and macOS/iOS 26)]) + ;; + esac + AC_MSG_RESULT([${sdkversion}]) ;; solaris2.11*) @@ -510,7 +694,7 @@ case "${host_os}" in DEFAULT_SUPP="$srcdir/solaris12.supp ${DEFAULT_SUPP}" ;; - *) + *) AC_MSG_RESULT([no (${host_os})]) AC_MSG_ERROR([Valgrind is operating system specific. Sorry.]) ;; @@ -523,18 +707,20 @@ esac # does not support building 32 bit programs case "$ARCH_MAX-$VGCONF_OS" in - amd64-linux|ppc64be-linux|arm64-linux|amd64-solaris) - AC_MSG_CHECKING([for 32 bit build support]) + amd64-linux|ppc64be-linux|arm64-linux|amd64-solaris|amd64-darwin|amd64-freebsd) + AC_MSG_CHECKING([for 32 bit build and execution support]) safe_CFLAGS=$CFLAGS CFLAGS="-m32" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[ return 0; ]])], [ AC_MSG_RESULT([yes]) ], [ vg_cv_only64bit="yes" AC_MSG_RESULT([no]) - ]) + ] , [ + AC_MSG_RESULT([cross compiling, assuming no]) + vg_cv_only64bit="yes"]) CFLAGS=$safe_CFLAGS;; mips64-linux) AC_MSG_CHECKING([for 32 bit build support]) @@ -595,7 +781,7 @@ AC_SUBST(VGCONF_PLATFORM_SEC_CAPS) AC_MSG_CHECKING([for a supported CPU/OS combination]) -# NB. The load address for a given platform may be specified in more +# NB. The load address for a given platform may be specified in more # than one place, in some cases, depending on whether we're doing a biarch, # 32-bit only or 64-bit only build. eg see case for amd64-linux below. # Be careful to give consistent values in all subcases. Also, all four @@ -606,83 +792,83 @@ case "$ARCH_MAX-$VGCONF_OS" in x86-linux) VGCONF_ARCH_PRI="x86" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="X86_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="X86_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" valt_load_address_sec_norml="0xUNSET" valt_load_address_sec_inner="0xUNSET" AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) - ;; + ;; amd64-linux) valt_load_address_sec_norml="0xUNSET" valt_load_address_sec_inner="0xUNSET" - if test x$vg_cv_only64bit = xyes; then + if test x$vg_cv_only64bit = xyes; then VGCONF_ARCH_PRI="amd64" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" - elif test x$vg_cv_only32bit = xyes; then - VGCONF_ARCH_PRI="x86" + elif test x$vg_cv_only32bit = xyes; then + VGCONF_ARCH_PRI="x86" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="X86_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="X86_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" - else + else VGCONF_ARCH_PRI="amd64" VGCONF_ARCH_SEC="x86" - VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX" - VGCONF_PLATFORM_SEC_CAPS="X86_LINUX" + VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX" + VGCONF_PLATFORM_SEC_CAPS="X86_LINUX" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" valt_load_address_sec_norml="0x58000000" valt_load_address_sec_inner="0x38000000" - fi + fi AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) - ;; + ;; ppc32-linux) VGCONF_ARCH_PRI="ppc32" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" valt_load_address_sec_norml="0xUNSET" valt_load_address_sec_inner="0xUNSET" AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) - ;; + ;; ppc64be-linux) valt_load_address_sec_norml="0xUNSET" valt_load_address_sec_inner="0xUNSET" - if test x$vg_cv_only64bit = xyes; then - VGCONF_ARCH_PRI="ppc64be" + if test x$vg_cv_only64bit = xyes; then + VGCONF_ARCH_PRI="ppc64be" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="PPC64BE_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="PPC64BE_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" - elif test x$vg_cv_only32bit = xyes; then - VGCONF_ARCH_PRI="ppc32" + elif test x$vg_cv_only32bit = xyes; then + VGCONF_ARCH_PRI="ppc32" VGCONF_ARCH_SEC="" - VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX" - VGCONF_PLATFORM_SEC_CAPS="" + VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" - else - VGCONF_ARCH_PRI="ppc64be" + else + VGCONF_ARCH_PRI="ppc64be" VGCONF_ARCH_SEC="ppc32" - VGCONF_PLATFORM_PRI_CAPS="PPC64BE_LINUX" - VGCONF_PLATFORM_SEC_CAPS="PPC32_LINUX" + VGCONF_PLATFORM_PRI_CAPS="PPC64BE_LINUX" + VGCONF_PLATFORM_SEC_CAPS="PPC32_LINUX" valt_load_address_pri_norml="0x58000000" valt_load_address_pri_inner="0x38000000" valt_load_address_sec_norml="0x58000000" valt_load_address_sec_inner="0x38000000" - fi + fi AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) - ;; + ;; ppc64le-linux) # Little Endian is only supported on PPC64 valt_load_address_sec_norml="0xUNSET" @@ -786,7 +972,7 @@ case "$ARCH_MAX-$VGCONF_OS" in fi AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) ;; - arm-linux) + arm-linux) VGCONF_ARCH_PRI="arm" VGCONF_PLATFORM_PRI_CAPS="ARM_LINUX" VGCONF_PLATFORM_SEC_CAPS="" @@ -838,7 +1024,7 @@ case "$ARCH_MAX-$VGCONF_OS" in valt_load_address_sec_inner="0xUNSET" AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) ;; - mips32-linux) + mips32-linux) VGCONF_ARCH_PRI="mips32" VGCONF_ARCH_SEC="" VGCONF_PLATFORM_PRI_CAPS="MIPS32_LINUX" @@ -958,7 +1144,7 @@ esac # Set up VGCONF_ARCHS_INCLUDE_. Either one or two of these become # defined. -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_X86, +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_X86, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xX86_FREEBSD \ @@ -967,21 +1153,21 @@ AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_X86, -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_DARWIN \ -o x$VGCONF_PLATFORM_PRI_CAPS = xX86_SOLARIS \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_SOLARIS ) -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_AMD64, +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_AMD64, test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_FREEBSD \ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN \ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_SOLARIS ) -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC32, - test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \ +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC32, + test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX ) -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC64, +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC64, test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64BE_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64LE_LINUX ) -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM, +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM, test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xARM_LINUX ) -AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM64, +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM64, test x$VGCONF_PLATFORM_PRI_CAPS = xARM64_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xARM64_FREEBSD ) AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_S390X, @@ -990,7 +1176,7 @@ AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS32, test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xMIPS32_LINUX ) AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS64, - test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ) + test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ) AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_NANOMIPS, test x$VGCONF_PLATFORM_PRI_CAPS = xNANOMIPS_LINUX ) AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_RISCV64, @@ -998,22 +1184,22 @@ AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_RISCV64, # Set up VGCONF_PLATFORMS_INCLUDE_. Either one or two of these # become defined. -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_LINUX, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_LINUX) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX, - test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \ +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX, + test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC64BE_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64BE_LINUX) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC64LE_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64LE_LINUX) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM_LINUX, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX \ -o x$VGCONF_PLATFORM_SEC_CAPS = xARM_LINUX) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM64_LINUX, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM64_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xARM64_LINUX) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_S390X_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \ @@ -1030,14 +1216,14 @@ AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_RISCV64_LINUX, AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_FREEBSD, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_FREEBSD \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_FREEBSD) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_FREEBSD, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_FREEBSD, test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_FREEBSD) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM64_FREEBSD, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM64_FREEBSD, test x$VGCONF_PLATFORM_PRI_CAPS = xARM64_FREEBSD) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_DARWIN, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_DARWIN) -AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_DARWIN, +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_DARWIN, test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_SOLARIS, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_SOLARIS \ @@ -1047,7 +1233,7 @@ AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_SOLARIS, # Similarly, set up VGCONF_OS_IS_. Exactly one of these becomes defined. -# Relies on the assumption that the primary and secondary targets are +# Relies on the assumption that the primary and secondary targets are # for the same OS, so therefore only necessary to test the primary. AM_CONDITIONAL(VGCONF_OS_IS_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \ @@ -1094,7 +1280,7 @@ AM_CONDITIONAL(VGCONF_HAVE_PLATFORM_SEC, AC_SUBST(VALT_LOAD_ADDRESS_PRI) AC_SUBST(VALT_LOAD_ADDRESS_SEC) AC_CACHE_CHECK([for use as an inner Valgrind], vg_cv_inner, - [AC_ARG_ENABLE(inner, + [AC_ARG_ENABLE(inner, [ --enable-inner enables self-hosting], [vg_cv_inner=$enableval], [vg_cv_inner=no])]) @@ -1113,7 +1299,7 @@ fi # Check whether we should build with the undefined beahviour sanitiser. AC_CACHE_CHECK([for using the undefined behaviour sanitiser], vg_cv_ubsan, - [AC_ARG_ENABLE(ubsan, + [AC_ARG_ENABLE(ubsan, [ --enable-ubsan enables the undefined behaviour sanitiser], [vg_cv_ubsan=$enableval], [vg_cv_ubsan=no])]) @@ -1131,31 +1317,6 @@ AC_SUBST(VG_TMPDIR, [$tmpdir]) # CodSpeed: Capstone decoder for Callgrind cycle estimation. See m4/codspeed_capstone.m4. CODSPEED_CAPSTONE -#---------------------------------------------------------------------------- -# Detect xcode path -#---------------------------------------------------------------------------- -AM_COND_IF([VGCONF_OS_IS_DARWIN], -[AC_CHECK_PROG([XCRUN], [xcrun], [yes], [no]) -AC_MSG_CHECKING([for xcode sdk include path]) -AC_ARG_WITH(xcodedir, - [ --with-xcode-path=PATH Specify path for xcode sdk includes], - [xcodedir="$withval"], - [ - if test "x$XCRUN" != "xno" -a ! -d /usr/include; then - xcrundir=`xcrun --sdk macosx --show-sdk-path` - if test -z "$xcrundir"; then - xcodedir="/usr/include" - else - xcodedir="$xcrundir/usr/include" - fi - else - xcodedir="/usr/include" - fi - ]) -AC_MSG_RESULT([$xcodedir]) -AC_DEFINE_UNQUOTED(XCODE_DIR, "$xcodedir", [xcode sdk include directory]) -AC_SUBST(XCODE_DIR, [$xcodedir])]) - #---------------------------------------------------------------------------- # Where to install gdb scripts, defaults to VG_LIBDIR (pkglibexecdir) #---------------------------------------------------------------------------- @@ -1422,6 +1583,25 @@ AC_MSG_RESULT([no]) AM_CONDITIONAL([HAVE_AT_FDCWD], [test x$ac_have_at_fdcwd = xyes]) + +# Check for MADV_GUARD_INSTALL + +AC_MSG_CHECKING([for MADV_GUARD_INSTALL]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +]], [[ + int a = MADV_GUARD_INSTALL; +]])], [ +ac_have_madv_guard_install=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_madv_guard_install=no +AC_MSG_RESULT([no]) +]) + +AM_CONDITIONAL([HAVE_MADV_GUARD_INSTALL], [test x$ac_have_madv_guard_install = xyes]) + + # Check for stpncpy function definition in string.h # This explicitly checks with _GNU_SOURCE defined since that is also # used in the test case (some systems might define it without anyway @@ -1600,7 +1780,7 @@ AC_MSG_RESULT([no]) AC_CHECK_MEMBER([pthread_mutex_t.__m_kind], [AC_DEFINE([HAVE_PTHREAD_MUTEX_T__M_KIND], - 1, + 1, [Define to 1 if pthread_mutex_t has a member called __m_kind.]) ], [], @@ -1987,8 +2167,14 @@ AC_MSG_RESULT([no]) # clang 3.3 cannot process from e.g. # gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 +#---------------------------------------------------------------------------- +# C++ checks +#---------------------------------------------------------------------------- + + +AC_LANG_PUSH(C++) + AC_MSG_CHECKING([that C++ compiler can compile C++17 code]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS=-std=c++17 @@ -2003,14 +2189,12 @@ ac_have_cxx_17=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(HAVE_CXX17, test x$ac_have_cxx_17 = xyes) # Compiler may announce C++17 support as above but may lack # some features AC_MSG_CHECKING([that C++ compiler supports constexpr if]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS=-std=c++17 @@ -2029,12 +2213,10 @@ ac_have_constexpr_if=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(HAVE_CONSTEXPR_IF, test x$ac_have_constexpr_if = xyes) AC_MSG_CHECKING([that C++ compiler supports std::align_val_t]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS=-std=c++17 @@ -2050,18 +2232,16 @@ ac_have_align_val_t=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(HAVE_ALIGN_VAL_T, test x$ac_have_align_val_t = xyes) AC_MSG_CHECKING([that C++ compiler can include header file]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS=-std=c++0x AC_COMPILE_IFELSE([AC_LANG_SOURCE([ -#include +#include ])], [ ac_cxx_can_include_thread_header=yes @@ -2071,19 +2251,17 @@ ac_cxx_can_include_thread_header=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(CXX_CAN_INCLUDE_THREAD_HEADER, test x$ac_cxx_can_include_thread_header = xyes) # Check whether compiler can process #include without errors AC_MSG_CHECKING([that C++ compiler can include header file]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS=-std=c++0x AC_COMPILE_IFELSE([AC_LANG_SOURCE([ -#include +#include ])], [ ac_cxx_can_include_condition_variable_header=yes @@ -2093,14 +2271,12 @@ ac_cxx_can_include_condition_variable_header=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(CXX_CAN_INCLUDE_CONDITION_VARIABLE_HEADER, test x$ac_cxx_can_include_condition_variable_header = xyes) # check for std::shared_timed_mutex, this is a C++ 14 feature AC_MSG_CHECKING([that C++ compiler can use std::shared_timed_mutex]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS="-std=c++1y -pthread" @@ -2116,14 +2292,12 @@ ac_cxx_can_use_shared_timed_mutex=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(CXX_CAN_USE_SHARED_TIMED_MUTEX, test x$ac_cxx_can_use_shared_timed_mutex = xyes) # check for std::shared_mutex, this is a C++ 11 feature AC_MSG_CHECKING([that C++ compiler can use std::timed_mutex]) -AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS="-std=c++0x -pthread" @@ -2139,10 +2313,146 @@ ac_cxx_can_use_timed_mutex=no AC_MSG_RESULT([no]) ]) CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) AM_CONDITIONAL(CXX_CAN_USE_TIMED_MUTEX, test x$ac_cxx_can_use_timed_mutex = xyes) +# does this compiler support -faligned-new ? +AC_MSG_CHECKING([if g++ accepts -faligned-new]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-faligned-new -Werror" + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + return 0; +]])], [ +FLAG_FALIGNED_NEW="-faligned-new" +AC_MSG_RESULT([yes]) +], [ +FLAG_FALIGNED_NEW="" +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS + +AC_SUBST(FLAG_FALIGNED_NEW) + +# does this compiler support -fsized-deallocation ? +AC_MSG_CHECKING([if g++ accepts -fsized-deallocation]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-fsized-deallocation -Werror" + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + return 0; +]])], [ +FLAG_FSIZED_DEALLOCATION="-fsized-deallocation" +ac_have_sized_deallocation=yes +AC_MSG_RESULT([yes]) +], [ +FLAG_FSIZED_DEALLOCATION="" +ac_have_sized_deallocation=no +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS + +AC_SUBST(FLAG_FSIZED_DEALLOCATION) +AM_CONDITIONAL([HAVE_FSIZED_DEALLOCATION], [test x$ac_have_sized_deallocation = xyes]) + +# does this compiler support C++17 aligned new/delete? +AC_MSG_CHECKING([if g++ supports aligned new and delete]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-std=c++17" + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +]], [[ + operator delete(nullptr, std::align_val_t(64U)); +]])], [ +ac_have_aligned_cxx_alloc=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_aligned_cxx_alloc=no +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS + +AM_CONDITIONAL([HAVE_ALIGNED_CXX_ALLOC], [test x$ac_have_aligned_cxx_alloc = xyes]) + +# does g++ have built-in functions for atomic memory access ? +AC_MSG_CHECKING([if g++ supports __sync_add_and_fetch]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$mflag_primary" + +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int variable = 1; + return (__sync_bool_compare_and_swap(&variable, 1, 2) + && __sync_add_and_fetch(&variable, 1) ? 1 : 0) +]])], [ + ac_have_builtin_atomic_cxx=yes + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_BUILTIN_ATOMIC_CXX, 1, [Define to 1 if g++ supports __sync_bool_compare_and_swap() and __sync_add_and_fetch()]) +], [ + ac_have_builtin_atomic_cxx=no + AC_MSG_RESULT([no]) +]) + +CXXFLAGS=$safe_CXXFLAGS + +AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC_CXX], [test x$ac_have_builtin_atomic_cxx = xyes]) + + +# does libstdc++ support annotating shared pointers ? +AC_MSG_CHECKING([if libstdc++ supports annotating shared pointers]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-std=c++0x" + +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include +]], [[ + std::shared_ptr p +]])], [ + ac_have_shared_ptr=yes +], [ + ac_have_shared_ptr=no +]) +if test x$ac_have_shared_ptr = xyes; then + # If compilation of the program below fails because of a syntax error + # triggered by substituting one of the annotation macros then that + # means that libstdc++ supports these macros. + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(a) (a)---- + #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(a) (a)---- + #include + ]], [[ + std::shared_ptr p + ]])], [ + ac_have_shared_pointer_annotation=no + AC_MSG_RESULT([no]) + ], [ + ac_have_shared_pointer_annotation=yes + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_SHARED_POINTER_ANNOTATION, 1, + [Define to 1 if libstd++ supports annotating shared pointers]) + ]) +else + ac_have_shared_pointer_annotation=no + AC_MSG_RESULT([no]) +fi + +CXXFLAGS=$safe_CXXFLAGS + +AM_CONDITIONAL([HAVE_SHARED_POINTER_ANNOTATION], + [test x$ac_have_shared_pointer_annotation = xyes]) + +AC_LANG_POP() + +#---------------------------------------------------------------------------- +# End of C++ checks +#---------------------------------------------------------------------------- + # On aarch64 before glibc 2.20 we would get the kernel user_pt_regs instead # of the user_regs_struct from sys/user.h. They are structurally the same # but we get either one or the other. @@ -2187,6 +2497,21 @@ AC_MSG_RESULT([no]) AM_CONDITIONAL(HAVE_NR_IO_PGETEVENTS, [test x$ac_have_nr_io_pgetevents = xyes]) +AC_MSG_CHECKING([for PROCMAP_QUERY]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +]], [[ +return PROCMAP_QUERY +]])], [ +ac_have_procmap_query=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_procmap_query=no +AC_MSG_RESULT([no]) +]) + +AM_CONDITIONAL(HAVE_PROCMAP_QUERY, [test x$ac_have_procmap_query = xyes]) + #---------------------------------------------------------------------------- # Checking for supported compiler flags. #---------------------------------------------------------------------------- @@ -2485,13 +2810,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ ]])], [ ac_compiler_supports_mlong_double_128=yes AC_MSG_RESULT([yes]) +FLAG_MLONG_DOUBLE_128="-mlong-double-128" ], [ ac_compiler_supports_mlong_double_128=no AC_MSG_RESULT([no]) +FLAG_MLONG_DOUBLE_128="" ]) CFLAGS=$safe_CFLAGS AM_CONDITIONAL(HAS_MLONG_DOUBLE_128, test x$ac_compiler_supports_mlong_double_128 = xyes) -FLAG_MLONG_DOUBLE_128="-mlong-double-128" AC_SUBST(FLAG_MLONG_DOUBLE_128) # does this toolchain support lto ? @@ -2552,7 +2878,7 @@ fi AC_DEFUN([AC_GCC_WARNING_SUBST_NO],[ AC_MSG_CHECKING([if gcc accepts -W$1]) safe_CFLAGS=$CFLAGS - CFLAGS="-W$1 -Werror" + CFLAGS="-W$1 -Wno-$1 -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[;]])], [ AC_SUBST([$2], [-Wno-$1]) AC_MSG_RESULT([yes])], [ @@ -2605,8 +2931,9 @@ AC_GCC_WARNING_SUBST_NO([unused-result], [FLAG_W_NO_UNUSED_RESULT]) AC_GCC_WARNING_SUBST_NO([infinite-recursion], [FLAG_W_NO_INFINITE_RECURSION]) AC_GCC_WARNING_SUBST_NO([deprecated], [FLAG_W_NO_DEPRECATED]) # OK for 32 and 64 bit -AC_GCC_WARNING_SUBST_NO([alloc-size-larger-than=18446744073709551615], [FLAG_W_NO_ALLOC_SIZE_LARGER_THAN]) AC_GCC_WARNING_SUBST_NO([alloc-size], [FLAG_W_NO_ALLOC_SIZE]) +AC_GCC_WARNING_SUBST_NO([deprecated-declarations], [FLAG_W_NO_DEPRECATED_DECLARATIONS]) +AC_GCC_WARNING_SUBST_NO([nullability-completeness], [FLAG_W_NO_NULLABILITY_COMPLETENESS]) AC_GCC_WARNING_SUBST([write-strings], [FLAG_W_WRITE_STRINGS]) AC_GCC_WARNING_SUBST([empty-body], [FLAG_W_EMPTY_BODY]) @@ -2619,24 +2946,25 @@ AC_GCC_WARNING_SUBST([missing-parameter-type], [FLAG_W_MISSING_PARAMETER_TYPE]) AC_GCC_WARNING_SUBST([logical-op], [FLAG_W_LOGICAL_OP]) AC_GCC_WARNING_SUBST([enum-conversion], [FLAG_W_ENUM_CONVERSION]) AC_GCC_WARNING_SUBST([implicit-fallthrough=2], [FLAG_W_IMPLICIT_FALLTHROUGH]) +AC_GCC_WARNING_SUBST([alloc-size-larger-than=18446744073709551616], [FLAG_W_ALLOC_SIZE_LARGER_THAN]) # as above, C++ flags AC_DEFUN([AC_GXX_WARNING_SUBST_NO],[ AC_MSG_CHECKING([if g++ accepts -W$1]) safe_CXXFLAGS=$CXXFLAGS CXXFLAGS="-W$1 -Werror" - AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[;]])], [ AC_SUBST([$2], [-Wno-$1]) - AC_LANG_POP() AC_MSG_RESULT([yes])], [ AC_SUBST([$2], []) AC_MSG_RESULT([no])]) CXXFLAGS=$safe_CXXFLAGS ]) +AC_LANG_PUSH(C++) AC_GXX_WARNING_SUBST_NO([missing-exception-spec], [FLAG_W_NO_MISSING_EXCEPTION_SPEC]) AC_GXX_WARNING_SUBST_NO([implicit-exception-spec-mismatch], [FLAG_W_NO_IMPLICIT_EXCEPTION_SPEC_MISMATCH]) +AC_LANG_POP() # Does this compiler support -Wformat-security ? # Special handling is needed, because certain GCC versions require -Wformat @@ -2689,116 +3017,89 @@ else AC_SUBST([FLAG_W_CAST_ALIGN], [-Wcast-align]) fi -# does this compiler support -faligned-new ? -AC_MSG_CHECKING([if g++ accepts -faligned-new]) +# does this compiler support -fno-stack-protector ? +AC_MSG_CHECKING([if gcc accepts -fno-stack-protector]) -safe_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-faligned-new -Werror" +safe_CFLAGS=$CFLAGS +CFLAGS="-fno-stack-protector -Werror" -AC_LANG(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ return 0; ]])], [ -FLAG_FALIGNED_NEW="-faligned-new" +no_stack_protector=yes +FLAG_FNO_STACK_PROTECTOR="-fno-stack-protector" AC_MSG_RESULT([yes]) ], [ -FLAG_FALIGNED_NEW="" +no_stack_protector=no +FLAG_FNO_STACK_PROTECTOR="" AC_MSG_RESULT([no]) ]) -CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) +CFLAGS=$safe_CFLAGS -AC_SUBST(FLAG_FALIGNED_NEW) +AC_SUBST(FLAG_FNO_STACK_PROTECTOR) -# does this compiler support -fsized-deallocation ? -AC_MSG_CHECKING([if g++ accepts -fsized-deallocation]) +# does this compiler support -finline-functions ? +AC_MSG_CHECKING([if gcc accepts -finline-functions]) -safe_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-fsized-deallocation -Werror" +safe_CFLAGS=$CFLAGS +CFLAGS="-finline-functions -Werror" -AC_LANG(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ return 0; ]])], [ -FLAG_FSIZED_DEALLOCATION="-fsized-deallocation" -ac_have_sized_deallocation=yes -AC_MSG_RESULT([yes]) -], [ -FLAG_FSIZED_DEALLOCATION="" -ac_have_sized_deallocation=no -AC_MSG_RESULT([no]) -]) -CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) - -AC_SUBST(FLAG_FSIZED_DEALLOCATION) -AM_CONDITIONAL([HAVE_FSIZED_DEALLOCATION], [test x$ac_have_sized_deallocation = xyes]) - -# does this compiler support C++17 aligned new/delete? -AC_MSG_CHECKING([if g++ supports aligned new and delete]) - -safe_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-std=c++17" - -AC_LANG(C++) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -]], [[ - operator delete(nullptr, std::align_val_t(64U)); -]])], [ -ac_have_aligned_cxx_alloc=yes +inline_functions=yes +FLAG_FINLINE_FUNCTIONS="-finline-functions" AC_MSG_RESULT([yes]) ], [ -ac_have_aligned_cxx_alloc=no +inline_functions=no +FLAG_FINLINE_FUNCTIONS="" AC_MSG_RESULT([no]) ]) -CXXFLAGS=$safe_CXXFLAGS -AC_LANG(C) +CFLAGS=$safe_CFLAGS -AM_CONDITIONAL([HAVE_ALIGNED_CXX_ALLOC], [test x$ac_have_aligned_cxx_alloc = xyes]) +AC_SUBST(FLAG_FINLINE_FUNCTIONS) -# does this compiler support -fno-stack-protector ? -AC_MSG_CHECKING([if gcc accepts -fno-stack-protector]) +# does this compiler support -fno-diagnostics-show-caret ? +AC_MSG_CHECKING([if gcc accepts -fno-diagnostics-show-caret]) safe_CFLAGS=$CFLAGS -CFLAGS="-fno-stack-protector -Werror" +CFLAGS="-fno-diagnostics-show-caret -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ return 0; ]])], [ -no_stack_protector=yes -FLAG_FNO_STACK_PROTECTOR="-fno-stack-protector" +no_diagnostics_show_caret=yes +FLAG_FNO_DIAGNOSTICS_SHOW_CARET="-fno-diagnostics-show-caret" AC_MSG_RESULT([yes]) ], [ -no_stack_protector=no -FLAG_FNO_STACK_PROTECTOR="" +no_diagnostics_show_caret=no +FLAG_FNO_DIAGNOSTICS_SHOW_CARET="" AC_MSG_RESULT([no]) ]) CFLAGS=$safe_CFLAGS -AC_SUBST(FLAG_FNO_STACK_PROTECTOR) +AC_SUBST(FLAG_FNO_DIAGNOSTICS_SHOW_CARET) -# does this compiler support -finline-functions ? -AC_MSG_CHECKING([if gcc accepts -finline-functions]) +# does this compiler support -ftrack-macro-expansion=0 ? +AC_MSG_CHECKING([if gcc accepts -ftrack-macro-expansion=0]) safe_CFLAGS=$CFLAGS -CFLAGS="-finline-functions -Werror" +CFLAGS="-ftrack-macro-expansion=0 -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ return 0; ]])], [ -inline_functions=yes -FLAG_FINLINE_FUNCTIONS="-finline-functions" +track_macro_expansion=yes +FLAG_FTRACK_MACRO_EXPANSION="-ftrack-macro-expansion=0" AC_MSG_RESULT([yes]) ], [ -inline_functions=no -FLAG_FINLINE_FUNCTIONS="" +track_macro_expansion=no +FLAG_FTRACK_MACRO_EXPANSION="" AC_MSG_RESULT([no]) ]) CFLAGS=$safe_CFLAGS -AC_SUBST(FLAG_FINLINE_FUNCTIONS) +AC_SUBST(FLAG_FTRACK_MACRO_EXPANSION) # Does GCC support disabling Identical Code Folding? # We want to disabled Identical Code Folding for the @@ -3038,26 +3339,25 @@ AM_CONDITIONAL([HAVE_ANSI], [test x$ac_have_ansi = xyes]) CFLAGS=$safe_CFLAGS -# Does this compiler support -no-pie? +# Does this linker support -no-pie? # On Ubuntu 16.10+, gcc produces position independent executables (PIE) by # default. However this gets in the way with some tests, we use -no-pie # for these. - AC_MSG_CHECKING([if gcc accepts -no-pie]) -safe_CFLAGS=$CFLAGS -CFLAGS="-no-pie -Werror" +safe_LDFLAGS=$LDFLAGS +LDFLAGS="-Wl,-no-pie" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[ return 0; ]])], [ -AC_SUBST([FLAG_NO_PIE], ["-no-pie"]) +AC_SUBST([LDFLAG_NO_PIE], ["-Wl,-no-pie"]) AC_MSG_RESULT([yes]) ], [ -AC_SUBST([FLAG_NO_PIE], [""]) +AC_SUBST([LDFLAG_NO_PIE], [""]) AC_MSG_RESULT([no]) ]) -CFLAGS=$safe_CFLAGS +LDFLAGS=$safe_LDFLAGS # We want to use use the -Ttext-segment option to the linker. @@ -3246,8 +3546,8 @@ fi AC_MSG_CHECKING([if x86/amd64 assembler speaks SSE3]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; - __asm__ __volatile__("fisttpq (%0)" : :"r"(&x) ); } + do { long long int x; + __asm__ __volatile__("fisttpq (%0)" : :"r"(&x) ); } while (0) ]])], [ ac_have_as_sse3=yes @@ -3268,7 +3568,7 @@ AC_MSG_CHECKING([if x86/amd64 assembler speaks SSSE3]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -msse -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; + do { long long int x; __asm__ __volatile__( "pabsb (%0),%%xmm7" : : "r"(&x) : "xmm7" ); } while (0) @@ -3355,8 +3655,8 @@ AM_CONDITIONAL(BUILD_FMA4_TESTS, test x$ac_have_as_vfmaddpd = xyes) AC_MSG_CHECKING([if x86/amd64 assembler supports 'lzcnt']) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { - __asm__ __volatile__("lzcnt %%rax,%%rax" : : : "rax"); + do { + __asm__ __volatile__("lzcnt %%eax,%%eax" : : : "eax"); } while (0) ]])], [ ac_have_as_lzcnt=yes @@ -3375,7 +3675,7 @@ AM_CONDITIONAL([BUILD_LZCNT_TESTS], [test x$ac_have_as_lzcnt = xyes]) AC_MSG_CHECKING([if x86/amd64 assembler supports 'loopnel']) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { + do { __asm__ __volatile__("1: loopnel 1b\n"); } while (0) ]])], [ @@ -3395,7 +3695,7 @@ AM_CONDITIONAL([BUILD_LOOPNEL_TESTS], [test x$ac_have_as_loopnel = xyes]) AC_MSG_CHECKING([if x86/amd64 assembler supports 'addr32']) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { + do { asm volatile ("addr32 rep movsb"); } while (0) ]])], [ @@ -3415,11 +3715,11 @@ AM_CONDITIONAL([BUILD_ADDR32_TESTS], [test x$ac_have_as_addr32 = xyes]) AC_MSG_CHECKING([if x86/amd64 assembler speaks SSE4.2]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; + do { long long int x; __asm__ __volatile__( "crc32q %%r15,%%r15" : : : "r15" ); __asm__ __volatile__( - "pblendvb (%%rcx), %%xmm11" : : : "memory", "xmm11"); + "pblendvb (%%rcx), %%xmm11" : : : "memory", "xmm11"); __asm__ __volatile__( "aesdec %%xmm2, %%xmm1" : : : "xmm2", "xmm1"); } while (0) @@ -3440,7 +3740,7 @@ AM_CONDITIONAL(BUILD_SSE42_TESTS, test x$ac_have_as_sse42 = xyes) AC_MSG_CHECKING([if x86/amd64 assembler speaks AVX]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; + do { long long int x; __asm__ __volatile__( "vmovupd (%%rsp), %%ymm7" : : : "xmm7" ); __asm__ __volatile__( @@ -3463,7 +3763,7 @@ AM_CONDITIONAL(BUILD_AVX_TESTS, test x$ac_have_as_avx = xyes) AC_MSG_CHECKING([if x86/amd64 assembler speaks AVX2]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; + do { long long int x; __asm__ __volatile__( "vpsravd (%%rsp), %%ymm8, %%ymm7" : : : "xmm7", "xmm8" ); __asm__ __volatile__( @@ -3672,7 +3972,7 @@ AM_CONDITIONAL(BUILD_F16C_TESTS, test x$ac_have_as_f16c = xyes) AC_MSG_CHECKING([if x86/amd64 assembler knows the MOVBE insn]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - do { long long int x; + do { long long int x; __asm__ __volatile__( "movbe (%%rsp), %%r15" : : : "memory", "r15" ); } while (0) @@ -3849,6 +4149,14 @@ fi if test "$VGCONF_OS" = "solaris" ; then AC_CHECK_HEADERS([sys/lgrp_user_impl.h]) +AC_CHECK_HEADER([sys/crypto/ioctl.h], [ + AC_DEFINE([HAVE_SYS_CRYPTO_IOCTL_H], [1], [Define to 1 if sys/crypto/ioctl.h is available.]) + ac_have_sys_crypto_ioctl_h=yes +], [ + ac_have_sys_crypto_ioctl_h=no +]) +AM_CONDITIONAL(SOLARIS_HAVE_SYS_CRYPTO_IOCTL_H, test x$ac_have_sys_crypto_ioctl_h = xyes ) + # Solaris-specific check determining if the Sun Studio Assembler is used to # build Valgrind. The test checks if the x86/amd64 assembler understands the # cmovl.l instruction, if yes then it's Sun Assembler. @@ -4071,7 +4379,7 @@ AC_MSG_RESULT([no]) # AC_MSG_CHECKING([for the new `lwp_sigqueue' syscall (Solaris-specific)]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include +#include ]], [[ return !SYS_lwp_sigqueue; ]])], [ @@ -4815,6 +5123,7 @@ AC_MSG_RESULT([no]) ]) else +AM_CONDITIONAL(SOLARIS_HAVE_SYS_CRYPTO_IOCTL_H, false) AM_CONDITIONAL(SOLARIS_SUN_STUDIO_AS, false) AM_CONDITIONAL(SOLARIS_XPG_SYMBOLS_PRESENT, false) AM_CONDITIONAL(SOLARIS_PROC_CMDLINE, false) @@ -4859,7 +5168,7 @@ if test "$VGCONF_OS" = "freebsd" ; then AC_CHECK_FUNCS([ \ eventfd ]) - + AM_CONDITIONAL([FREEBSD_EVENTFD], [test x$ac_cv_func_eventfd = xyes]) @@ -5145,7 +5454,7 @@ fi #---------------------------------------------------------------------------- # Do we have a useable MPI setup on the primary and/or secondary targets? # On Linux, by default, assumes mpicc and -m32/-m64 -# Note: this is a kludge in that it assumes the specified mpicc +# Note: this is a kludge in that it assumes the specified mpicc # understands -m32/-m64 regardless of what is specified using # --with-mpicc=. AC_PATH_PROG([MPI_CC], [mpicc], [mpicc], @@ -5232,7 +5541,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ int r = MPI_Init(NULL,NULL); r |= MPI_Type_get_envelope( MPI_INT, &ni, &na, &nd, &comb ); r |= MPI_Finalize(); - return r; + return r; ]])], [ ac_have_mpi2_pri=yes AC_MSG_RESULT([yes, $MPI_CC]) @@ -5269,7 +5578,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ int r = MPI_Init(NULL,NULL); r |= MPI_Type_get_envelope( MPI_INT, &ni, &na, &nd, &comb ); r |= MPI_Finalize(); - return r; + return r; ]])], [ ac_have_mpi2_sec=yes AC_MSG_RESULT([yes, $MPI_CC]) @@ -5316,7 +5625,7 @@ AM_CONDITIONAL(HAVE_STATIC_LIBC, test x$ac_have_static_libc = xyes) # in a situation (eg) where, on amd64-linux, the test for Boost checks # for usable 64-bit Boost facilities, but because we are doing a 32-bit # only build (meaning, the primary target is x86-linux), the build -# of the regtest programs that use Boost fails, because they are +# of the regtest programs that use Boost fails, because they are # build as 32-bit (IN THIS EXAMPLE). # # Hence: ALWAYS USE $mflag_primary FOR CONFIGURE TESTS FOR FACILITIES @@ -5370,7 +5679,7 @@ safe_CFLAGS=$CFLAGS CFLAGS="-fopenmp $mflag_primary -Werror" AC_LINK_IFELSE([AC_LANG_SOURCE([ -#include +#include int main(int argc, char** argv) { omp_set_dynamic(0); @@ -5556,6 +5865,20 @@ fi AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC64], [test x$ac_have_builtin_atomic64 = xyes]) +if test x$ac_have_usable_linux_futex_h = xyes \ + -a x$ac_have_builtin_atomic_primary = xyes; then + ac_enable_linux_ticket_lock_primary=yes +fi +AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_PRIMARY], + [test x$ac_enable_linux_ticket_lock_primary = xyes]) + +if test x$VGCONF_PLATFORM_SEC_CAPS != x \ + -a x$ac_have_usable_linux_futex_h = xyes \ + -a x$ac_have_builtin_atomic_secondary = xyes; then + ac_enable_linux_ticket_lock_secondary=yes +fi +AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_SECONDARY], + [test x$ac_enable_linux_ticket_lock_secondary = xyes]) AC_MSG_CHECKING([if platform has openat2 syscall]) @@ -5618,94 +5941,6 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ AM_CONDITIONAL([HAVE_AIO_READV], [test x$ac_have_aio_readv = xyes]) -# does g++ have built-in functions for atomic memory access ? -AC_MSG_CHECKING([if g++ supports __sync_add_and_fetch]) - -safe_CXXFLAGS=$CXXFLAGS -CXXFLAGS="$mflag_primary" - -AC_LANG_PUSH(C++) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ - int variable = 1; - return (__sync_bool_compare_and_swap(&variable, 1, 2) - && __sync_add_and_fetch(&variable, 1) ? 1 : 0) -]])], [ - ac_have_builtin_atomic_cxx=yes - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_BUILTIN_ATOMIC_CXX, 1, [Define to 1 if g++ supports __sync_bool_compare_and_swap() and __sync_add_and_fetch()]) -], [ - ac_have_builtin_atomic_cxx=no - AC_MSG_RESULT([no]) -]) -AC_LANG_POP(C++) - -CXXFLAGS=$safe_CXXFLAGS - -AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC_CXX], [test x$ac_have_builtin_atomic_cxx = xyes]) - - -if test x$ac_have_usable_linux_futex_h = xyes \ - -a x$ac_have_builtin_atomic_primary = xyes; then - ac_enable_linux_ticket_lock_primary=yes -fi -AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_PRIMARY], - [test x$ac_enable_linux_ticket_lock_primary = xyes]) - -if test x$VGCONF_PLATFORM_SEC_CAPS != x \ - -a x$ac_have_usable_linux_futex_h = xyes \ - -a x$ac_have_builtin_atomic_secondary = xyes; then - ac_enable_linux_ticket_lock_secondary=yes -fi -AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_SECONDARY], - [test x$ac_enable_linux_ticket_lock_secondary = xyes]) - - -# does libstdc++ support annotating shared pointers ? -AC_MSG_CHECKING([if libstdc++ supports annotating shared pointers]) - -safe_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-std=c++0x" - -AC_LANG_PUSH(C++) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include -]], [[ - std::shared_ptr p -]])], [ - ac_have_shared_ptr=yes -], [ - ac_have_shared_ptr=no -]) -if test x$ac_have_shared_ptr = xyes; then - # If compilation of the program below fails because of a syntax error - # triggered by substituting one of the annotation macros then that - # means that libstdc++ supports these macros. - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(a) (a)---- - #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(a) (a)---- - #include - ]], [[ - std::shared_ptr p - ]])], [ - ac_have_shared_pointer_annotation=no - AC_MSG_RESULT([no]) - ], [ - ac_have_shared_pointer_annotation=yes - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_SHARED_POINTER_ANNOTATION, 1, - [Define to 1 if libstd++ supports annotating shared pointers]) - ]) -else - ac_have_shared_pointer_annotation=no - AC_MSG_RESULT([no]) -fi -AC_LANG_POP(C++) - -CXXFLAGS=$safe_CXXFLAGS - -AM_CONDITIONAL([HAVE_SHARED_POINTER_ANNOTATION], - [test x$ac_have_shared_pointer_annotation = xyes]) - # checking for GNU libc C17 aligned_alloc # just check glibc version rather than trying to muck around # checking the runtime behaviour or seeing if it is a weak alias @@ -5732,14 +5967,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ int thrd_entry(void *arg) { return 0; } ], [[thrd_t thr; return thrd_create(&thr, thrd_entry, NULL);]])], [ -ac_cxx_have_thrd_create=yes +ac_have_thrd_create=yes AC_MSG_RESULT([yes]) ], [ -ac_cxx_have_thrd_create=no +ac_have_thrd_create=no AC_MSG_RESULT([no]) ]) -AM_CONDITIONAL(HAVE_THRD_CREATE, test x$ac_cxx_have_thrd_create = xyes) +AM_CONDITIONAL(HAVE_THRD_CREATE, test x$ac_have_thrd_create = xyes) # Check arm64 sha3 @@ -5766,7 +6001,7 @@ CFLAGS=$safe_CFLAGS # Nb: VEX/Makefile is generated from Makefile.vex.in. AC_CONFIG_FILES([ - Makefile + Makefile VEX/Makefile:Makefile.vex.in third_party/Makefile valgrind.spec @@ -5775,13 +6010,13 @@ AC_CONFIG_FILES([ glibc-2.X-helgrind.supp glibc-2.X-drd.supp include/valgrind.h - docs/Makefile + docs/Makefile docs/xml/vg-entities.xml - tests/Makefile - perf/Makefile + tests/Makefile + perf/Makefile gdbserver_tests/Makefile gdbserver_tests/solaris/Makefile - include/Makefile + include/Makefile auxprogs/Makefile mpi/Makefile coregrind/Makefile diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index e7921ffaad..8741e2eed6 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -167,10 +167,10 @@ mach_hdrs += \ m_mach/thread_act.h \ m_mach/vm_map.h mach_defs += \ - @XCODE_DIR@/mach/mach_vm.defs \ - @XCODE_DIR@/mach/task.defs \ - @XCODE_DIR@/mach/thread_act.defs \ - @XCODE_DIR@/mach/vm_map.defs + @SDK_INC_DIR@/mach/mach_vm.defs \ + @SDK_INC_DIR@/mach/task.defs \ + @SDK_INC_DIR@/mach/thread_act.defs \ + @SDK_INC_DIR@/mach/vm_map.defs endif # Be careful w.r.t. parallel builds. See section 27.9 of the automake info @@ -178,9 +178,9 @@ endif $(abs_builddir)/m_mach: mkdir -p $@ $(mach_user_srcs): $(mach_defs) $(abs_builddir)/m_mach - (cd m_mach && mig $(mach_defs)) + (cd m_mach && mig -I@SDK_INC_DIR@ $(mach_defs)) $(mach_hdrs): $(mach_defs) $(mach_user_srcs) $(abs_builddir)/m_mach - (cd m_mach && mig $(mach_defs)) + (cd m_mach && mig -I@SDK_INC_DIR@ $(mach_defs)) #---------------------------------------------------------------------------- # Headers @@ -283,6 +283,7 @@ noinst_HEADERS = \ m_gdbserver/target.h \ m_gdbserver/valgrind_low.h \ m_gdbserver/gdb/signals.h \ + m_mach/priv_dyld_internals.h \ m_scheduler/priv_sema.h \ m_scheduler/priv_sched-lock.h \ m_scheduler/priv_sched-lock-impl.h \ @@ -433,6 +434,8 @@ COREGRIND_SOURCES_COMMON = \ m_mach/mach_msg.c \ m_mach/mach_traps-x86-darwin.S \ m_mach/mach_traps-amd64-darwin.S \ + m_mach/mig_strncpy.c \ + m_mach/dyld_cache.c \ m_replacemalloc/replacemalloc_core.c \ m_scheduler/sched-lock.c \ m_scheduler/sched-lock-generic.c \ diff --git a/coregrind/fixup_macho_loadcmds.c b/coregrind/fixup_macho_loadcmds.c index 1a5cdf62ad..a6699baed4 100644 --- a/coregrind/fixup_macho_loadcmds.c +++ b/coregrind/fixup_macho_loadcmds.c @@ -117,14 +117,10 @@ #include #include -/* Get hold of DARWIN_VERS, and check it has a sane value. */ +/* Check that DARWIN_VERS is defined */ #include "config.h" -#if DARWIN_VERS != DARWIN_10_5 && DARWIN_VERS != DARWIN_10_6 \ - && DARWIN_VERS != DARWIN_10_7 && DARWIN_VERS != DARWIN_10_8 \ - && DARWIN_VERS != DARWIN_10_9 && DARWIN_VERS != DARWIN_10_10 \ - && DARWIN_VERS != DARWIN_10_11 && DARWIN_VERS != DARWIN_10_12 \ - && DARWIN_VERS != DARWIN_10_13 -# error "Unknown DARWIN_VERS value. This file only compiles on Darwin." +#if !defined(DARWIN_VERS) +# error "DARWIN_VERS not defind. This file only compiles on Darwin." #endif @@ -271,7 +267,7 @@ static Int map_image_aboard ( /*OUT*/ImageInfo* ii, HChar* filename ) { struct fat_header* fh_be; struct fat_header fh; struct mach_header_64* mh; - + // Assume initially that we have a thin image, and update // these if it turns out to be fat. ii->macho_img = ii->img; @@ -294,7 +290,7 @@ static Int map_image_aboard ( /*OUT*/ImageInfo* ii, HChar* filename ) + fh.nfat_arch * sizeof(struct fat_arch)) fail("Invalid Mach-O file (1 too small)."); - for (f = 0, arch_be = (struct fat_arch *)(fh_be+1); + for (f = 0, arch_be = (struct fat_arch *)(fh_be+1); f < fh.nfat_arch; f++, arch_be++) { Int cputype; @@ -519,8 +515,13 @@ void modify_macho_loadcmds ( HChar* filename, fail("has __UNIXSTACK, but wrong ::vmaddr"); if (seg->vmsize != expected_stack_size) fail("has __UNIXSTACK, but wrong ::vmsize"); +#if SDK_VERS >= SDK_10_14_6 + if (seg->maxprot != 3) + fail("has __UNIXSTACK, but wrong ::maxprot (should be 3)"); +#else if (seg->maxprot != 7) fail("has __UNIXSTACK, but wrong ::maxprot (should be 7)"); +#endif if (seg->initprot != 3) fail("has __UNIXSTACK, but wrong ::initprot (should be 3)"); if (seg->nsects != 0) @@ -605,7 +606,7 @@ int main ( int argc, char** argv ) if (argc != 4) fail("args: -stack_addr-arg -stack_size-arg " - "name-of-tool-executable-to-modify"); + "name-of-tool-executable-to-modify"); r= sscanf(argv[1], "0x%llx", &req_stack_addr); if (r != 1) fail("invalid stack_addr arg"); @@ -620,7 +621,7 @@ int main ( int argc, char** argv ) if (!is_plausible_tool_exe_name(argv[3])) fail("implausible tool exe name -- not of the form *-{x86,amd64}-darwin"); - fprintf(stderr, "fixup_macho_loadcmds: examining tool exe: %s\n", + fprintf(stderr, "fixup_macho_loadcmds: examining tool exe: %s\n", argv[3] ); modify_macho_loadcmds( argv[3], req_stack_addr - req_stack_size, req_stack_size ); diff --git a/coregrind/launcher-darwin.c b/coregrind/launcher-darwin.c index 933050617b..743f7c943b 100644 --- a/coregrind/launcher-darwin.c +++ b/coregrind/launcher-darwin.c @@ -64,7 +64,7 @@ static struct { MacOS X, but .. the Apple PPC descriptors refer to the BE variant, since the LE variant is something that appeared long after Apple dropped PPC. */ - { CPU_TYPE_POWERPC, "ppc", "ppc32" }, + { CPU_TYPE_POWERPC, "ppc", "ppc32" }, { CPU_TYPE_POWERPC64, "ppc64", "ppc64be" } }; static int valid_archs_count = sizeof(valid_archs)/sizeof(valid_archs[0]); @@ -156,7 +156,7 @@ static const char *select_arch( if (bytes != sizeof(buf)) { return NULL; } - + // If it's thin, return that arch. { struct mach_header *mh = (struct mach_header *)buf; @@ -182,7 +182,7 @@ static const char *select_arch( if (fat_has_cputype(fh, default_cputype)) { return default_arch; } - + // Scan fat headers for any supported arch. for (i = 0; i < valid_archs_count; i++) { if (fat_has_cputype(fh, valid_archs[i].cputype)) { @@ -191,7 +191,7 @@ static const char *select_arch( } } } - + return NULL; } @@ -210,6 +210,7 @@ int main(int argc, char** argv, char** envp) const char *default_arch; cpu_type_t default_cputype; char *toolfile; + char* executable_path; char launcher_name[PATH_MAX+1]; char* new_line; char* set_cwd; @@ -218,7 +219,7 @@ int main(int argc, char** argv, char** envp) char **new_argv; int new_argc; - /* Start the debugging-log system ASAP. First find out how many + /* Start the debugging-log system ASAP. First find out how many "-d"s were specified. This is a pre-scan of the command line. At the same time, look for the tool name. */ loglevel = 0; @@ -235,9 +236,9 @@ int main(int argc, char** argv, char** envp) } break; } - if (0 == strcmp(argv[i], "-d")) + if (0 == strcmp(argv[i], "-d")) loglevel++; - if (0 == strncmp(argv[i], "--tool=", 7)) + if (0 == strncmp(argv[i], "--tool=", 7)) toolname = argv[i] + 7; if (0 == strncmp(argv[i], "--arch=", 7)) archname = argv[i] + 7; @@ -251,7 +252,7 @@ int main(int argc, char** argv, char** envp) if (toolname) { VG_(debugLog)(1, "launcher", "tool '%s' requested\n", toolname); } else { - VG_(debugLog)(1, "launcher", + VG_(debugLog)(1, "launcher", "no tool requested, defaulting to 'memcheck'\n"); toolname = "memcheck"; } @@ -296,14 +297,14 @@ int main(int argc, char** argv, char** envp) free(vgpreload_core); } - /* Find the "default" arch (VGCONF_ARCH_PRI from configure). + /* Find the "default" arch (VGCONF_ARCH_PRI from configure). This is the preferred arch from fat files and the fallback. */ default_arch = NULL; default_cputype = 0; for (i = 0; i < valid_archs_count; i++) { if (!valid_archs[i].cputype) continue; - if (0 == strncmp(VG_PLATFORM, valid_archs[i].valgrind_name, - strlen(valid_archs[i].valgrind_name))) + if (0 == strncmp(VG_PLATFORM, valid_archs[i].valgrind_name, + strlen(valid_archs[i].valgrind_name))) { default_arch = valid_archs[i].valgrind_name; default_cputype = valid_archs[i].cputype; @@ -319,7 +320,7 @@ int main(int argc, char** argv, char** envp) // --arch from command line arch = NULL; for (i = 0; i < valid_archs_count; i++) { - if (0 == strcmp(archname, valid_archs[i].apple_name) || + if (0 == strcmp(archname, valid_archs[i].apple_name) || 0 == strcmp(archname, valid_archs[i].valgrind_name)) { arch = valid_archs[i].valgrind_name; @@ -328,28 +329,28 @@ int main(int argc, char** argv, char** envp) } if (i == valid_archs_count) barf("Unknown --arch '%s'", archname); assert(NULL != arch); - VG_(debugLog)(1, "launcher", "using arch '%s' from --arch=%s\n", + VG_(debugLog)(1, "launcher", "using arch '%s' from --arch=%s\n", arch, archname); - } + } else if (clientname == NULL) { // no client executable; use default as fallback - VG_(debugLog)(1, "launcher", + VG_(debugLog)(1, "launcher", "no client specified, defaulting arch to '%s'\n", default_arch); arch = default_arch; - } + } else if ((arch = select_arch(clientname, default_cputype,default_arch))) { // arch from client executable VG_(debugLog)(1, "launcher", "selected arch '%s'\n", arch); - } + } else { // nothing found in client executable; use default as fallback - VG_(debugLog)(1, "launcher", + VG_(debugLog)(1, "launcher", "no arch detected, defaulting arch to '%s'\n", default_arch); arch = default_arch; } - + cwd = getcwd(NULL, 0); if (!cwd) barf("Current directory no longer exists."); @@ -357,28 +358,35 @@ int main(int argc, char** argv, char** envp) we can tell stage2. stage2 will use the name for recursive invocations of valgrind on child processes. */ memset(launcher_name, 0, PATH_MAX+1); - for (i = 0; envp[i]; i++) + for (i = 0; envp[i]; i++) ; /* executable path is after last envp item */ /* envp[i] == NULL ; envp[i+1] == executable_path */ - if (envp[i+1][0] != '/') { + executable_path = envp[i+1]; + /* Since macOS 10.14.6, executable_path is prefixed by "executable_path=", + like an environment list */ + if (strlen(executable_path) > 16 && strncmp(executable_path, "executable_path=", 16) == 0) { + executable_path = &executable_path[16]; + } + if (executable_path[0] != '/') { strcpy(launcher_name, cwd); strcat(launcher_name, "/"); } - if (strlen(launcher_name) + strlen(envp[i+1]) > PATH_MAX) + if (strlen(launcher_name) + strlen(executable_path) > PATH_MAX) barf("launcher path is too long"); - strcat(launcher_name, envp[i+1]); + strcat(launcher_name, executable_path); VG_(debugLog)(1, "launcher", "launcher_name = %s\n", launcher_name); /* tediously augment the env: VALGRIND_LAUNCHER=launcher_name */ asprintf(&new_line, VALGRIND_LAUNCHER "=%s", launcher_name); /* tediously augment the env: VALGRIND_STARTUP_PWD_%PID_XYZZY=current_working_dir */ - asprintf(&set_cwd, "VALGRIND_STARTUP_PWD_%u_XYZZY=%s", getppid(), cwd); + asprintf(&set_cwd, "VALGRIND_STARTUP_PWD_%d_XYZZY=%s", getppid(), cwd); // Note that Apple binaries get a secret fourth arg, "char* apple", which // contains the executable path. Don't forget about it. for (j = 0; envp[j]; j++) ; + // 4 includes VALGRIND_LAUNCHER, VALGRIND_STARTUP_PWD, NULL and executable_path new_env = malloc((j+4) * sizeof(char*)); if (new_env == NULL) barf("malloc of new_env failed."); diff --git a/coregrind/launcher-freebsd.c b/coregrind/launcher-freebsd.c index 56307d50b6..eaf09320bb 100644 --- a/coregrind/launcher-freebsd.c +++ b/coregrind/launcher-freebsd.c @@ -9,7 +9,7 @@ Copyright (C) 2000-2009 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2024 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or diff --git a/coregrind/m_addrinfo.c b/coregrind/m_addrinfo.c index 32d2fd4c90..6615bbca60 100644 --- a/coregrind/m_addrinfo.c +++ b/coregrind/m_addrinfo.c @@ -228,7 +228,14 @@ void VG_(describe_addr) ( DiEpoch ep, Addr a, /*OUT*/AddrInfo* ai ) if (tid != VG_INVALID_THREADID) { /* Should be below stack pointer, as if it is >= SP, it will have been described as StackPos_stacked above. */ - stackPos = StackPos_below_stack_ptr; +#if defined(VGO_linux) + const NSegment *seg = VG_(am_find_nsegment) (a); + /* On linux we might be hitting madvise guard pages, bug 514297 */ + if (seg->hasGuardPages && VG_(is_guarded)(a) ) { + stackPos = StackPos_guard_page; + } else +#endif + stackPos = StackPos_below_stack_ptr; } else { /* Try to find a stack with guard page containing a. For this, check if a is in a page mapped without r, w and x. */ diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c index 379ad773db..95473ff6a6 100644 --- a/coregrind/m_aspacemgr/aspacemgr-common.c +++ b/coregrind/m_aspacemgr/aspacemgr-common.c @@ -324,6 +324,12 @@ Int ML_(am_fcntl) ( Int fd, Int cmd, Addr arg ) return sr_isError(res) ? -1 : sr_Res(res); } +Int ML_(am_lseek) ( Int fd, vki_off_t off, Int whence ) +{ + SysRes res = VG_(do_syscall3)(__NR_lseek, fd, off, whence); + return sr_isError(res) ? -1 : sr_Res(res); +} + /* Get the dev, inode and mode info for a file descriptor, if possible. Returns True on success. */ Bool ML_(am_get_fd_d_i_m)( Int fd, diff --git a/coregrind/m_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c index e375076312..39f73b0cca 100644 --- a/coregrind/m_aspacemgr/aspacemgr-linux.c +++ b/coregrind/m_aspacemgr/aspacemgr-linux.c @@ -297,6 +297,13 @@ static NSegment nsegments[VG_N_SEGMENTS]; static Int nsegments_used = 0; +/* bookkeeping for madvise() guard pages, bug 514297 */ +#if defined(VGO_linux) +static UInt VG_N_GUARDS; +static Addr *guardpages; +static Int nguardpages_used = 0; +#endif + #define Addr_MIN ((Addr)0) #define Addr_MAX ((Addr)(-1ULL)) @@ -467,27 +474,32 @@ static void show_nsegment ( Int logLevel, Int segNo, const NSegment* seg ) { HChar len_buf[20]; show_len_concisely(len_buf, seg->start, seg->end); + const char *tail = ""; + +#if defined(VGO_linux) + tail = seg->hasGuardPages ? " (G)" : " (g)"; +#endif switch (seg->kind) { case SkFree: VG_(debugLog)( logLevel, "aspacem", - "%3d: %s %010lx-%010lx %s\n", + "%3d: %s %010lx-%010lx %s%s\n", segNo, show_SegKind(seg->kind), - seg->start, seg->end, len_buf + seg->start, seg->end, len_buf, tail ); break; case SkAnonC: case SkAnonV: case SkShmC: VG_(debugLog)( logLevel, "aspacem", - "%3d: %s %010lx-%010lx %s %c%c%c%c%c\n", + "%3d: %s %010lx-%010lx %s %c%c%c%c%c%s\n", segNo, show_SegKind(seg->kind), seg->start, seg->end, len_buf, seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', - seg->isCH ? 'H' : '-' + seg->isCH ? 'H' : '-', tail ); break; @@ -495,27 +507,28 @@ static void show_nsegment ( Int logLevel, Int segNo, const NSegment* seg ) VG_(debugLog)( logLevel, "aspacem", "%3d: %s %010lx-%010lx %s %c%c%c%c%c d=0x%03llx " - "i=%-7llu o=%-7lld (%d,%d)\n", + "i=%-7llu o=%-7lld (%d,%d)%s\n", segNo, show_SegKind(seg->kind), seg->start, seg->end, len_buf, seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', seg->isCH ? 'H' : '-', seg->dev, seg->ino, seg->offset, - ML_(am_segname_get_seqnr)(seg->fnIdx), seg->fnIdx + ML_(am_segname_get_seqnr)(seg->fnIdx), seg->fnIdx, + tail ); break; case SkResvn: VG_(debugLog)( logLevel, "aspacem", - "%3d: %s %010lx-%010lx %s %c%c%c%c%c %s\n", + "%3d: %s %010lx-%010lx %s %c%c%c%c%c %s%s\n", segNo, show_SegKind(seg->kind), seg->start, seg->end, len_buf, seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', seg->isCH ? 'H' : '-', - show_ShrinkMode(seg->smode) + show_ShrinkMode(seg->smode), tail ); break; @@ -631,7 +644,10 @@ static Bool sane_NSegment ( const NSegment* s ) case SkAnonC: case SkAnonV: case SkShmC: return s->smode == SmFixed - && s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1 +#if !defined(VGO_darwin) // on macOS we use ino as the vm_tag holder + && s->ino == 0 +#endif + && s->dev == 0 && s->offset == 0 && s->fnIdx == -1 && (s->kind==SkAnonC ? True : !s->isCH); case SkFileC: case SkFileV: @@ -672,6 +688,9 @@ static Bool maybe_merge_nsegments ( NSegment* s1, const NSegment* s2 ) case SkFree: s1->end = s2->end; +#if defined(VGO_linux) + s1->hasGuardPages |= s2->hasGuardPages; +#endif return True; case SkAnonC: case SkAnonV: @@ -679,6 +698,9 @@ static Bool maybe_merge_nsegments ( NSegment* s1, const NSegment* s2 ) && s1->hasX == s2->hasX && s1->isCH == s2->isCH) { s1->end = s2->end; s1->hasT |= s2->hasT; +#if defined(VGO_linux) + s1->hasGuardPages |= s2->hasGuardPages; +#endif return True; } break; @@ -691,6 +713,9 @@ static Bool maybe_merge_nsegments ( NSegment* s1, const NSegment* s2 ) + ((ULong)s2->start) - ((ULong)s1->start) ) { s1->end = s2->end; s1->hasT |= s2->hasT; +#if defined(VGO_linux) + s1->hasGuardPages |= s2->hasGuardPages; +#endif ML_(am_dec_refcount)(s1->fnIdx); return True; } @@ -702,6 +727,9 @@ static Bool maybe_merge_nsegments ( NSegment* s1, const NSegment* s2 ) case SkResvn: if (s1->smode == SmFixed && s2->smode == SmFixed) { s1->end = s2->end; +#if defined(VGO_linux) + s1->hasGuardPages |= s2->hasGuardPages; +#endif return True; } @@ -861,6 +889,7 @@ static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt prot, #if defined(VGO_darwin) // GrP fixme kernel info doesn't have dev/inode + // FIXME PJF but now ino is being used for vm tag cmp_devino = False; // GrP fixme V and kernel don't agree on offsets @@ -1057,6 +1086,264 @@ void ML_(am_do_sanity_check)( void ) AM_SANITY_CHECK; } +/*-----------------------------------------------------------------*/ +/*--- ---*/ +/*--- Low level access / modification of the guardpages array. ---*/ +/*--- ---*/ +/*-----------------------------------------------------------------*/ + +/* This bug 514297 related section is linux specific. + Guard whole the section with defined(VGO_linux) */ + +Bool is_guarded_segment( Int ); +Bool is_guarded_interval( Addr, Addr ); + +#if defined(VGO_linux) +static void guard_page_install ( Addr addr ) { + /* Note that this only installs guard pages into the + guardpages array. But it doesn't flag hasGuardPages + for segments having guard pages. + That's handled in guard_pages_install() below. */ + Addr addr_aligned = addr & ~(VKI_PAGE_SIZE - 1); + if (nguardpages_used >= VG_N_GUARDS) { + VG_(printf)("Use --max-guard-pages=INT to specify a larger number of\n" + "guard pages and rerun valgrind\n"); + VG_(core_panic)("Max number of guard pages is too low"); + } + // bisect + Int mid = 0, + lo = 0, + hi = nguardpages_used - 1; + while (True) { + if (lo > hi) { + break; + } else { + mid = (lo + hi) / 2; + if (addr_aligned < guardpages[mid]) { hi = mid - 1; continue; } + if (addr_aligned > guardpages[mid]) { lo = mid + 1; continue; } + if (addr_aligned == guardpages[mid]) { + VG_(debugLog)(0,"aspacem", + "Attempt to reinstall already existing guard page\n"); + return; + } + } + } + // merge in + for (Int i=nguardpages_used; i > lo; i--) + guardpages[i] = guardpages[i-1]; + guardpages[lo] = addr_aligned; + nguardpages_used++; +} + + +inline static void guard_pages_install ( Addr addr, SizeT len ) { + Int iLo = find_nsegment_idx(addr); + Int iHi = find_nsegment_idx(addr + len - 1); + + // Record the new guard pages in the guardpages array + Int pages = (len - 1) / VKI_PAGE_SIZE + 1; + for (Int i=0; i < pages; i++) + guard_page_install(addr + i * VKI_PAGE_SIZE); + + // These 5 should be guaranteed by find_nsegment_idx. + aspacem_assert(0 <= iLo && iLo < nsegments_used); + aspacem_assert(0 <= iHi && iHi < nsegments_used); + aspacem_assert(iLo <= iHi); + aspacem_assert(nsegments[iLo].start <= addr ); + aspacem_assert(nsegments[iHi].end >= addr + len - 1 ); + + // Flag the new guardpages in the nsegments array + for (Int i = iLo; i <= iHi; i++) + nsegments[i].hasGuardPages = True; +} + +static void guard_page_remove ( Addr addr, Bool check ) { + /* Note that this only removes guard pages from the + guardpages array. But it doesn't unflag hasGuardPages + for segments not having any guard pages any more. + That's handled in guard_pages_remove() below. */ + Addr addr_aligned = addr & ~(VKI_PAGE_SIZE - 1); + // search + Int mid = 0, + lo = 0, + hi = nguardpages_used - 1; + while (True) { + if (lo > hi) { + if (check == False) { + // Here we just return. The address wasn't found, and + // thus can't be removed from the evidence. This may + // happen when munmap() is called. Unmapping memory + // removes also guard pages. In this case we remove + // guard page from V's evidence if there is one, but + // if there is none, we don't complain and go ahead. + return; + } + } + aspacem_assert(lo <= hi); + mid = (lo + hi) / 2; + if (addr_aligned < guardpages[mid]) { hi = mid - 1; continue; } + if (addr_aligned > guardpages[mid]) { lo = mid + 1; continue; } + if (addr_aligned == guardpages[mid]) break; + } + // remove + for(Int i=mid; i= addr + len - 1 ); + + // Unflag segments not having any guard pages any more + for (Int i = iLo; i <= iHi; i++) { + Addr aLo = nsegments[i].start; + Addr aHi = nsegments[i].end; + guardPageSeen = False; + for (Int j = 0; j < nguardpages_used; j++) { + if ((guardpages[j] >= aLo) && (guardpages[j] <= aHi)) + guardPageSeen = True; + } + if (guardPageSeen == False) + nsegments[i].hasGuardPages = False; + + } +} + +static void is_guarded_sanity ( Addr addr, Bool expected ) +{ + static Int VG_(cl_pagemap_fd) = -1; + static Bool pagemap_io_err = False; + // Don't repeatedly complain about io /proc/self/pagemap IO errors + if (pagemap_io_err == True) + return; + if (VG_(cl_pagemap_fd) == -1) { + VG_(cl_pagemap_fd) = sr_Res(ML_(am_open)("/proc/self/pagemap", VKI_O_RDONLY, 0 )); + if(VG_(cl_pagemap_fd) == -1) { + pagemap_io_err = True; + VG_(debugLog)(0, "aspacem", "I/O error on /proc/self/pagemap"); + } + VG_(cl_pagemap_fd) = VG_(safe_fd)(VG_(cl_pagemap_fd)); + } + Addr addr_page_aligned = addr & ~(VKI_PAGE_SIZE - 1); + vki_off_t offset = ((vki_uint64_t)addr_page_aligned / VKI_PAGE_SIZE) * sizeof(vki_uint64_t); + Int ret = ML_(am_lseek) (VG_(cl_pagemap_fd), offset, VKI_SEEK_SET); + if (ret == -1) { + VG_(debugLog)(0, "aspacem", "failed lseek in pagemap\n"); + pagemap_io_err = True; + } + // https://docs.kernel.org/admin-guide/mm/pagemap.html + vki_uint64_t entry; // one 64-bit value for each virtual page + ret = ML_(am_read) (VG_(cl_pagemap_fd), &entry, sizeof(vki_uint64_t)); + if (ret == -1) { + VG_(debugLog)(0, "aspacem", "failed reading pagemap\n"); + pagemap_io_err = True; + } + if (((entry >> 58) & 1) == 1) { + VG_(debugLog)(1, "aspacem", + "madvise guard page hit at addr 0x%lx\n", addr); + if (expected == True) { + return; + } else { + ML_(am_barf)("FATAL: failed guard page sanity check\n"); + ML_(am_exit)(1); + } + } + if (expected == False) { + return; + } else { + VG_(debugLog)(0, "Valgrind:", + "FATAL: failed guard page sanity check\n"); + ML_(am_exit)(1); + } +} + +Bool VG_(is_guarded) ( Addr addr ) { + Addr addr_aligned = addr & ~(VKI_PAGE_SIZE - 1); + Int mid, + lo = 0, + hi = nguardpages_used - 1; + while (True) { + if (lo > hi) { + if (LIKELY(VG_(clo_sanity_level) < 3)) { + /* do nothing */ + } else { + is_guarded_sanity ( addr, False ); + } + return False; + } + mid = (lo + hi) / 2; + if (addr_aligned < guardpages[mid]) { hi = mid - 1; continue; } + if (addr_aligned > guardpages[mid]) { lo = mid + 1; continue; } + if (LIKELY(VG_(clo_sanity_level) < 3)) { + /* do nothing */ + } else { + is_guarded_sanity ( addr, True ); + } + return True; + } +} + +/* Check if segment with given id has at least one guard page */ +Bool is_guarded_segment( Int seg ) { + return is_guarded_interval (nsegments[seg].start, + nsegments[seg].end); +} + +/* Check if there is a guard page in the guardpages array + evidence in given interval of addresses */ +Bool is_guarded_interval ( Addr aStart, Addr aEnd ) { + if (nguardpages_used < 1) + return False; + /* Quickly find the beginning of interesting interval + of the guardpages array by bisecting it */ + Int mid = 0, + lo = 0, + hi = nguardpages_used - 1; + while (True) { + if (lo > hi) { + break; + } else { + mid = (lo + hi) / 2; + if (aStart < guardpages[mid]) { hi = mid - 1; continue; } + if (aStart > guardpages[mid]) { lo = mid + 1; continue; } + if (aStart == guardpages[mid]) { + /* Lucky enough to step on the guard page early */ + return True; + } + } + } + if (lo >= nguardpages_used) { + /* Out of range, no guard page for this segment for sure */ + return False; + } + /* Scan the interesting interval of guardpages array one by one */ + for (Int i = lo; i<= nguardpages_used; i++) { + if (guardpages[i] > aEnd) + return False; + return True; + } + return False; +} +#else +/* Provide stub VG_(is_guarded)() for non-linux targets */ +Bool VG_(is_guarded) ( Addr addr ) { + return False; +} +#endif /*-----------------------------------------------------------------*/ /*--- ---*/ @@ -1233,6 +1520,9 @@ Bool is_valid_for( UInt kinds, Addr start, SizeT len, UInt prot ) { Int i, iLo, iHi; Bool needR, needW, needX; +#if defined(VGO_linux) + Bool needGuardPageCheck = False; +#endif if (len == 0) return True; /* somewhat dubious case */ @@ -1263,11 +1553,23 @@ Bool is_valid_for( UInt kinds, Addr start, SizeT len, UInt prot ) && (needW ? nsegments[i].hasW : True) && (needX ? nsegments[i].hasX : True) ) { /* ok */ +#if defined(VGO_linux) + if ( ( nsegments[i].hasGuardPages ) + && (prot != VKI_PROT_NONE) ) { + needGuardPageCheck = True; + } +#endif } else { return False; } } +#if defined(VGO_linux) + if (needGuardPageCheck && VG_(is_guarded)(start)) { + return False; + } +#endif + return True; } @@ -1417,6 +1719,11 @@ static void split_nsegment_at ( Addr a ) ML_(am_inc_refcount)(nsegments[i].fnIdx); +#if defined(VGO_linux) + nsegments[i].hasGuardPages = is_guarded_segment(i); + nsegments[i+1].hasGuardPages = is_guarded_segment(i+1); +#endif + aspacem_assert(sane_NSegment(&nsegments[i])); aspacem_assert(sane_NSegment(&nsegments[i+1])); } @@ -1451,6 +1758,11 @@ void split_nsegments_lo_and_hi ( Addr sLo, Addr sHi, /* Not that I'm overly paranoid or anything, definitely not :-) */ } +#if defined(VGO_darwin) +#include "pub_core_tooliface.h" + +static void fill_segment(NSegment* seg); +#endif /* Add SEG to the collection, deleting/truncating any it overlaps. This deals with all the tricky cases of splitting up segments as @@ -1464,6 +1776,12 @@ static void add_segment ( const NSegment* seg ) Addr sStart = seg->start; Addr sEnd = seg->end; +#if defined(VGO_darwin) + // FIXME: adding for all segments causes some failures and alignment crashes in leak check + // need to debug more + //fill_segment((NSegment*) (Addr) seg); +#endif + aspacem_assert(sStart <= sEnd); aspacem_assert(VG_IS_PAGE_ALIGNED(sStart)); aspacem_assert(VG_IS_PAGE_ALIGNED(sEnd+1)); @@ -1525,6 +1843,9 @@ static void init_nsegment ( /*OUT*/NSegment* seg ) seg->isFF = False; seg->ignore_offset = False; #endif +#if defined(VGO_linux) + seg->hasGuardPages = False; +#endif } @@ -1598,6 +1919,10 @@ static void read_maps_callback ( Addr addr, SizeT len, UInt prot, seg.fnIdx = ML_(am_allocate_segname)( filename ); if (0) show_nsegment( 2,0, &seg ); +#if defined(VGO_darwin) + // FIXME this is the one that causes problems with leak checks + //fill_segment( &seg ); +#endif add_segment( &seg ); } @@ -1659,12 +1984,12 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) // --- Darwin ------------------------------------------- #if defined(VGO_darwin) -# if VG_WORDSIZE == 4 +#if defined(VGP_x86_darwin) aspacem_maxAddr = (Addr) 0xffffffff; aspacem_cStart = aspacem_minAddr; aspacem_vStart = 0xf0000000; // 0xc0000000..0xf0000000 available -# else +#elif defined(VGP_amd64_darwin) aspacem_maxAddr = (Addr) 0x7fffffffffff; aspacem_cStart = aspacem_minAddr; @@ -1920,10 +2245,16 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) if (aspacem_cStart > Addr_MIN) { init_resvn(&seg, Addr_MIN, aspacem_cStart-1); +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment(&seg); } if (aspacem_maxAddr < Addr_MAX) { init_resvn(&seg, aspacem_maxAddr+1, Addr_MAX); +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment(&seg); } @@ -1933,6 +2264,9 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) valgrind allocations at the boundary, this is kind of necessary in order to get it to start allocating in the right place. */ init_resvn(&seg, aspacem_vStart, aspacem_vStart + VKI_PAGE_SIZE - 1); +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment(&seg); VG_(am_show_nsegments)(2, "Initial layout"); @@ -1951,6 +2285,18 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) VG_(am_show_nsegments)(2, "With contents of /proc/self/maps"); +#if defined(VGO_linux) + /* With glibc upstream commit a6fbe36b7f31 and others, on x86_64, + a new madvise(MADV_GUARD_INSTALL ... ) guard page is installed for + each new thread. In the future, MADV_GUARD_INSTALL is likely to + be used with DSOs supporting multiple kernel page sizes. A rough + estimation of max madvise guard page count is Nthreads + 3 * DSOcnt. + Madvise guard pages are tracked in the guardpages array below. The + array size is set via --max-guard-pages or --max-threads: */ + VG_N_GUARDS = VG_(clo_max_guard_pages); + guardpages = VG_(calloc)("aspacem.guardpages", VG_N_GUARDS, sizeof(Addr)); +#endif + AM_SANITY_CHECK; return suggested_clstack_end; } @@ -2320,6 +2666,9 @@ VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags, seg.isFF = (flags & VKI_MAP_FIXED); #endif } +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; return needDiscard; @@ -2351,6 +2700,9 @@ VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot ) seg.hasR = toBool(prot & VKI_PROT_READ); seg.hasW = toBool(prot & VKI_PROT_WRITE); seg.hasX = toBool(prot & VKI_PROT_EXEC); +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; return needDiscard; @@ -2410,6 +2762,36 @@ Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot ) return needDiscard; } +/* Notifiy aspacem about madvise(MADV_GUARD_INSTALL), bug 514297 */ +#if defined(VGO_linux) +Bool VG_(am_notify_madv_guard)( Addr start, SizeT len, Bool install ) +{ + aspacem_assert(VG_IS_PAGE_ALIGNED(start)); + aspacem_assert(VG_IS_PAGE_ALIGNED(len)); + + if (len == 0) + return False; + + if (install) { + VG_(debugLog)(1, "aspacem", + "installing guard pages (addr=0x%lx, len=0x%lx)\n", + start, len); + guard_pages_install(start, len); + } else { + VG_(debugLog)(1, "aspacem", + "removing guard pages (addr=0x%lx, len=0x%lx)\n", + start, len); + guard_pages_remove(start, len, True); + } + + AM_SANITY_CHECK; + + // The return val determines whether translations will be discarded. + // That is supposed to happen when guard page is installed, but not + // otherwise. + return install; +} +#endif /* Notifies aspacem that an munmap completed successfully. The segment array is updated accordingly. As with @@ -2451,8 +2833,16 @@ Bool VG_(am_notify_munmap)( Addr start, SizeT len ) else seg.kind = SkFree; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); + /* Unmapping drops guard pages (if present) */ +#if defined(VGO_linux) + guard_pages_remove( start, len, False ); +#endif + /* Unmapping could create two adjacent free segments, so a preen is needed. add_segment() will do that, so no need to here. */ AM_SANITY_CHECK; @@ -2562,6 +2952,9 @@ SysRes VG_(am_mmap_named_file_fixed_client_flags) } #if defined(VGO_freebsd) seg.isFF = (flags & VKI_MAP_FIXED); +#endif +#if defined(VGO_darwin) + fill_segment( &seg ); #endif add_segment( &seg ); @@ -2621,6 +3014,9 @@ SysRes VG_(am_mmap_anon_fixed_client) ( Addr start, SizeT length, UInt prot ) seg.hasR = toBool(prot & VKI_PROT_READ); seg.hasW = toBool(prot & VKI_PROT_WRITE); seg.hasX = toBool(prot & VKI_PROT_EXEC); +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -2680,6 +3076,9 @@ static SysRes am_mmap_anon_float_client ( SizeT length, Int prot, Bool isCH ) seg.hasW = toBool(prot & VKI_PROT_WRITE); seg.hasX = toBool(prot & VKI_PROT_EXEC); seg.isCH = isCH; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -2782,6 +3181,9 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length ) seg.hasR = True; seg.hasW = True; seg.hasX = True; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -2874,6 +3276,9 @@ static SysRes VG_(am_mmap_file_float_valgrind_flags) ( SizeT length, UInt prot, } #if defined(VGO_freebsd) seg.isFF = (flags & VKI_MAP_FIXED); +#endif +#if defined(VGO_darwin) + fill_segment( &seg ); #endif add_segment( &seg ); @@ -3096,6 +3501,9 @@ Bool VG_(am_create_reservation) ( Addr start, SizeT length, reservation. */ seg.end = end1; seg.smode = smode; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -3269,6 +3677,9 @@ const NSegment *VG_(am_extend_map_client)( Addr addr, SizeT delta ) NSegment seg_copy = *seg; seg_copy.end += delta; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg_copy ); if (0) @@ -3342,6 +3753,9 @@ Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard, } seg.start = new_addr; seg.end = new_addr + new_len - 1; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); /* Create a free hole in the old location. */ @@ -3357,6 +3771,9 @@ Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard, else seg.kind = SkFree; +#if defined(VGO_darwin) + fill_segment( &seg ); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -3693,6 +4110,35 @@ static void parse_procselfmaps ( if (record_gap && gapStart < Addr_MAX) (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 ); + +#if defined(VGO_linux) + // Iterate over guard pages + for (i = 0; i #include +#include static unsigned int mach2vki(unsigned int vm_prot) { @@ -3711,6 +4158,353 @@ static unsigned int mach2vki(unsigned int vm_prot) ((vm_prot & VM_PROT_EXECUTE) ? VKI_PROT_EXEC : 0) ; } +static Int get_filename_for_region(int pid, Addr addr, HChar* path, SizeT path_len, ULong* vm_tag) { + int ret; + SizeT len; + struct proc_regionwithpathinfo info; + VG_(memset)(&info, 0, sizeof(info)); + ret = sr_Res(VG_(do_syscall6)(__NR_proc_info, 2, pid, PROC_PIDREGIONPATHINFO, addr, (Addr)&info, sizeof(info))); + if (ret == -1) { + return ret; + } + if (vm_tag) { + *vm_tag = info.prp_prinfo.pri_user_tag; + } + len = VG_(strlen)(&info.prp_vip.vip_path[0]); + if (len == 0) { + return 0; + } + len += 1; // include the null terminator + if (len > path_len) { + len = path_len; + } + VG_(strlcpy)(path, info.prp_vip.vip_path, len); + return len; +} + +static Bool get_name_from_tag(int tag, HChar* path, SizeT path_len) { + switch (tag) { + case VKI_VM_MEMORY_DYLD: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[internal dyld memory]", path_len); + return True; + case VKI_VM_MEMORY_OS_ALLOC_ONCE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[kernel alloc once]", path_len); + return True; + case VKI_VM_MEMORY_GENEALOGY: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[activity tracing]", path_len); + return True; + case VKI_VM_MEMORY_BRK: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[brk]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc memory]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC_HUGE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (huge) memory]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC_LARGE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (large) memory]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC_SMALL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (small) memory]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC_TINY: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (tiny) memory]", path_len); + return True; + case VKI_VM_MEMORY_MALLOC_NANO: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (nano) memory]", path_len); + return True; + case VM_MEMORY_MACH_MSG: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[mach message]", path_len); + return True; + case VKI_VM_MEMORY_ANALYSIS_TOOL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[analysis tool]", path_len); + return True; + case VKI_VM_MEMORY_STACK: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[stack]", path_len); + return True; + case VKI_VM_MEMORY_SHARED_PMAP: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[shared pmap]", path_len); + return True; + case VKI_VM_MEMORY_UNSHARED_PMAP: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[unshared pmap]", path_len); + return True; + case VKI_VM_MEMORY_REALLOC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[realloc]", path_len); + break; + case VKI_VM_MEMORY_MALLOC_LARGE_REUSABLE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (large, reusable) memory]", path_len); + break; + case VKI_VM_MEMORY_MALLOC_LARGE_REUSED: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (large, reused) memory]", path_len); + break; + case VKI_VM_MEMORY_MALLOC_MEDIUM: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc (medium) memory]", path_len); + break; + case VKI_VM_MEMORY_MALLOC_PROB_GUARD: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[malloc prob guard]", path_len); + break; + case VKI_VM_MEMORY_IOKIT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[iokit]", path_len); + break; + case VKI_VM_MEMORY_GUARD: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[guard]", path_len); + break; + case VKI_VM_MEMORY_DYLIB: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[dylib]", path_len); + break; + case VKI_VM_MEMORY_OBJC_DISPATCHERS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[objc dispatchers]", path_len); + break; + case VKI_VM_MEMORY_APPKIT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[appkit]", path_len); + break; + case VKI_VM_MEMORY_FOUNDATION: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[foundation]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics]", path_len); + break; + case VKI_VM_MEMORY_CORESERVICES: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core services]", path_len); + break; + case VKI_VM_MEMORY_JAVA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[java]", path_len); + break; + case VKI_VM_MEMORY_COREDATA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core data]", path_len); + break; + case VKI_VM_MEMORY_COREDATA_OBJECTIDS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core data object ids]", path_len); + break; + case VKI_VM_MEMORY_ATS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[ats]", path_len); + break; + case VKI_VM_MEMORY_LAYERKIT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[layer kit]", path_len); + break; + case VKI_VM_MEMORY_CGIMAGE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics image]", path_len); + break; + case VKI_VM_MEMORY_TCMALLOC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[tcmalloc]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS_DATA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics data]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS_SHARED: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics shared]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics framebuffers]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS_BACKINGSTORES: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics backing stores]", path_len); + break; + case VKI_VM_MEMORY_COREGRAPHICS_XALLOC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core graphics xalloc]", path_len); + break; + case VKI_VM_MEMORY_DYLD_MALLOC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[dyld malloc]", path_len); + break; + case VKI_VM_MEMORY_SQLITE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[sqlite]", path_len); + break; + case VKI_VM_MEMORY_JAVASCRIPT_CORE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[javascript core]", path_len); + break; + case VKI_VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[javascript jit executable allocator]", path_len); + break; + case VKI_VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[javascript jit register file]", path_len); + break; + case VKI_VM_MEMORY_GLSL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[glsl]", path_len); + break; + case VKI_VM_MEMORY_OPENCL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[opencl]", path_len); + break; + case VKI_VM_MEMORY_COREIMAGE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core image]", path_len); + break; + case VKI_VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[webcore purgeable buffers]", path_len); + break; + case VKI_VM_MEMORY_IMAGEIO: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[imageio]", path_len); + break; + case VKI_VM_MEMORY_COREPROFILE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core profile]", path_len); + break; + case VKI_VM_MEMORY_ASSETSD: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[assetsd]", path_len); + break; + case VKI_VM_MEMORY_LIBDISPATCH: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[libdispatch]", path_len); + break; + case VKI_VM_MEMORY_ACCELERATE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[accelerate]", path_len); + break; + case VKI_VM_MEMORY_COREUI: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core ui]", path_len); + break; + case VKI_VM_MEMORY_COREUIFILE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core ui file]", path_len); + break; + case VKI_VM_MEMORY_RAWCAMERA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[raw camera]", path_len); + break; + case VKI_VM_MEMORY_CORPSEINFO: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[corpse info]", path_len); + break; + case VKI_VM_MEMORY_ASL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[asl]", path_len); + break; + case VKI_VM_MEMORY_SWIFT_RUNTIME: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[swift runtime]", path_len); + break; + case VKI_VM_MEMORY_SWIFT_METADATA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[swift metadata]", path_len); + break; + case VKI_VM_MEMORY_DHMM: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[dhmm]", path_len); + break; + case VKI_VM_MEMORY_SCENEKIT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[scene kit]", path_len); + break; + case VKI_VM_MEMORY_SKYWALK: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[skywalk]", path_len); + break; + case VKI_VM_MEMORY_IOSURFACE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[io surface]", path_len); + break; + case VKI_VM_MEMORY_LIBNETWORK: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[libnetwork]", path_len); + break; + case VKI_VM_MEMORY_AUDIO: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[audio]", path_len); + break; + case VKI_VM_MEMORY_VIDEOBITSTREAM: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[video bitstream]", path_len); + break; + case VKI_VM_MEMORY_CM_XPC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm xpc]", path_len); + break; + case VKI_VM_MEMORY_CM_RPC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm rpc]", path_len); + break; + case VKI_VM_MEMORY_CM_MEMORYPOOL: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm memory pool]", path_len); + break; + case VKI_VM_MEMORY_CM_READCACHE: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm read cache]", path_len); + break; + case VKI_VM_MEMORY_CM_CRABS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm crabs]", path_len); + break; + case VKI_VM_MEMORY_QUICKLOOK_THUMBNAILS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[quicklook thumbnails]", path_len); + break; + case VKI_VM_MEMORY_ACCOUNTS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[accounts]", path_len); + break; + case VKI_VM_MEMORY_SANITIZER: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[sanitizer]", path_len); + break; + case VKI_VM_MEMORY_IOACCELERATOR: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[io accelerator]", path_len); + break; + case VKI_VM_MEMORY_CM_REGWARP: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm regwarp]", path_len); + break; + case VKI_VM_MEMORY_EAR_DECODER: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[ear decoder]", path_len); + break; + case VKI_VM_MEMORY_COREUI_CACHED_IMAGE_DATA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[core ui cached image data]", path_len); + break; + case VKI_VM_MEMORY_COLORSYNC: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[color sync]", path_len); + break; + case VKI_VM_MEMORY_BTINFO: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[bt info]", path_len); + break; + case VKI_VM_MEMORY_CM_HLS: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[cm hls]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_THREAD_CONTEXT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta thread context]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_INDIRECT_BRANCH_MAP: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta indirect branch map]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_RETURN_STACK: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta return stack]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_EXECUTABLE_HEAP: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta executable heap]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_USER_LDT: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta user ldt]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_ARENA: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta arena]", path_len); + break; + case VKI_VM_MEMORY_ROSETTA_10: + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[rosetta 10]", path_len); + break; + case VKI_VM_MEMORY_VALGRIND: + case 0: + return False; + default: + if (tag >= VKI_VM_MEMORY_APPLICATION_SPECIFIC_1 && tag <= VKI_VM_MEMORY_APPLICATION_SPECIFIC_16) { + VG_(strlcpy)(path, DARWIN_FAKE_MEMORY_PATH "[application specific]", path_len); + return True; + } + VG_(debugLog)(0, "aspacem", "unknown vm tag: %d\n", tag); + return False; + } + return True; +} + +static void fill_segment(NSegment* seg) { + Int pid; + HChar name[VKI_PATH_MAX]; + Int ret; + + if (seg->fnIdx != -1 || seg->kind == SkFree || seg->kind == SkResvn) { + return; + } + + pid = sr_Res(VG_(do_syscall0)(__NR_getpid)); + ret = get_filename_for_region(pid, seg->start, name, sizeof(name), &seg->ino); + if (ret != 0) { + if (ret == -1) { + return; + } + } else if (get_name_from_tag(seg->ino, name, sizeof(name))) { + // these are owned by the kernel and are already initialized + // we flag them as client so m_main.c track them correctly + seg->kind = SkFileC; + } else { + return; + } + seg->fnIdx = ML_(am_allocate_segname)( name ); +} + +static Bool endswith(const HChar* str, const HChar* suffix) { + SizeT str_len = VG_(strlen)(str); + SizeT suffix_len = VG_(strlen)(suffix); + if (str_len < suffix_len) { + return False; + } + return VG_(strcmp)(str + str_len - suffix_len, suffix) == 0; +} + static UInt stats_machcalls = 0; static void parse_procselfmaps ( @@ -3723,13 +4517,16 @@ static void parse_procselfmaps ( vm_address_t iter; unsigned int depth; vm_address_t last; + HChar name[VKI_PATH_MAX]; + Bool ret; + Int pid = sr_Res(VG_(do_syscall0)(__NR_getpid)); iter = 0; depth = 0; last = 0; while (1) { mach_vm_address_t addr = iter; - mach_vm_size_t size; + mach_vm_size_t size = 0; vm_region_submap_short_info_data_64_t info; kern_return_t kr; @@ -3749,12 +4546,19 @@ static void parse_procselfmaps ( } iter = addr + size; + // FIXME: not sure we should fill up anything here as it will added later anyway + ret = get_filename_for_region(pid, addr, name, sizeof(name), NULL); + if (!ret) { + ret = get_name_from_tag(info.user_tag, name, sizeof(name)); + } + + if (addr > last && record_gap) { (*record_gap)(last, addr - last); } if (record_mapping) { (*record_mapping)(addr, size, mach2vki(info.protection), - 0, 0, info.offset, NULL, False); + 0, info.user_tag, info.offset, ret ? name : NULL, False); } last = addr + size; } @@ -3964,32 +4768,33 @@ static char* maybe_merge_procmap_stack(char* p, struct vki_kinfo_vmentry *kve, { static Bool sgrowsiz_read = False; static SizeT kern_sgrowsiz; + static SizeT kern_maxssiz; if (!sgrowsiz_read) { SizeT sysctl_size = sizeof(SizeT); - VG_(sysctlbyname)("kern.sgrowsiz", &kern_sgrowsiz, &sysctl_size, NULL, 0); + Int res = VG_(sysctlbyname)("kern.sgrowsiz", &kern_sgrowsiz, &sysctl_size, NULL, 0); + vg_assert(res == 0); +#if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd) + res = VG_(sysctlbyname)("kern.maxssiz", &kern_maxssiz, &sysctl_size, NULL, 0); + vg_assert(0 == res); +#elif defined (VGP_x86_freebsd) + // first check for x86 on amd64 + res = VG_(sysctlbyname)("compat.ia32.maxssiz", &kern_maxssiz, &sysctl_size, NULL, 0); + if (0 != res) { + // then x86 on x86 + res = VG_(sysctlbyname)("kern.maxssiz", &kern_maxssiz, &sysctl_size, NULL, 0); + } + vg_assert(0 == res); +#else +#error "unknown FreeBSD platform" +#endif sgrowsiz_read = True; } char* p_next = p + kve->kve_structsize; struct vki_kinfo_vmentry *kve_next = (struct vki_kinfo_vmentry *)(p_next); -#if defined(VGP_amd64_freebsd) - // I think that this is the stacksize rlimit - // I could use sysctl kern.maxssiz for this - if ( *pEndPlusOne + kern_sgrowsiz - kve->kve_start == 512ULL*1024ULL*1024ULL) { - return p; - } -#elif defined(VGP_x86_freebsd) - // sysctl kern.maxssiz OK for x86 on x86 but not x86 on amd64 - if ( *pEndPlusOne + kern_sgrowsiz - kve->kve_start == 64ULL*1024ULL*1024ULL) { - return p; - } -#elif defined(VGP_arm64_freebsd) - if ( *pEndPlusOne + kern_sgrowsiz - kve->kve_start == 1024ULL*1024ULL*1024ULL) { + if ( *pEndPlusOne + kern_sgrowsiz - kve->kve_start == kern_maxssiz) { return p; } -#else -# error Unknown platform -#endif while (kve_next->kve_protection & VKI_KVME_PROT_READ && kve_next->kve_protection & VKI_KVME_PROT_WRITE && @@ -4016,8 +4821,6 @@ static char* maybe_merge_procmap_stack(char* p, struct vki_kinfo_vmentry *kve, /* - * PJF 2023-09-23 - * * This function is somewhat badly named for FreeBSD, where the * /proc filesystem is optional so we can't count on users * having it. Instead we use the KERN_PROC_VMMAP syscall. @@ -4031,8 +4834,8 @@ static char* maybe_merge_procmap_stack(char* p, struct vki_kinfo_vmentry *kve, * The other use is at startup in order to get the mapping for the * tool itself. In this case we have a fairly big problem. There is * a difference in the mapping used when the kernel loads an exe - * and when the link loader ldrt (or Valgrind which does the same - * job for the guest exe. In the case of ldrt, all ELF PT_LOAD + * and when the link loader rtld (or Valgrind which does the same + * job for the guest exe). In the case of rtld, all ELF PT_LOAD * sections get mmap'd. The kernel, however, does _not_ mmap * the RW PT_LOAD. * @@ -4052,9 +4855,32 @@ static char* maybe_merge_procmap_stack(char* p, struct vki_kinfo_vmentry *kve, * Instead of mmap'ing the RW PT_LOAD the kernel has mmap'd anonymous swap and copied from the exe file. * See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273956 * - * So what can we do? We can reuse most of the info from the previous 'r-x' mapping. - * The filename, dev and ino are all the same. That leaves the offset. We can - * make a rough estimate of the value as being previous offset + previous size. + * If Valgrind is built with GNU bfd.ld (which could be with clang or GCC) then we have + * + * objdump -p .in_place/memcheck-amd64-freebsd + * LOAD off 0x0000000000000000 vaddr 0x0000000038000000 paddr 0x0000000038000000 align 2**12 + * filesz 0x0000000000297b40 memsz 0x0000000000297b40 flags r-x + * LOAD off 0x0000000000298000 vaddr 0x0000000038298000 paddr 0x0000000038298000 align 2**12 + * filesz 0x0000000000000a38 memsz 0x00000000025dcfb8 flags rw- + * + * and the procstat -v output + * 57440 0x38000000 0x38298000 r-x 664 2776 1 0 CN--- vn /home/paulf/valgrind/memcheck/memcheck-amd64-freebsd + * 57440 0x38298000 0x3a875000 rw- 4512 4512 1 0 ----- sw + * + * Is that complicated enough? No. + * + * The final RW PT_LOAD for the host can be split (at least when building + * with the LLVM toolchain). + * + * 40751 0x38000000 0x380cc000 r-- 204 2722 3 1 CN--- vn /home/paulf/scratch/valgrind/memcheck/memcheck-amd64-freebsd + * 40751 0x380cc000 0x38294000 r-x 456 2722 3 1 CN--- vn /home/paulf/scratch/valgrind/memcheck/memcheck-amd64-freebsd + * 40751 0x38294000 0x38295000 rw- 1 0 1 0 C---- vn /home/paulf/scratch/valgrind/memcheck/memcheck-amd64-freebsd + * 40751 0x38295000 0x3a872000 rw- 4587 4587 1 0 --S-- sw + * + * So what can we do? We can reuse most of the info from the previous 'r-x' + * or 'rw-' mapping. The filename, dev and ino are all the same. That leaves + * the offset. We can make a rough estimate of the value as being + * previous offset + previous size. * Since the addresses in memory will be page aligned it's not possible to * obtain the original offset. It isn't good enough for ML_(read_elf_object) * in readelf.c @@ -4067,6 +4893,12 @@ static char* maybe_merge_procmap_stack(char* p, struct vki_kinfo_vmentry *kve, * if Valgrind crashes or asserts it will print its own stack without * debuginfo, which is mostly useless. See the above FreeBSD bugzilla item * for an example. + * + * The rule for triggering the recording of the part or whole RW PT_LOAD + * mapped as swap is: + * + * "The first time that there is a swap mapping after a RW or RX mapping + * then also record that swap mapping." */ /* Size of a smallish table used to read /proc/self/map entries. */ @@ -4088,27 +4920,11 @@ static void parse_procselfmaps ( UInt prot; ULong foffset, dev, ino; struct vki_kinfo_vmentry *kve; - vki_size_t len; + SizeT len; Int oid[4]; SysRes sres; - Int map_count = 0; - // this assumes that compiling with clang uses ld.lld which produces 3 LOAD segements - // and that compiling with GCC uses ld.bfd which produces 2 LOAD segments -#if defined(__clang__) - Int const rx_map = 1; - Int const rw_map = 2; -#elif defined(__GNUC__) - Int const rx_map = 0; - Int const rw_map = 1; -#else -#error("unsupported compiler") -#endif - // could copy the whole kinfo_vmentry but it is 1160 bytes - char *rx_filename = NULL; - ULong rx_dev = 0U; - ULong rx_ino = 0U; - ULong rx_foffset = 0U; Bool tool_read_maps = (record_mapping == read_maps_callback); + Bool host_rw_map_swap_hack_done = False; foffset = ino = 0; /* keep gcc-4.1.0 happy */ @@ -4144,16 +4960,6 @@ static void parse_procselfmaps ( if (kve->kve_protection & VKI_KVME_PROT_WRITE) prot |= VKI_PROT_WRITE; if (kve->kve_protection & VKI_KVME_PROT_EXEC) prot |= VKI_PROT_EXEC; - map_count = (p - (char *)procmap_buf)/kve->kve_structsize; - - if (tool_read_maps && map_count == rw_map) { - aspacem_assert((prot & (VKI_PROT_READ | VKI_PROT_WRITE)) == (VKI_PROT_READ | VKI_PROT_WRITE)); - filename = rx_filename; - dev = rx_dev; - ino = rx_ino; - foffset = rx_foffset; - } - if (record_gap && gapStart < start) (*record_gap) ( gapStart, start-gapStart ); @@ -4163,27 +4969,48 @@ static void parse_procselfmaps ( p = maybe_merge_procmap_stack(p, kve, &endPlusOne, &prot); } + /* a normal mapping */ if (record_mapping && start < endPlusOne) { (*record_mapping) ( start, endPlusOne-start, prot, dev, ino, - foffset, filename, tool_read_maps && map_count == 2 ); + foffset, filename, False ); } - if (tool_read_maps && map_count == rx_map) { - aspacem_assert((prot & (VKI_PROT_READ | VKI_PROT_EXEC)) == (VKI_PROT_READ | VKI_PROT_EXEC)); - rx_filename = filename; - rx_dev = dev; - rx_ino = ino; - /* this is only accurate to the page alignment */ - rx_foffset = foffset + endPlusOne - start; + /* check for the host RW segment partially or wholly mapped as swap */ + if (!host_rw_map_swap_hack_done && + tool_read_maps && + (((prot & (VKI_PROT_READ | VKI_PROT_EXEC)) == (VKI_PROT_READ | VKI_PROT_EXEC)) || + ((prot & (VKI_PROT_READ | VKI_PROT_WRITE)) == (VKI_PROT_READ | VKI_PROT_WRITE))) && + filename && + p + kve->kve_structsize < (char*)procmap_buf + len) { + char* p_next = p + kve->kve_structsize; + struct vki_kinfo_vmentry* kve_next = (struct vki_kinfo_vmentry *)p_next; + UInt prot_next = 0; + if (kve_next->kve_protection & VKI_KVME_PROT_READ) prot_next |= VKI_PROT_READ; + if (kve_next->kve_protection & VKI_KVME_PROT_WRITE) prot_next |= VKI_PROT_WRITE; + if (kve_next->kve_protection & VKI_KVME_PROT_EXEC) prot_next |= VKI_PROT_EXEC; + if (((prot_next & (VKI_PROT_READ | VKI_PROT_WRITE)) == (VKI_PROT_READ | VKI_PROT_WRITE)) && + (kve_next->kve_type == VKI_KVME_TYPE_SWAP)) { + Addr start_next = (UWord)kve_next->kve_start; + Addr endPlusOne_next = (UWord)kve_next->kve_end; + if (record_mapping && start_next < endPlusOne_next) { + (*record_mapping) ( start_next, endPlusOne_next-start_next, + prot_next, dev, ino, + foffset + start_next - start, + filename, True ); + p += kve_next->kve_structsize; + host_rw_map_swap_hack_done = True; + } + } } gapStart = endPlusOne; - // PJF I think that we need to walk this based on each entry's kve_structsize + // We need to walk this based on each entry's kve_structsize // because sysctl kern.coredump_pack_fileinfo (on by default) can cause this // array to be packed (for core dumps) // the packing consists of only storing the used part of kve_path rather than - // the full 1024 bytes + // the full 1024 bytes. + // Other BSDs do not provide the filename and can therefore use sizeof. p += kve->kve_structsize; } diff --git a/coregrind/m_aspacemgr/priv_aspacemgr.h b/coregrind/m_aspacemgr/priv_aspacemgr.h index 978c58b987..e64ae5eea3 100644 --- a/coregrind/m_aspacemgr/priv_aspacemgr.h +++ b/coregrind/m_aspacemgr/priv_aspacemgr.h @@ -51,14 +51,21 @@ // VG_(mk_SysRes_Error) // VG_(mk_SysRes_Success) -#include "pub_core_options.h" // VG_(clo_sanity_level) +#include "pub_core_options.h" // VG_(clo_sanity_level), VG_(clo_max_guard_pages) #if defined(VGO_freebsd) #include "pub_core_libcproc.h" // VG_(sysctlbyname) #endif #include "pub_core_aspacemgr.h" // self +#if defined(VGO_darwin) +#include "pub_core_mach.h" // macos support +#endif +#if defined(VGO_linux) +#include "pub_core_libcfile.h" // VG_(safe_fd) +#include "pub_core_mallocfree.h" // VG_(calloc) +#endif /* --------------- Implemented in aspacemgr-common.c ---------------*/ @@ -116,6 +123,7 @@ extern void ML_(am_close) ( Int fd ); extern Int ML_(am_read) ( Int fd, void* buf, Int count); extern Int ML_(am_readlink) ( const HChar* path, HChar* buf, UInt bufsiz ); extern Int ML_(am_fcntl) ( Int fd, Int cmd, Addr arg ); +extern Int ML_(am_lseek) ( Int fd, vki_off_t off, Int whence ); /* Get the dev, inode and mode info for a file descriptor, if possible. Returns True on success. */ diff --git a/coregrind/m_cache.c b/coregrind/m_cache.c index fd6f801c13..2777f8c6f6 100644 --- a/coregrind/m_cache.c +++ b/coregrind/m_cache.c @@ -614,11 +614,6 @@ get_cache_info(VexArchInfo *vai) ci->icaches_maintain_coherence = True; - if (! (vai->hwcaps & VEX_HWCAPS_S390X_GIE)) { - // ECAG is not available - return False; - } - UInt level, cache_kind, info, i; ULong topology = ecag(0, 0, 0); // get summary diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 97f98b62b3..6f5c1ae254 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -9,7 +9,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright (C) 2000-2017 Julian Seward + Copyright (C) 2000-2017 Julian Seward jseward@acm.org This program is free software; you can redistribute it and/or @@ -61,11 +61,11 @@ #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) # include "priv_readelf.h" # include "priv_readdwarf3.h" -# include "priv_readpdb.h" #elif defined(VGO_darwin) # include "priv_readmacho.h" -# include "priv_readpdb.h" +# include "pub_core_mach.h" #endif +# include "priv_readpdb.h" #if defined(VGO_freebsd) #include "pub_core_clientstate.h" #endif @@ -84,14 +84,14 @@ debuginfo reading confusing. Recently I arrived at some terminology which makes it clearer (to me, at least). There are 3 kinds of address used in the debuginfo reading process: - + stated VMAs - the address where (eg) a .so says a symbol is, that is, what it tells you if you consider the .so in isolation - + actual VMAs - the address where (eg) said symbol really wound up after the .so was mapped into memory - + image addresses - pointers into the copy of the .so (etc) transiently mmaped aboard whilst we read its info @@ -298,7 +298,7 @@ static void show_epochs ( const HChar* msg ) static ULong handle_counter = 1; /* Allocate and zero out a new DebugInfo record. */ -static +static DebugInfo* alloc_DebugInfo( const HChar* filename ) { Bool traceme; @@ -317,7 +317,7 @@ DebugInfo* alloc_DebugInfo( const HChar* filename ) /* Everything else -- pointers, sizes, arrays -- is zeroed by ML_(dinfo_zalloc). Now set up the debugging-output flags. */ - traceme + traceme = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ); if (traceme) { di->trace_symtab = VG_(clo_trace_symtab); @@ -327,6 +327,10 @@ DebugInfo* alloc_DebugInfo( const HChar* filename ) di->ddump_frames = VG_(clo_debug_dump_frames); } +#if DARWIN_VERS >= DARWIN_11_00 + di->from_memory = False; +#endif + return di; } @@ -463,7 +467,7 @@ static void discard_or_archive_DebugInfo ( DebugInfo* di ) if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)) VG_(dmsg)("%s syms at %#lx-%#lx in %s (have_dinfo %d)\n", archive ? "Archiving" : "Discarding", - di->text_avma, + di->text_avma, di->text_avma + di->text_size, curr->fsm.filename ? curr->fsm.filename : "???", @@ -541,7 +545,7 @@ static Bool discard_syms_in_range ( Addr start, SizeT length ) static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) { Addr e1, e2; - if (len1 == 0 || len2 == 0) + if (len1 == 0 || len2 == 0) return False; e1 = s1 + len1 - 1; e2 = s2 + len2 - 1; @@ -557,9 +561,26 @@ static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) /* Do the basic mappings of the two DebugInfos overlap in any way? */ static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 ) { - Word i, j; vg_assert(di1); vg_assert(di2); +#if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_10_15 + // FIXME: This is probably wrong but the other methods returns too many false positives + // as it doesn't account for munmap being called on one of these maps. + // dyld will mmap and then munmap every library ro_map at the same address thus every library shows + // an overlap and only the last is retained, making most debug UNKNOW_FUNCTION UNKNOWN_OBJECT. + // Seeing how discard_syms_in_range relies exclusively on text_* to check conflicts, let's do the same here + + // Sanity check needed by discard_DebugInfos_which_overlap_with + if (di1 == di2) { + return True; + } + if (!di1->text_present || !di2->text_present) { + return False; + } + return ranges_overlap(di1->text_avma, di1->text_size, di2->text_avma, di2->text_size); +#else + Word i, j; + for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) { const DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i); for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { @@ -571,6 +592,7 @@ static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 ) } return False; +#endif } @@ -832,7 +854,7 @@ static Bool overlaps_DebugInfoMappings ( const DebugInfoMapping* map1, /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */ -static void show_DebugInfoMappings +static void show_DebugInfoMappings ( const DebugInfo* di, /*MOD*/XArray* maps /* XArray */ ) { @@ -936,7 +958,7 @@ static void truncate_DebugInfoMapping_overlaps /* When the sequence of observations causes a DebugInfoFSM to move into the accept state, call here to actually get the debuginfo read - in. Returns a ULong whose purpose is described in comments + in. Returns a ULong whose purpose is described in comments preceding VG_(di_notify_mmap) just below. */ static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) @@ -1156,7 +1178,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) if (debug) { VG_(dmsg)("di_notify_mmap-0:\n"); VG_(dmsg)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", - seg->start, seg->end, + seg->start, seg->end, seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); } @@ -1170,6 +1192,13 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) return 0; /* If the file doesn't have a name, we're hosed. Give up. */ + /* + * Maybe not. Since bug 280965 we may have the fd, and if we + * do have the fd we use that rather than the filename to + * get ELF info. The filename is used in several places but I think + * that it is not obligatory and when we have just the fd we could + * get by. + */ filename = VG_(am_get_filename)( seg ); if (!filename) return 0; @@ -1179,8 +1208,11 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) * --20208-- WARNING: Serious error when reading debug info * --20208-- When reading debug info from /proc/xen/privcmd: * --20208-- can't read file to inspect ELF header + * + * Also PCI devices, see bug 514206 */ - if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0) + if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0 || + VG_(strncmp)(filename, "/sys/devices/pci", 16) == 0) return 0; if (debug) @@ -1198,6 +1230,9 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) if (sr_isError(statres)) { DebugInfo fake_di; Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL +#if defined(VGO_darwin) + || VG_(strstr)(filename, DARWIN_FAKE_MEMORY_PATH) != NULL +#endif || VG_(strstr)(filename, "/dev/shm/") != NULL || VG_(strncmp)("/memfd:", filename, VG_(strlen)("/memfd:")) == 0; @@ -1490,7 +1525,7 @@ void VG_(addr_load_di)( Addr a ) VG_(di_load_di)(di); } -/* Unmap is simpler - throw away any SegInfos intersecting +/* Unmap is simpler - throw away any SegInfos intersecting [a, a+len). */ void VG_(di_notify_munmap)( Addr a, SizeT len ) { @@ -1642,7 +1677,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, VG_(message)(Vg_UserMsg, "\n"); VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " - "bias=%#lx\n", + "bias=%#lx\n", fd_obj, avma_obj, total_size, (UWord)bias_obj ); } @@ -1661,7 +1696,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, return; /* failed */ sz_exename = VG_(strlen)(exe); HChar exename[sz_exename + 1]; - VG_(strcpy)(exename, exe); // make a copy on the stack + VG_(strcpy)(exename, exe); // make a copy on the stack if (VG_(clo_verbosity) > 0) { VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); @@ -1861,6 +1896,62 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, #endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) */ +#if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_11_00 +// Special version of VG_(di_notify_mmap) specifically to read debug info from the DYLD Shared Cache (DSC) +// We only use this on macOS 11.0 and later, because Apple stopped shipping dylib on-disk then. + +ULong VG_(di_notify_dsc)( const HChar* filename, Addr header, SizeT len ) +{ + DebugInfo* di; + Int rw_load_count; + const Bool debug = VG_(debugLog_getLevel)() >= 3; + + if (debug) + VG_(dmsg)("di_notify_dsc-1: %s at %#lx-%#lx\n", filename, header, header+len); + + if (!ML_(check_macho_and_get_rw_loads_from_memory)( (const void*) header, len, &rw_load_count )) + return 0; + + /* See if we have a DebugInfo for this filename. If not, + create one. */ + di = find_or_create_DebugInfo_for( filename ); + vg_assert(di); + + di->from_memory = True; + + if (di->have_dinfo) { + if (debug) + VG_(dmsg)("di_notify_dsc-2x: " + "ignoring mapping because we already read debuginfo " + "for DebugInfo* %p\n", di); + return 0; + } + + if (debug) + VG_(dmsg)("di_notify_dsc-2: " + "noting details in DebugInfo* at %p\n", di); + + /* Note the details about the mapping. */ + DebugInfoMapping map; + map.avma = header; + map.size = len; + map.foff = 0; + map.rx = True; + map.rw = False; + map.ro = False; + VG_(addToXA)(di->fsm.maps, &map); + + /* Update flags about what kind of mappings we've already seen. */ + di->fsm.have_rx_map |= True; + + vg_assert(!di->have_dinfo); + + if (debug) + VG_(dmsg)("di_notify_dsc-3: " + "achieved accept state for %s\n", filename); + return di_notify_ACHIEVE_ACCEPT_STATE ( di ); +} +#endif /*------------------------------------------------------------*/ /*--- ---*/ @@ -1884,7 +1975,7 @@ void VG_(di_discard_ALL_debuginfo)( void ) DebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi ) { Word i; - vg_assert(lo <= hi); + vg_assert(lo <= hi); /* Optimization: Try to use the last matched rx mapping first */ if ( di->last_rx_map @@ -1951,7 +2042,7 @@ Bool VG_(next_IIPC)(InlIPCursor *iipc) di = iipc->di; for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) { - if (di->inltab[i].addr_lo <= iipc->eip + if (di->inltab[i].addr_lo <= iipc->eip && iipc->eip < di->inltab[i].addr_hi && di->inltab[i].level < iipc->curlevel && (!hinl || hinl->level < di->inltab[i].level)) { @@ -1959,7 +2050,7 @@ Bool VG_(next_IIPC)(InlIPCursor *iipc) hinl_pos = i; } } - + iipc->cur_inltab = iipc->next_inltab; iipc->next_inltab = hinl_pos; if (iipc->next_inltab < 0) @@ -1981,12 +2072,12 @@ static void search_all_loctabs ( DiEpoch ep, Addr ptr, (note that inltab might have duplicates addr_lo). */ static Word inltab_insert_pos (DebugInfo *di, Addr eip) { - Word mid, - lo = 0, + Word mid, + lo = 0, hi = di->inltab_used-1; while (lo <= hi) { mid = (lo + hi) / 2; - if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } + if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; } lo = mid; break; } @@ -2032,7 +2123,7 @@ InlIPCursor* VG_(new_IIPC)(DiEpoch ep, Addr eip) if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) return NULL; } - + if (i < 0) return NULL; // No entry containing eip. @@ -2043,7 +2134,7 @@ InlIPCursor* VG_(new_IIPC)(DiEpoch ep, Addr eip) ret->di = di; ret->inltab_hipos = i; for (i = ret->inltab_hipos - 1; i >= 0; i--) { - + if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) break; /* Similar stop backward scan logic as above. */ } @@ -2100,27 +2191,27 @@ static void search_all_symtabs ( DiEpoch ep, Addr ptr, } else { inRange = (di->data_present && di->data_size > 0 - && di->data_avma <= ptr + && di->data_avma <= ptr && ptr < di->data_avma + di->data_size) || (di->sdata_present && di->sdata_size > 0 - && di->sdata_avma <= ptr + && di->sdata_avma <= ptr && ptr < di->sdata_avma + di->sdata_size) || (di->bss_present && di->bss_size > 0 - && di->bss_avma <= ptr + && di->bss_avma <= ptr && ptr < di->bss_avma + di->bss_size) || (di->sbss_present && di->sbss_size > 0 - && di->sbss_avma <= ptr + && di->sbss_avma <= ptr && ptr < di->sbss_avma + di->sbss_size) || (di->rodata_present && di->rodata_size > 0 - && di->rodata_avma <= ptr + && di->rodata_avma <= ptr && ptr < di->rodata_avma + di->rodata_size); } @@ -2151,7 +2242,7 @@ static void search_all_loctabs ( DiEpoch ep, Addr ptr, continue; if (di->text_present && di->text_size > 0 - && di->text_avma <= ptr + && di->text_avma <= ptr && ptr < di->text_avma + di->text_size) { lno = ML_(search_one_loctab) ( di, ptr ); if (lno == -1) goto not_found; @@ -2176,7 +2267,7 @@ typedef Addr sym_avma; // Fields below here are not part of the key. const HChar* sym_name; - PtrdiffT offset : (sizeof(PtrdiffT)*8)-1; + PtrdiffT offset : (sizeof(PtrdiffT)*8)-1; Bool isText : 1; } Sym_Name_CacheEnt; @@ -2212,10 +2303,10 @@ static void sym_name_cache__invalidate ( void ) { -- caller must choose one kind or the other. NOTE: See IMPORTANT COMMENT above about persistence and ownership - in pub_tool_debuginfo.h + in pub_tool_debuginfo.h get_sym_name and the fact it calls the demangler is the main reason for non persistence of the information returned by m_debuginfo.c - functions : the string returned in *BUF is persistent as long as + functions : the string returned in *BUF is persistent as long as (1) the DebugInfo it belongs to is not discarded (2) the demangler is not invoked again Also, the returned string is owned by "somebody else". Callers must @@ -2266,7 +2357,7 @@ Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, se->sym_name, buf ); /* Do the below-main hack */ - // To reduce the endless nuisance of multiple different names + // To reduce the endless nuisance of multiple different names // for "the frame below main()" screwing up the testsuite, change all // known incarnations of said into a single name, "(below main)", if // --show-below-main=yes. @@ -2311,7 +2402,7 @@ Addr VG_(get_tocptr) ( DiEpoch ep, Addr guest_code_addr ) search_all_symtabs ( ep, guest_code_addr, &si, &sno, True/*consider text symbols only*/ ); - if (si == NULL) + if (si == NULL) return 0; else return GET_TOCPTR_AVMA(si->symtab[sno].avmas); @@ -2329,7 +2420,7 @@ Bool VG_(get_fnname) ( DiEpoch ep, Addr a, const HChar** buf ) return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, ep, a, buf, - /*match_anywhere_in_fun*/True, + /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text sym*/True, /*offsetP*/NULL ); @@ -2370,7 +2461,7 @@ Bool VG_(get_fnname_w_offset) ( DiEpoch ep, Addr a, const HChar** buf ) return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, ep, a, buf, - /*match_anywhere_in_fun*/True, + /*match_anywhere_in_fun*/True, /*show offset?*/True, /*text sym*/True, /*offsetP*/NULL ); @@ -2414,7 +2505,7 @@ Bool VG_(get_fnname_if_entry) ( DiEpoch ep, Addr a, const HChar** buf ) res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, ep, a, &tmp, - /*match_anywhere_in_fun*/False, + /*match_anywhere_in_fun*/False, /*show offset?*/False, /*text sym*/True, /*offsetP*/NULL ); @@ -2433,7 +2524,7 @@ Bool VG_(get_fnname_raw) ( DiEpoch ep, Addr a, const HChar** buf ) return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, ep, a, buf, - /*match_anywhere_in_fun*/True, + /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text sym*/True, /*offsetP*/NULL ); @@ -2461,7 +2552,7 @@ Bool VG_(get_fnname_no_cxx_demangle) ( DiEpoch ep, Addr a, const HChar** buf, return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, /*below-main-renaming*/True, ep, a, buf, - /*match_anywhere_in_fun*/True, + /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text sym*/True, /*offsetP*/NULL ); @@ -2476,7 +2567,7 @@ Bool VG_(get_fnname_no_cxx_demangle) ( DiEpoch ep, Addr a, const HChar** buf, } } -/* mips-linux only: find the offset of current address. This is needed for +/* mips-linux only: find the offset of current address. This is needed for stack unwinding for MIPS. */ Bool VG_(get_inst_offset_in_function)( DiEpoch ep, Addr a, @@ -2486,7 +2577,7 @@ Bool VG_(get_inst_offset_in_function)( DiEpoch ep, Addr a, return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, ep, a, &fnname, - /*match_anywhere_in_sym*/True, + /*match_anywhere_in_sym*/True, /*show offset?*/False, /*text sym*/True, offset ); @@ -2549,7 +2640,7 @@ Bool VG_(get_datasym_and_offset)( DiEpoch ep, Addr data_addr, return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, ep, data_addr, dname, - /*match_anywhere_in_sym*/True, + /*match_anywhere_in_sym*/True, /*show offset?*/False, /*text sym*/False, offset ); @@ -2557,7 +2648,7 @@ Bool VG_(get_datasym_and_offset)( DiEpoch ep, Addr data_addr, /* Map a code address to the name of a shared object file or the executable. Returns False if no idea; otherwise True. - Note: the string returned in *BUF is persistent as long as + Note: the string returned in *BUF is persistent as long as (1) the DebugInfo it belongs to is not discarded (2) the segment containing the address is not merged with another segment */ @@ -2574,7 +2665,7 @@ Bool VG_(get_objname) ( DiEpoch ep, Addr a, const HChar** objname ) continue; if (di->text_present && di->text_size > 0 - && di->text_avma <= a + && di->text_avma <= a && a < di->text_avma + di->text_size) { *objname = di->fsm.filename; return True; @@ -2610,7 +2701,7 @@ DebugInfo* VG_(find_DebugInfo) ( DiEpoch ep, Addr a ) continue; if (di->text_present && di->text_size > 0 - && di->text_avma <= a + && di->text_avma <= a && a < di->text_avma + di->text_size) { if (0 == (n_search & 0xF)) move_DebugInfo_one_step_forward( di ); @@ -2658,7 +2749,7 @@ Bool VG_(get_filename)( DiEpoch ep, Addr a, const HChar** filename ) UInt fndn_ix; search_all_loctabs ( ep, a, &si, &locno ); - if (si == NULL) + if (si == NULL) return False; fndn_ix = ML_(fndn_ix) (si, locno); *filename = ML_(fndn_ix2filename) (si, fndn_ix); @@ -2671,7 +2762,7 @@ Bool VG_(get_linenum)( DiEpoch ep, Addr a, UInt* lineno ) DebugInfo* si; Word locno; search_all_loctabs ( ep, a, &si, &locno ); - if (si == NULL) + if (si == NULL) return False; *lineno = si->loctab[locno].lineno; @@ -2753,7 +2844,7 @@ Bool VG_(lookup_symbol_SLOW)(DiEpoch ep, vg_assert(sec_names[0]); while (*sec_names) { if (0==VG_(strcmp)(name, *sec_names) - && (require_pToc + && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { *avmas = si->symtab[i].avmas; return True; @@ -2773,8 +2864,8 @@ Bool VG_(lookup_symbol_SLOW)(DiEpoch ep, /* Copy str into *buf starting at n, ensuring that buf is zero-terminated. Return the index of the terminating null character. */ -static SizeT -putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) +static SizeT +putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) { SizeT slen = VG_(strlen)(str); SizeT need = n + slen + 1; @@ -2791,21 +2882,21 @@ putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) } /* Same as putStr, but escaping chars for XML output. */ -static SizeT +static SizeT putStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) { HChar alt[2]; for (; *str != 0; str++) { switch (*str) { - case '&': - n = putStr( n, buf, bufsiz, "&"); + case '&': + n = putStr( n, buf, bufsiz, "&"); break; - case '<': - n = putStr( n, buf, bufsiz, "<"); + case '<': + n = putStr( n, buf, bufsiz, "<"); break; - case '>': - n = putStr( n, buf, bufsiz, ">"); + case '>': + n = putStr( n, buf, bufsiz, ">"); break; default: alt[0] = *str; @@ -2826,7 +2917,7 @@ const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc) # define APPEND_ESC(_str) \ n = putStrEsc(n, &buf, &bufsiz, _str) - UInt lineno; + UInt lineno; HChar ibuf[50]; // large enough SizeT n = 0; @@ -2979,7 +3070,7 @@ const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc) Int i; dirname = buf_dirname; // Remove leading prefixes from the dirname. - // If user supplied --fullpath-after=foo, this will remove + // If user supplied --fullpath-after=foo, this will remove // a leading string which matches '.*foo' (not greedy). for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) { const HChar* prefix = @@ -3059,7 +3150,7 @@ typedef caller must set it to True before calling. */ __attribute__((noinline)) static -UWord evalCfiExpr ( const XArray* exprs, Int ix, +UWord evalCfiExpr ( const XArray* exprs, Int ix, const CfiExprEvalContext* eec, Bool* ok ) { UWord w, wL, wR; @@ -3146,7 +3237,7 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, } /* let's hope it doesn't trap! */ return ML_(read_UWord)((void *)a); - default: + default: goto unhandled; } /*NOTREACHED*/ @@ -3161,7 +3252,7 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, /* Search all the DebugInfos in the entire system, to find the DiCfSI_m - that pertains to 'ip'. + that pertains to 'ip'. If found, set *diP to the DebugInfo in which it resides, and *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool. @@ -3172,7 +3263,7 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, DebugInfos that are valid for the current epoch. */ __attribute__((noinline)) -static void find_DiCfSI ( /*OUT*/DebugInfo** diP, +static void find_DiCfSI ( /*OUT*/DebugInfo** diP, /*OUT*/DiCfSI_m** cfsi_mP, Addr ip ) { @@ -3254,7 +3345,7 @@ static void find_DiCfSI ( /*OUT*/DebugInfo** diP, if (0 && ((n_search & 0x7FFFF) == 0)) VG_(printf)("find_DiCfSI: %lu searches, " - "%lu DebugInfos looked at\n", + "%lu DebugInfos looked at\n", n_search, n_steps); } @@ -3346,23 +3437,23 @@ static Addr compute_cfa ( const D3UnwindRegs* uregs, cfa = 0; switch (cfsi_m->cfa_how) { # if defined(VGA_x86) || defined(VGA_amd64) - case CFIC_IA_SPREL: + case CFIC_IA_SPREL: cfa = cfsi_m->cfa_off + uregs->xsp; break; - case CFIC_IA_BPREL: + case CFIC_IA_BPREL: cfa = cfsi_m->cfa_off + uregs->xbp; break; # elif defined(VGA_arm) - case CFIC_ARM_R13REL: + case CFIC_ARM_R13REL: cfa = cfsi_m->cfa_off + uregs->r13; break; - case CFIC_ARM_R12REL: + case CFIC_ARM_R12REL: cfa = cfsi_m->cfa_off + uregs->r12; break; - case CFIC_ARM_R11REL: + case CFIC_ARM_R11REL: cfa = cfsi_m->cfa_off + uregs->r11; break; - case CFIC_ARM_R7REL: + case CFIC_ARM_R7REL: cfa = cfsi_m->cfa_off + uregs->r7; break; # elif defined(VGA_s390x) @@ -3395,10 +3486,10 @@ static Addr compute_cfa ( const D3UnwindRegs* uregs, break; # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) # elif defined(VGP_arm64_linux) - case CFIC_ARM64_SPREL: + case CFIC_ARM64_SPREL: cfa = cfsi_m->cfa_off + uregs->sp; break; - case CFIC_ARM64_X29REL: + case CFIC_ARM64_X29REL: cfa = cfsi_m->cfa_off + uregs->x29; break; # elif defined(VGP_arm64_freebsd) @@ -3431,7 +3522,7 @@ static Addr compute_cfa ( const D3UnwindRegs* uregs, cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok ); if (!ok) return 0; break; - default: + default: vg_assert(0); } return cfa; @@ -3569,9 +3660,7 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips) ipHere = uregsHere->pc; # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) -# elif defined(VGP_arm64_linux) - ipHere = uregsHere->pc; -# elif defined(VGP_arm64_freebsd) +# elif defined(VGA_arm64) ipHere = uregsHere->pc; # elif defined(VGP_riscv64_linux) ipHere = uregsHere->pc; @@ -3587,7 +3676,7 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, cfsi_m = ce->cfsi_m; if (0) { - VG_(printf)("found cfsi_m (but printing fake base/len): "); + VG_(printf)("found cfsi_m (but printing fake base/len): "); ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m); } @@ -3848,11 +3937,11 @@ Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, I don't know what happens when the compiler constructs an outgoing CALL. %esp could move if outgoing parameters are PUSHed, and this affects traceback for errors during the PUSHes. */ - + spHere = *spP; *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); - *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 + *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 + fpo->cdwParams); *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); return True; @@ -3950,7 +4039,7 @@ static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, VG_(printf)("\n"); } - if (res.kind == GXR_Addr + if (res.kind == GXR_Addr && res.word <= data_addr && data_addr < res.word + var_szB) { *offset = data_addr - res.word; @@ -3975,7 +4064,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, PtrdiffT var_offset, PtrdiffT residual_offset, const XArray* /*HChar*/ described, - Int frameNo, + Int frameNo, ThreadId tid ) { Bool have_descr, have_srcloc; @@ -4044,7 +4133,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, p2XA( dn2, "in frame #%d of thread %u", frameNo, tid ); } - } + } else if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { /* no description: @@ -4065,7 +4154,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, TXTR( dn2 ); // FIXME: also do p2XA( dn2, - " %pS %d ", + " %pS %d ", fileName, var->lineNo ); XAGR( dn2 ); } else { @@ -4102,7 +4191,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, p2XA( dn2, "in frame #%d of thread %u", frameNo, tid ); } - } + } else if ( frameNo >= 0 && have_srcloc && have_descr ) { /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, @@ -4152,7 +4241,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, "Location 0x%lx is %ld byte%s inside global var \"%s\"", data_addr, var_offset, vo_plural, var->name ); } - } + } else if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { /* no description: @@ -4210,7 +4299,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, p2XA( dn2, "a global variable"); } - } + } else if ( frameNo >= -1 && have_srcloc && have_descr ) { /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, @@ -4243,7 +4332,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, fileName, var->lineNo); } } - else + else vg_assert(0); /* Zero terminate both strings */ @@ -4264,7 +4353,7 @@ static void format_message ( /*MOD*/XArray* /* of HChar */ dn1, ends of DNAME{1,2}, which are XArray*s of HChar, that have been initialised by the caller, zero terminate both, and return True. If it's not a local variable in said frame, return False. */ -static +static Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, /*MOD*/XArray* /* of HChar */ dname2, DiEpoch ep, @@ -4295,7 +4384,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, if (di->text_avma <= ip && ip < di->text_avma + di->text_size) break; } - + /* Didn't find it. Strange -- means ip is a code address outside of any mapped text segment. Unlikely but not impossible -- app could be generating code to run. */ @@ -4304,7 +4393,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, if (0 && ((n_search & 0x1) == 0)) VG_(printf)("consider_vars_in_frame: %u searches, " - "%u DebugInfos looked at\n", + "%u DebugInfos looked at\n", n_search, n_steps); /* Start of performance-enhancing hack: once every ??? (chosen hackily after profiling) successful searches, move the found @@ -4334,7 +4423,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, XArray* vars; Word j; DiAddrRange* arange; - OSet* this_scope + OSet* this_scope = *(OSet**)VG_(indexXA)( di->varinfo, i ); if (debug) VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); @@ -4343,7 +4432,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, /* Find the set of variables in this scope that bracket the program counter. */ arange = VG_(OSetGen_LookupWithCmp)( - this_scope, &ip, + this_scope, &ip, ML_(cmp_for_DiAddrRange_range) ); if (!arange) @@ -4375,7 +4464,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, data_addr, di )) { PtrdiffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, - di->admin_tyents, + di->admin_tyents, var->typeR, offset ); format_message( dname1, dname2, data_addr, di, var, offset, residual_offset, @@ -4402,7 +4491,7 @@ Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, using VG_(strlen) on the contents, rather than VG_(sizeXA) on the XArray itself. */ -Bool VG_(get_data_description)( +Bool VG_(get_data_description)( /*MOD*/ XArray* /* of HChar */ dname1, /*MOD*/ XArray* /* of HChar */ dname2, DiEpoch ep, Addr data_addr @@ -4452,7 +4541,7 @@ Bool VG_(get_data_description)( vg_assert(gs_size == 1); /* Fish out the global scope and check it is as expected. */ zero = 0; - global_arange + global_arange = VG_(OSetGen_Lookup)( global_scope, &zero ); /* The global range from (Addr)0 to ~(Addr)0 must exist */ vg_assert(global_arange); @@ -4475,8 +4564,8 @@ Bool VG_(get_data_description)( This means, if the evaluation of the location expression/list requires a register, we have to let it fail. */ - if (data_address_is_in_var( &offset, di->admin_tyents, var, - NULL/* RegSummary* */, + if (data_address_is_in_var( &offset, di->admin_tyents, var, + NULL/* RegSummary* */, data_addr, di )) { PtrdiffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, @@ -4526,7 +4615,7 @@ Bool VG_(get_data_description)( for (j = 0; j < n_frames; j++) { if (consider_vars_in_frame( dname1, dname2, ep, data_addr, - ips[j], + ips[j], sps[j], fps[j], tid, j )) { zterm_XA( dname1 ); zterm_XA( dname2 ); @@ -4553,7 +4642,7 @@ Bool VG_(get_data_description)( if (j > 0 /* this is a non-innermost frame */ && consider_vars_in_frame( dname1, dname2, ep, data_addr, - ips[j] + 1, + ips[j] + 1, sps[j], fps[j], tid, j )) { zterm_XA( dname1 ); zterm_XA( dname2 ); @@ -4581,7 +4670,7 @@ Bool VG_(get_data_description)( it. If 'arrays_only' is True, also ignore it unless it has an array type. */ -static +static void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, const XArray* /* TyEnt */ tyents, Addr ip, const DebugInfo* di, const DiVariable* var, @@ -4739,7 +4828,7 @@ VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) if (di->text_avma <= ip && ip < di->text_avma + di->text_size) break; } - + /* Didn't find it. Strange -- means ip is a code address outside of any mapped text segment. Unlikely but not impossible -- app could be generating code to run. */ @@ -4748,7 +4837,7 @@ VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) if (0 && ((n_search & 0x1) == 0)) VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " - "%u DebugInfos looked at\n", + "%u DebugInfos looked at\n", n_search, n_steps); /* Start of performance-enhancing hack: once every ??? (chosen hackily after profiling) successful searches, move the found @@ -4775,7 +4864,7 @@ VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) XArray* vars; Word j; DiAddrRange* arange; - OSet* this_scope + OSet* this_scope = *(OSet**)VG_(indexXA)( di->varinfo, i ); if (debug) VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); @@ -4784,7 +4873,7 @@ VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) /* Find the set of variables in this scope that bracket the program counter. */ arange = VG_(OSetGen_LookupWithCmp)( - this_scope, &ip, + this_scope, &ip, ML_(cmp_for_DiAddrRange_range) ); if (!arange) @@ -4808,7 +4897,7 @@ VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) for (j = 0; j < VG_(sizeXA)( vars ); j++) { DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); if (debug) - VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", + VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", var->name,arange->aMin,arange->aMax,ip); analyse_deps( res, di->admin_tyents, ip, di, var, arrays_only ); @@ -4968,32 +5057,32 @@ const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) { - return di->text_present ? di->text_avma : 0; + return di->text_present ? di->text_avma : 0; } SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) { - return di->text_present ? di->text_size : 0; + return di->text_present ? di->text_size : 0; } Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di) { - return di->bss_present ? di->bss_avma : 0; + return di->bss_present ? di->bss_avma : 0; } SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di) { - return di->bss_present ? di->bss_size : 0; + return di->bss_present ? di->bss_size : 0; } Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) { - return di->plt_present ? di->plt_avma : 0; + return di->plt_present ? di->plt_avma : 0; } SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) { - return di->plt_present ? di->plt_size : 0; + return di->plt_present ? di->plt_size : 0; } Addr VG_(DebugInfo_get_pltsec_avma)(const DebugInfo* di) @@ -5008,22 +5097,22 @@ SizeT VG_(DebugInfo_get_pltsec_size)(const DebugInfo* di) Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) { - return di->gotplt_present ? di->gotplt_avma : 0; + return di->gotplt_present ? di->gotplt_avma : 0; } SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) { - return di->gotplt_present ? di->gotplt_size : 0; + return di->gotplt_present ? di->gotplt_size : 0; } Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) { - return di->got_present ? di->got_avma : 0; + return di->got_present ? di->got_avma : 0; } SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) { - return di->got_present ? di->got_size : 0; + return di->got_present ? di->got_size : 0; } const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) @@ -5046,7 +5135,7 @@ Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) return si->symtab_used; } -void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, +void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, Int idx, /*OUT*/SymAVMAs* avmas, /*OUT*/UInt* size, @@ -5218,12 +5307,14 @@ void VG_(load_all_debuginfo) (void) SizeT VG_(data_size)(void) { - HChar resolved[1000]; - VG_(realpath)( VG_(args_the_exename), resolved); - - for (DebugInfo* di = debugInfo_list; di; di = di->next) { - if (di->data_size && VG_(strcmp)(di->soname, "NONE") == 0 && VG_(strcmp)(resolved, di->fsm.filename) == 0) { - return VG_PGROUNDUP(di->data_size); + HChar resolved[VKI_PATH_MAX]; + if (VG_(realpath)( VG_(args_the_exename), resolved)) { + for (DebugInfo* di = debugInfo_list; di; di = di->next) { + if (di->data_size + && VG_(strcmp)(di->soname, "NONE") == 0 + && VG_(strcmp)(resolved, di->fsm.filename) == 0) { + return VG_PGROUNDUP(di->data_size); + } } } return 0U; diff --git a/coregrind/m_debuginfo/image.c b/coregrind/m_debuginfo/image.c index 21deabb356..7f9cfff64f 100644 --- a/coregrind/m_debuginfo/image.c +++ b/coregrind/m_debuginfo/image.c @@ -94,7 +94,12 @@ typedef // The rest of these fields are only valid when using remote files // (that is, using a debuginfo server; hence when is_local==False) // Session ID allocated to us by the server. Cannot be zero. - ULong session_id; + // The memory union member is used by Darwin when reading the DiImage + // from memory when there is no local file and fd is -1. + union { + ULong session_id; + Addr memory; + }; } Source; @@ -139,8 +144,8 @@ static Bool is_sane_CEnt ( const HChar* who, const DiImage* img, UInt i ) if (!(ce->used <= ce->size)) goto fail; if (ce->fromC) { // ce->size can be anything, but ce->used must be either the - // same or zero, in the case that it hasn't been set yet. - // Similarly, ce->off must either be above the real_size + // same or zero, in the case that it hasn't been set yet. + // Similarly, ce->off must either be above the real_size // threshold, or zero if it hasn't been set yet. if (!(ce->off >= img->real_size || ce->off == 0)) goto fail; if (!(ce->off + ce->used <= img->size)) goto fail; @@ -432,7 +437,7 @@ static Bool parse_Frame_asciiz ( const Frame* fr, const HChar* tag, static Bool parse_Frame_le64_le64_le64_bytes ( const Frame* fr, const HChar* tag, /*OUT*/ULong* n1, /*OUT*/ULong* n2, /*OUT*/ULong* n3, - /*OUT*/UChar** data, /*OUT*/ULong* n_data + /*OUT*/UChar** data, /*OUT*/ULong* n_data ) { vg_assert(VG_(strlen)(tag) == 4); @@ -581,35 +586,38 @@ static void set_CEnt ( const DiImage* img, UInt entNo, DiOffT off ) UInt delay = now - t_last; t_last = now; nread += len; - VG_(printf)("XXXXXXXX (tot %'llu) read %'lu offset %'llu delay %'u\n", + VG_(printf)("XXXXXXXX (tot %'llu) read %'lu offset %'llu delay %'u\n", nread, len, off, delay); } if (img->source.is_local) { // Simple: just read it - - // PJF not quite so simple - see - // https://bugs.kde.org/show_bug.cgi?id=480405 - // if img->source.fd was opened with O_DIRECT the memory needs - // to be aligned and also the length - // that's a lot of hassle just to take a quick peek to see if - // is an ELF binary so just twiddle the flag before and after - // peeking. - // This doesn't seem to be a problem on FreeBSD. I haven't tested - // on macOS or Solaris, hence the conditional compilation + if (img->source.fd == -1) { + VG_(memcpy)(&ce->data[0], ((const char *)img->source.memory) + off, len); + } else { + // PJF not quite so simple - see + // https://bugs.kde.org/show_bug.cgi?id=480405 + // if img->source.fd was opened with O_DIRECT the memory needs + // to be aligned and also the length + // that's a lot of hassle just to take a quick peek to see if + // is an ELF binary so just twiddle the flag before and after + // peeking. + // This doesn't seem to be a problem on FreeBSD. I haven't tested + // on macOS or Solaris, hence the conditional compilation #if defined(VKI_O_DIRECT) - Int flags = VG_(fcntl)(img->source.fd, VKI_F_GETFL, 0); - if (flags & VKI_O_DIRECT) { - VG_(fcntl)(img->source.fd, VKI_F_SETFL, flags & ~VKI_O_DIRECT); - } + Int flags = VG_(fcntl)(img->source.fd, VKI_F_GETFL, 0); + if (flags & VKI_O_DIRECT) { + VG_(fcntl)(img->source.fd, VKI_F_SETFL, flags & ~VKI_O_DIRECT); + } #endif - SysRes sr = VG_(pread)(img->source.fd, &ce->data[0], (Int)len, off); + SysRes sr = VG_(pread)(img->source.fd, &ce->data[0], (Int)len, off); #if defined(VKI_O_DIRECT) - if (flags & VKI_O_DIRECT) { - VG_(fcntl)(img->source.fd, VKI_F_SETFL, flags); - } + if (flags & VKI_O_DIRECT) { + VG_(fcntl)(img->source.fd, VKI_F_SETFL, flags); + } #endif - vg_assert(!sr_isError(sr)); + vg_assert(!sr_isError(sr)); + } } else { // Not so simple: poke the server vg_assert(img->source.session_id > 0); @@ -671,7 +679,7 @@ static void set_CEnt ( const DiImage* img, UInt entNo, DiOffT off ) end_of_else_clause: {} } - + ce->off = off; ce->used = len; ce->fromC = False; @@ -888,7 +896,7 @@ DiImage* ML_(img_from_local_file)(const HChar* fullpath) || /* size is unrepresentable as a SizeT */ size != (DiOffT)(SizeT)(size)) { VG_(close)(sr_Res(fd)); - return NULL; + return NULL; } DiImage* img = ML_(dinfo_zalloc)("di.image.ML_iflf.1", sizeof(DiImage)); @@ -958,6 +966,39 @@ DiImage* ML_(img_from_fd)(Int fd, const HChar* fullpath) return img; } +/* Create an image from a place in memory, this is to support certain use cases (DSC on macOS) + where images are already loaded in memory without changing every usage of DiImage. */ +DiImage* ML_(img_from_memory)(Addr a, SizeT size, const HChar* fullpath) +{ + if (size == 0 || size == DiOffT_INVALID + || /* size is unrepresentable as a SizeT */ + size != (DiOffT)(SizeT)(size)) { + return NULL; + } + + DiImage* img = ML_(dinfo_zalloc)("di.image.ML_iflf.1", sizeof(DiImage)); + img->source.is_local = True; + img->source.fd = -1; + img->source.memory = a; + img->size = size; + img->real_size = size; + img->ces_used = 0; + img->source.name = ML_(dinfo_strdup)("di.image.ML_iflf.2", fullpath); + img->cslc = NULL; + img->cslc_size = 0; + img->cslc_used = 0; + + /* Force the zeroth entry to be the first chunk of the file. + That's likely to be the first part that's requested anyway, and + loading it at this point forcing img->cent[0] to always be + non-empty, thereby saving us an is-it-empty check on the fast + path in get(). */ + UInt entNo = alloc_CEnt(img, CACHE_ENTRY_SIZE, False/*!fromC*/); + vg_assert(entNo == 0); + set_CEnt(img, 0, 0); + + return img; +} /* Create an image from a file on a remote debuginfo server. This is @@ -984,7 +1025,7 @@ DiImage* ML_(img_from_di_server)(const HChar* filename, if (!set_blocking(sd)) return NULL; Int one = 1; - Int sr = VG_(setsockopt)(sd, VKI_IPPROTO_TCP, VKI_TCP_NODELAY, + Int sr = VG_(setsockopt)(sd, VKI_IPPROTO_TCP, VKI_TCP_NODELAY, &one, sizeof(one)); vg_assert(sr == 0); @@ -1116,9 +1157,11 @@ void ML_(img_done)(DiImage* img) { vg_assert(img != NULL); if (img->source.is_local) { + if (img->source.fd != -1) { /* Close the file; nothing else to do. */ vg_assert(img->source.session_id == 0); VG_(close)(img->source.fd); + } } else { /* Close the socket. The server can detect this and will scrub the connection when it happens, so there's no need to tell it diff --git a/coregrind/m_debuginfo/priv_image.h b/coregrind/m_debuginfo/priv_image.h index 90de98dfc5..56dfbb85d3 100644 --- a/coregrind/m_debuginfo/priv_image.h +++ b/coregrind/m_debuginfo/priv_image.h @@ -61,6 +61,8 @@ DiImage* ML_(img_from_local_file)(const HChar* fullpath); DiImage* ML_(img_from_fd)(Int fd, const HChar* fullpath); +DiImage* ML_(img_from_memory)(Addr a, SizeT len, const HChar* fullpath); + /* Create an image by connecting to a Valgrind debuginfo server (auxprogs/valgrind-di-server.c). |filename| contains the object name to ask for; it must be a plain filename, not absolute, not a diff --git a/coregrind/m_debuginfo/priv_readmacho.h b/coregrind/m_debuginfo/priv_readmacho.h index 5ff5d048ce..c945d9b185 100644 --- a/coregrind/m_debuginfo/priv_readmacho.h +++ b/coregrind/m_debuginfo/priv_readmacho.h @@ -37,6 +37,9 @@ it. Also count the number of RW segements. */ extern Bool ML_(check_macho_and_get_rw_loads)( Int fd, Int* rw_loads ); +/* Same as above, but reads from memory instead of a file descriptor. */ +extern Bool ML_(check_macho_and_get_rw_loads_from_memory)( const void* buf, SizeT size, Int* rw_loads ); + /* The central function for reading Mach-O debug info. For the object/exe specified by the DebugInfo, find Mach-O sections, then read the symbols, line number info, file name info, CFA (stack-unwind diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index fad960aa02..56e30ffae3 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -1103,6 +1103,12 @@ struct _DebugInfo { This helps performance a lot during ML_(addLineInfo) etc., which can easily be invoked hundreds of thousands of times. */ DebugInfoMapping* last_rx_map; + +#if DARWIN_VERS >= DARWIN_11_00 + /* Indicate that this debug info was loaded from memory (i.e. DSC) + instead than from a file. This means that some data might be missing (e.g. rw data). */ + Bool from_memory; +#endif }; /* --------------------- functions --------------------- */ diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 374237498e..b67e41b7cf 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -2977,6 +2977,14 @@ static void parse_var_DIE ( if (level == 0) setup_cu_svma(cc, have_lo, ip_lo, td3); +#if defined(VGO_darwin) + // FIXME PJF Darwin LLVM generates this (non-standard?) combination + // it only seems to affect DRD + if (have_lo && have_range && !have_hi1) { + have_lo = False; + } +#endif + /* Do we have something that looks sane? */ if (have_lo && have_hi1 && (!have_range)) { if (ip_lo < ip_hi1) diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c index 48ef5aaf5f..f97866ffb5 100644 --- a/coregrind/m_debuginfo/readmacho.c +++ b/coregrind/m_debuginfo/readmacho.c @@ -37,6 +37,7 @@ #include "pub_core_libcfile.h" #include "pub_core_libcproc.h" #include "pub_core_aspacemgr.h" /* for mmaping debuginfo files */ +#include "pub_core_mach.h" /* VG_(dyld_cache_get_slide) */ #include "pub_core_machine.h" /* VG_ELF_CLASS */ #include "pub_core_options.h" #include "pub_core_oset.h" @@ -83,6 +84,41 @@ /*--- ---*/ /*------------------------------------------------------------*/ +static Int count_rw_loads(const struct load_command* macho_load_commands, unsigned int ncmds) +{ + Int rw_loads = 0; + const struct load_command* lc = (const struct load_command*)macho_load_commands; + for (unsigned int i = 0U; i < ncmds; ++i) { + if (lc->cmd == LC_SEGMENT_CMD) { + const struct SEGMENT_COMMAND* sc = (const struct SEGMENT_COMMAND*)lc; + if (sc->initprot == 3 && sc->filesize +#if DARWIN_VERS >= DARWIN_10_15 +// FIXME: somehow __DATA_CONST appears as rw- in most binaries in macOS 10.15 +// so we ignore it otherwise some binaries don't get symbols + && VG_(strcmp)(sc->segname, "__DATA_CONST") != 0 +#endif + ) { + rw_loads += 1; + } + } + const char* tmp = (const char*)lc + lc->cmdsize; + lc = (const struct load_command*)tmp; + } + return rw_loads; +} + +static Bool check_fat_macho_and_get_rw_loads(const void* macho_header, Int* rw_loads) +{ + const struct fat_header* fh_be = (const struct fat_header*)macho_header; + vg_assert(fh_be); + if (VG_(ntohl)(fh_be->magic) == FAT_MAGIC) { + // @todo PJF not yet handled, previous behaviour was to assume that the count is 1 + *rw_loads = 1; + return True; + } + return False; +} + /* A DiSlice is used to handle the thin/fat distinction for MachO images. (1) the entire mapped-in ("primary") image, fat headers, kitchen sink, whatnot: the entire file. This is the DiImage* that is the backing @@ -93,20 +129,11 @@ memory that falls entirely inside the primary image. */ +STATIC_ASSERT(sizeof(struct fat_header) <= sizeof(struct MACH_HEADER)); + Bool ML_(check_macho_and_get_rw_loads)( Int fd, Int* rw_loads ) { - /* (JRS: the Mach-O headers might not be in this mapped data, - because we only mapped a page for this initial check, - or at least not very much, and what's at the start of the file - is in general a so-called fat header. The Mach-O object we're - interested in could be arbitrarily far along the image, and so - we can't assume its header will fall within this page.) */ - - /* But we can say that either it's a fat object, in which case it - begins with a fat header, or it's unadorned Mach-O, in which - case it starts with a normal header. At least do what checks we - can to establish whether or not we're looking at something - sane. */ + vg_assert(rw_loads); HChar macho_header[sizeof(struct MACH_HEADER)]; SysRes preadres = VG_(pread)( fd, macho_header, sizeof(struct MACH_HEADER), 0 ); @@ -115,43 +142,47 @@ Bool ML_(check_macho_and_get_rw_loads)( Int fd, Int* rw_loads ) return False; } - const struct fat_header* fh_be = (const struct fat_header*)macho_header; - const struct MACH_HEADER* mh = (const struct MACH_HEADER*)macho_header; - - vg_assert(fh_be); - vg_assert(mh); - vg_assert(rw_loads); - STATIC_ASSERT(sizeof(struct fat_header) <= sizeof(struct MACH_HEADER)); - if (VG_(ntohl)(fh_be->magic) == FAT_MAGIC) { - // @todo PJF not yet handled, previous behaviour was to assume that the count is 1 - *rw_loads = 1; + if (check_fat_macho_and_get_rw_loads(macho_header, rw_loads)) { return True; } - if (mh->magic == MAGIC) { - HChar* macho_load_commands = ML_(dinfo_zalloc)("di.readmacho.macho_load_commands", mh->sizeofcmds); - preadres = VG_(pread)( fd, macho_load_commands, mh->sizeofcmds, sizeof(struct MACH_HEADER) ); - if (sr_isError(preadres) || sr_Res(preadres) < mh->sizeofcmds) { - ML_(dinfo_free)(macho_load_commands); - return False; - } + const struct MACH_HEADER* mh = (const struct MACH_HEADER*)macho_header; + vg_assert(mh); + if (mh->magic != MAGIC) { + return False; + } - const struct load_command* lc = (const struct load_command*)macho_load_commands; - for (unsigned int i = 0U; i < mh->ncmds; ++i) { - if (lc->cmd == LC_SEGMENT_CMD) { - const struct SEGMENT_COMMAND* sc = (const struct SEGMENT_COMMAND*)lc; - if (sc->initprot == 3) { - ++*rw_loads; - } - } - const char* tmp = (const char*)lc + lc->cmdsize; - lc = (const struct load_command*)tmp; - } - ML_(dinfo_free)(macho_load_commands); - return True; + HChar* macho_load_commands = ML_(dinfo_zalloc)("di.readmacho.macho_load_commands", mh->sizeofcmds); + preadres = VG_(pread)( fd, macho_load_commands, mh->sizeofcmds, sizeof(struct MACH_HEADER) ); + if (sr_isError(preadres) || sr_Res(preadres) < mh->sizeofcmds) { + ML_(dinfo_free)(macho_load_commands); + return False; } + *rw_loads = count_rw_loads((const struct load_command*)macho_load_commands, mh->ncmds); + ML_(dinfo_free)(macho_load_commands); + return True; +} - return False; +Bool ML_(check_macho_and_get_rw_loads_from_memory)( const void* buf, SizeT szB, Int* rw_loads ) +{ + vg_assert(buf); + vg_assert(rw_loads); + + if (szB < sizeof(struct fat_header)) { + return False; + } + if (check_fat_macho_and_get_rw_loads(buf, rw_loads)) { + return True; + } + + const struct MACH_HEADER* mh = (const struct MACH_HEADER*)buf; + vg_assert(mh); + if (mh->magic != MAGIC) { + return False; + } + + *rw_loads = count_rw_loads((const struct load_command*)((const HChar*)mh + sizeof(struct MACH_HEADER)), mh->ncmds); + return True; } @@ -165,19 +196,31 @@ static void unmap_image ( /*MOD*/DiSlice* sli ) } } - /* Open the given file, find the thin part if necessary, do some checks, and return a DiSlice containing details of both the thin part and (implicitly, via the contained DiImage*) the fat part. returns DiSlice_INVALID if it fails. If it succeeds, the returned slice is guaranteed to refer to a valid(ish) Mach-O image. */ static DiSlice map_image_aboard ( DebugInfo* di, /* only for err msgs */ - const HChar* filename ) + const HChar* filename, + const DebugInfoMapping* rx_map ) { DiSlice sli = DiSlice_INVALID; /* First off, try to map the thing in. */ - DiImage* mimg = ML_(img_from_local_file)(filename); + DiImage* mimg; + + if (rx_map != NULL) { + // FIXME: basically, we make a slice from the place where the mach_header is until the end of the memory space + // unfortunately, all the data needed for parsing from the DSC is spread across many places in memory + // and there is no way to know for sure the size of the DSC perfectly, so this is the best method at the moment + // and it's _very_ unsafe +#if (DARWIN_VERS >= DARWIN_10_15) + mimg = ML_(img_from_memory)(rx_map->avma, MACH_DSC_END - rx_map->avma, filename); +#endif + } else { + mimg = ML_(img_from_local_file)(filename); + } if (mimg == NULL) { VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n", filename ); @@ -190,7 +233,7 @@ static DiSlice map_image_aboard ( DebugInfo* di, /* only for err msgs */ DiOffT fh_be_ioff = 0; struct fat_header fh_be; struct fat_header fh; - + // Assume initially that we have a thin image, and narrow // the bounds if it turns out to be fat. This stores |mimg| as // |sli.img|, so NULL out |mimg| after this point, for the sake of @@ -231,6 +274,8 @@ static DiSlice map_image_aboard ( DebugInfo* di, /* only for err msgs */ Int cputype = CPU_TYPE_X86; # elif defined(VGA_amd64) Int cputype = CPU_TYPE_X86_64; +# elif defined(VGA_arm64) + Int cputype = CPU_TYPE_ARM64; # else # error "unknown architecture" # endif @@ -319,20 +364,108 @@ static DiSlice map_image_aboard ( DebugInfo* di, /* only for err msgs */ /*--- ---*/ /*------------------------------------------------------------*/ +static +void add_symbol( /*OUT*/XArray* /* DiSym */ syms, + struct _DebugInfo* di, + struct NLIST* nl, Addr sym_addr, + const HChar* prefix, + DiCursor strtab_cur, UInt strtab_sz ) +{ + DiSym disym; + + // "start_according_to_valgrind" + static const HChar* s_a_t_v = NULL; /* do not make non-static */ + + Bool inside_text = di->text_present && sym_addr >= di->text_avma && sym_addr < di->text_avma + di->text_size; + Bool inside_data = di->data_present && sym_addr >= di->data_avma && sym_addr < di->data_avma + di->data_size; + Bool inside_d_data = di->sdata_present && sym_addr >= di->sdata_avma && sym_addr < di->sdata_avma + di->sdata_size; + + if (di->trace_symtab) { + HChar* str = ML_(cur_read_strdup)( + ML_(cur_plus)(strtab_cur, nl->n_un.n_strx), + "di.read_symtab.1"); + VG_(printf)("nlist raw: avma %010lx %s in %s %s\n", + sym_addr, str, + inside_text ? "__TEXT" : inside_data ? "__DATA" : inside_d_data ? "__DATA_DIRTY" : "???", + prefix + ); + ML_(dinfo_free)(str); + } + + /* If no part of the symbol falls within the mapped range, + ignore it. */ + if (!inside_text && !inside_data && !inside_d_data) { + return; + } + + /* skip names which point outside the string table; + following these risks segfaulting Valgrind */ + if (nl->n_un.n_strx < 0 || nl->n_un.n_strx >= strtab_sz) { + return; + } + + HChar* name + = ML_(cur_read_strdup)( ML_(cur_plus)(strtab_cur, nl->n_un.n_strx), + "di.read_symtab.2"); + + /* skip nameless symbols; these appear to be common, but + useless */ + if (*name == 0) { + ML_(dinfo_free)(name); + return; + } + + if (prefix[0]) { + HChar* newname = ML_(dinfo_zalloc)("di.read_symtab.3", + VG_(strlen)(prefix) + VG_(strlen)(name)); + VG_(strcpy)(newname, prefix); + VG_(strcat)(newname, name); + ML_(dinfo_free)(name); + name = newname; + } + + VG_(bzero_inline)(&disym, sizeof(disym)); + disym.avmas.main = sym_addr; + SET_TOCPTR_AVMA(disym, 0); + SET_LOCAL_EP_AVMA(disym, 0); + disym.pri_name = ML_(addStr)(di, name, -1); + disym.sec_names = NULL; + disym.size = // let canonicalize fix it + di->text_avma+di->text_size - sym_addr; + disym.isText = inside_text; + disym.isIFunc = False; + disym.isGlobal = (nl->n_type & N_EXT) != 0; + // Lots of user function names get prepended with an underscore. Eg. the + // function 'f' becomes the symbol '_f'. And the "below main" + // function is called "start". So we skip the leading underscore, and + // if we see 'start' and --show-below-main=no, we rename it as + // "start_according_to_valgrind", which makes it easy to spot later + // and display as "(below main)". + if (disym.pri_name[0] == '_') { + disym.pri_name++; + } + else if (!VG_(clo_show_below_main) && VG_STREQ(disym.pri_name, "start")) { + if (s_a_t_v == NULL) + s_a_t_v = ML_(addStr)(di, "start_according_to_valgrind", -1); + vg_assert(s_a_t_v); + disym.pri_name = s_a_t_v; + } + + vg_assert(disym.pri_name); + VG_(addToXA)( syms, &disym ); + ML_(dinfo_free)(name); +} + /* Read a symbol table (nlist). Add the resulting candidate symbols to 'syms'; the caller will post-process them and hand them off to ML_(addSym) itself. */ static void read_symtab( /*OUT*/XArray* /* DiSym */ syms, - struct _DebugInfo* di, + struct _DebugInfo* di, DiCursor symtab_cur, UInt symtab_count, DiCursor strtab_cur, UInt strtab_sz ) { Int i; - DiSym disym; - - // "start_according_to_valgrind" - static const HChar* s_a_t_v = NULL; /* do not make non-static */ for (i = 0; i < symtab_count; i++) { struct NLIST nl; @@ -349,72 +482,37 @@ void read_symtab( /*OUT*/XArray* /* DiSym */ syms, } else { continue; } - - if (di->trace_symtab) { - HChar* str = ML_(cur_read_strdup)( - ML_(cur_plus)(strtab_cur, nl.n_un.n_strx), - "di.read_symtab.1"); - VG_(printf)("nlist raw: avma %010lx %s\n", sym_addr, str ); - ML_(dinfo_free)(str); - } - - /* If no part of the symbol falls within the mapped range, - ignore it. */ - if (sym_addr <= di->text_avma - || sym_addr >= di->text_avma+di->text_size) { - continue; - } - - /* skip names which point outside the string table; - following these risks segfaulting Valgrind */ - if (nl.n_un.n_strx < 0 || nl.n_un.n_strx >= strtab_sz) { - continue; - } - HChar* name - = ML_(cur_read_strdup)( ML_(cur_plus)(strtab_cur, nl.n_un.n_strx), - "di.read_symtab.2"); + add_symbol(syms, di, &nl, sym_addr, "", strtab_cur, strtab_sz); + } +} - /* skip nameless symbols; these appear to be common, but - useless */ - if (*name == 0) { - ML_(dinfo_free)(name); - continue; - } +// See reason for disabling later in this file +#if 0 +static +void add_indirect_symbols( /*OUT*/XArray* /* DiSym */ syms, + struct _DebugInfo* di, + struct SECTION* section, SizeT entry_size, + DiCursor indir_cur, UInt indir_count, + DiCursor symtab_cur, UInt symtab_count, + DiCursor strtab_cur, UInt strtab_sz ) +{ + for (Int i = 0; i < indir_count; i++) { + Int index; + struct NLIST nl; + ML_(cur_read_get)(&index, + ML_(cur_plus)(indir_cur, i * sizeof(Int)), + sizeof(index)); + ML_(cur_read_get)(&nl, + ML_(cur_plus)(symtab_cur, index * sizeof(struct NLIST)), + sizeof(nl)); - VG_(bzero_inline)(&disym, sizeof(disym)); - disym.avmas.main = sym_addr; - SET_TOCPTR_AVMA(disym, 0); - SET_LOCAL_EP_AVMA(disym, 0); - disym.pri_name = ML_(addStr)(di, name, -1); - disym.sec_names = NULL; - disym.size = // let canonicalize fix it - di->text_avma+di->text_size - sym_addr; - disym.isText = True; - disym.isIFunc = False; - disym.isGlobal = False; - // Lots of user function names get prepended with an underscore. Eg. the - // function 'f' becomes the symbol '_f'. And the "below main" - // function is called "start". So we skip the leading underscore, and - // if we see 'start' and --show-below-main=no, we rename it as - // "start_according_to_valgrind", which makes it easy to spot later - // and display as "(below main)". - if (disym.pri_name[0] == '_') { - disym.pri_name++; - } - else if (!VG_(clo_show_below_main) && VG_STREQ(disym.pri_name, "start")) { - if (s_a_t_v == NULL) - s_a_t_v = ML_(addStr)(di, "start_according_to_valgrind", -1); - vg_assert(s_a_t_v); - disym.pri_name = s_a_t_v; - } + Addr sym_addr = di->text_bias + section->addr + i * entry_size; - vg_assert(disym.pri_name); - VG_(addToXA)( syms, &disym ); - ML_(dinfo_free)(name); + add_symbol(syms, di, &nl, sym_addr, section->sectname, strtab_cur, strtab_sz); } } - +#endif /* Compare DiSyms by their start address, and for equal addresses, use the primary name as a secondary sort key. */ @@ -527,7 +625,7 @@ static Bool file_exists_p(const HChar *path) } -/* Search for an existing dSYM file as a possible separate debug file. +/* Search for an existing dSYM file as a possible separate debug file. Adapted from gdb. */ static HChar * find_separate_debug_file (const HChar *executable_name) @@ -536,7 +634,7 @@ find_separate_debug_file (const HChar *executable_name) HChar *dot_ptr; HChar *slash_ptr; HChar *dsymfile; - + /* Make sure the object file name itself doesn't contain ".dSYM" in it or we will end up with an infinite loop where after we add a dSYM symbol file, it will then enter this function asking if there is a debug file for the @@ -545,23 +643,23 @@ find_separate_debug_file (const HChar *executable_name) { /* Check for the existence of a .dSYM file for a given executable. */ basename_str = VG_(basename) (executable_name); - dsymfile = ML_(dinfo_zalloc)("di.readmacho.dsymfile", + dsymfile = ML_(dinfo_zalloc)("di.readmacho.dsymfile", VG_(strlen) (executable_name) + VG_(strlen) (APPLE_DSYM_EXT_AND_SUBDIRECTORY) + VG_(strlen) (basename_str) + 1 ); - + /* First try for the dSYM in the same directory as the original file. */ VG_(strcpy) (dsymfile, executable_name); VG_(strcat) (dsymfile, APPLE_DSYM_EXT_AND_SUBDIRECTORY); VG_(strcat) (dsymfile, basename_str); - + if (file_exists_p (dsymfile)) return dsymfile; - + /* Now search for any parent directory that has a '.' in it so we can find - Mac OS X applications, bundles, plugins, and any other kinds of files. + Mac OS X applications, bundles, plugins, and any other kinds of files. Mac OS X application bundles wil have their program in "/some/path/MyApp.app/Contents/MacOS/MyApp" (or replace ".app" with ".bundle" or ".plugin" for other types of bundles). So we look for any @@ -586,7 +684,7 @@ find_separate_debug_file (const HChar *executable_name) if (file_exists_p (dsymfile)) return dsymfile; } - + /* NULL terminate the string at the '.' character and append the path down to the dSYM file. */ *dot_ptr = '\0'; @@ -594,11 +692,11 @@ find_separate_debug_file (const HChar *executable_name) VG_(strcat) (dot_ptr, basename_str); if (file_exists_p (dsymfile)) return dsymfile; - + /* NULL terminate the string at the '.' locatated by the strrchr() function again. */ *dot_ptr = '\0'; - + /* We found a previous extension '.' character and did not find a dSYM file so now find previous directory delimiter so we don't try multiple times on a file name that may have a version number @@ -631,7 +729,7 @@ static DiSlice getsectdata ( DiSlice img, Int c; for (c = 0; c < mh.ncmds; c++) { - struct load_command cmd; + struct load_command cmd; ML_(cur_read_get)(&cmd, cur, sizeof(cmd)); if (cmd.cmd == LC_SEGMENT_CMD) { struct SEGMENT_COMMAND seg; @@ -643,7 +741,7 @@ static DiSlice getsectdata ( DiSlice img, for (s = 0; s < seg.nsects; s++) { struct SECTION sect; ML_(cur_step_get)(§, §s_cur, sizeof(sect)); - if (0 == VG_(strncmp)(sect.sectname, sectname, + if (0 == VG_(strncmp)(sect.sectname, sectname, sizeof(sect.sectname))) { DiSlice res = img; res.ioff = sect.offset; @@ -732,17 +830,31 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) DiCursor dysym_cur = DiCursor_INVALID; HChar* dsymfilename = NULL; Bool have_uuid = False; + Bool from_memory = False; // True if we're reading from DSC + Bool have_rw = False; + Addr kernel_slide = 0; // Used when from_memory is True UChar uuid[16]; Word i; + struct SEGMENT_COMMAND data_const = {.cmd = 0}; + struct SEGMENT_COMMAND link_edit = {.cmd = 0}; const DebugInfoMapping* rx_map = NULL; const DebugInfoMapping* rw_map = NULL; - /* mmap the object file to look for di->soname and di->text_bias + /* mmap the object file to look for di->soname and di->text_bias and uuid and nlist */ /* This should be ensured by our caller (that we're in the accept state). */ vg_assert(di->fsm.have_rx_map); +#if DARWIN_VERS >= DARWIN_11_00 + if (di->from_memory) { + from_memory = True; + kernel_slide = VG_(dyld_cache_get_slide)(); + } +#endif + if (di->fsm.rw_map_count) { + have_rw = True; + } for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); @@ -750,19 +862,27 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) rx_map = map; if (map->rw && !rw_map) rw_map = map; - if (rx_map && rw_map) + if (rx_map && (rw_map || !have_rw)) break; } vg_assert(rx_map); + vg_assert(!have_rw || rw_map); - if (VG_(clo_verbosity) > 1) + if (VG_(clo_verbosity) > 1) { + if (!have_rw) { + VG_(message)(Vg_DebugMsg, + "%s (rx at %#lx)\n", di->fsm.filename, + rx_map->avma); + } else { VG_(message)(Vg_DebugMsg, "%s (rx at %#lx, rw at %#lx)\n", di->fsm.filename, rx_map->avma, rw_map->avma ); + } + } VG_(memset)(&uuid, 0, sizeof(uuid)); - msli = map_image_aboard( di, di->fsm.filename ); + msli = map_image_aboard( di, di->fsm.filename, from_memory ? rx_map : NULL ); if (!ML_(sli_is_valid)(msli)) { ML_(symerr)(di, False, "Connect to main image failed."); goto fail; @@ -773,15 +893,15 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) /* Poke around in the Mach-O header, to find some important stuff. */ // Find LC_SYMTAB and LC_DYSYMTAB, if present. - // Read di->soname from LC_ID_DYLIB if present, - // or from LC_ID_DYLINKER if present, + // Read di->soname from LC_ID_DYLIB if present, + // or from LC_ID_DYLINKER if present, // or use "NONE". // Get di->text_bias (aka slide) based on the corresponding LC_SEGMENT // Get uuid for later dsym search di->text_bias = 0; - { + { DiCursor cmd_cur = ML_(cur_from_sli)(msli); struct MACH_HEADER mh; @@ -795,13 +915,13 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) for (c = 0; c < mh.ncmds; c++) { struct load_command cmd; ML_(cur_read_get)(&cmd, cmd_cur, sizeof(cmd)); - + if (cmd.cmd == LC_SYMTAB) { sym_cur = cmd_cur; - } + } else if (cmd.cmd == LC_DYSYMTAB) { dysym_cur = cmd_cur; - } + } else if (cmd.cmd == LC_ID_DYLIB && mh.filetype == MH_DYLIB) { // GrP fixme bundle? struct dylib_command dcmd; @@ -866,7 +986,7 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) if (!di->text_present && 0 == VG_(strcmp)(&seg.segname[0], "__TEXT") /* DDD: is the next line a kludge? -- JRS */ - && seg.fileoff == 0 && seg.filesize != 0) { + && (from_memory || seg.fileoff == 0) && seg.filesize != 0) { di->text_present = True; di->text_svma = (Addr)seg.vmaddr; di->text_avma = rx_map->avma; @@ -880,18 +1000,56 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) di->text_debug_svma = di->text_svma; di->text_debug_bias = di->text_bias; } + if (0 == VG_(strcmp)(seg.segname, "__DATA_CONST")) { + data_const = seg; + } /* Try for __DATA */ - if (!di->data_present + if (have_rw && !di->data_present && 0 == VG_(strcmp)(&seg.segname[0], "__DATA") /* && DDD:seg->fileoff == 0 */ && seg.filesize != 0) { di->data_present = True; di->data_svma = (Addr)seg.vmaddr; di->data_avma = rw_map->avma; +#if defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_15) + // FIXME: the same mmap contains both __DATA_CONST, __DATA and __DATA_DIRTY + // this means that symbols in __DATA/__DATA_DIRTY are offset by the size of __DATA_CONST + // not sure when this started to be an issue so I am going to gate this under arm64 for now + if (data_const.cmd != 0) { + di->data_avma += data_const.vmsize; + } +#endif di->data_size = seg.vmsize; di->data_bias = di->data_avma - di->data_svma; di->data_debug_svma = di->data_svma; di->data_debug_bias = di->data_bias; } + /* We store __DATA_DIRTY inside .sdata (because they correspond somewhat). + Some binaries have very important information there, + notably dyld and its dyld_all_image_infos. */ + if (have_rw && !di->sdata_present + && 0 == VG_(strcmp)(&seg.segname[0], "__DATA_DIRTY") + /* && DDD:seg->fileoff == 0 */ && seg.filesize != 0) { + di->sdata_present = True; + di->sdata_svma = (Addr)seg.vmaddr; + // FIXME: assumes __DATA was found first (which in practice should be fine) + di->sdata_avma = rw_map->avma + di->data_size; +#if defined(VGA_arm64) + // FIXME: the same mmap contains both __DATA_CONST, __DATA and __DATA_DIRTY + // this means that symbols in __DATA/__DATA_DIRTY are offset by the size of __DATA_CONST + // not sure when this started to be an issue so I am going to gate this under arm64 for now + if (data_const.cmd != 0) { + di->sdata_avma += data_const.vmsize; + } +#endif + di->sdata_size = seg.vmsize; + di->sdata_bias = di->sdata_avma - di->sdata_svma; + di->sdata_debug_svma = di->sdata_svma; + di->sdata_debug_bias = di->sdata_bias; + } + /* Try for __LINKEDIT */ + if (0 == VG_(strcmp)(&seg.segname[0], "__LINKEDIT")) { + link_edit = seg; + } } else if (cmd.cmd == LC_UUID) { ML_(cur_read_get)(&uuid, cmd_cur, sizeof(uuid)); @@ -902,6 +1060,11 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) } } + if (from_memory && link_edit.cmd == 0) { + ML_(symerr)(di, False, "Invalid Mach-O file (missing __LINKEDIT)."); + goto fail; + } + if (!di->soname) { di->soname = ML_(dinfo_strdup)("di.readmacho.noname", "NONE"); } @@ -917,13 +1080,19 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) // We already asserted that .. vg_assert(msli.img != NULL && msli.szB > 0); - if (ML_(cur_is_valid)(sym_cur) && ML_(cur_is_valid)(dysym_cur)) { + if (ML_(cur_is_valid)(sym_cur)) { + // Some binaries (e.g. Valgrind's tools themselves, like memcheck) + // don't have dynamic symbols because they are static binaries. + // Let's try to load symbols using a single table. + Bool has_dynamic = ML_(cur_is_valid)(dysym_cur); struct symtab_command symcmd; struct dysymtab_command dysymcmd; ML_(cur_read_get)(&symcmd, sym_cur, sizeof(symcmd)); - ML_(cur_read_get)(&dysymcmd, dysym_cur, sizeof(dysymcmd)); + if (has_dynamic) { + ML_(cur_read_get)(&dysymcmd, dysym_cur, sizeof(dysymcmd)); + } /* Read nlist symbol table */ DiCursor syms = DiCursor_INVALID; @@ -931,25 +1100,50 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) XArray* /* DiSym */ candSyms = NULL; Word nCandSyms; - if (msli.szB < symcmd.stroff + symcmd.strsize - || msli.szB < symcmd.symoff + symcmd.nsyms - * sizeof(struct NLIST)) { + // FIXME: there is no real nice way to check this when using DSC + // the chunk that msli points to is only the mach_header + load_commands + // but not the actual sections (__TEXT, __DATA, __LINKEDIT, etc) + // so those checks will always fail because they point to data much further in memory + // (as DSC groups all this kind of data together for X amount of images) + if (!from_memory + && (msli.szB < symcmd.stroff + symcmd.strsize + || msli.szB < symcmd.symoff + symcmd.nsyms * sizeof(struct NLIST))) { ML_(symerr)(di, False, "Invalid Mach-O file (5 too small)."); goto fail; - } - if (dysymcmd.ilocalsym + dysymcmd.nlocalsym > symcmd.nsyms - || dysymcmd.iextdefsym + dysymcmd.nextdefsym > symcmd.nsyms) { + } + if (has_dynamic + && (dysymcmd.ilocalsym + dysymcmd.nlocalsym > symcmd.nsyms + || dysymcmd.iextdefsym + dysymcmd.nextdefsym > symcmd.nsyms)) { ML_(symerr)(di, False, "Invalid Mach-O file (bad symbol table)."); goto fail; } - syms = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.symoff); - strs = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.stroff); - - if (VG_(clo_verbosity) > 1) + if (from_memory) { + // First, we calculate the real position of __LINKEDIT in the DSC by adding the slide + // Then we get the offset of syms/strings within __LINKEDIT by removing the fileoffset + // Then we add the __LINKEDIT address + // Finally we calculate the proper offset of those addresses compared to the mach_header slice + Addr link_edit_addr = link_edit.vmaddr + kernel_slide; + syms = ML_(cur_from_sli)(msli); + syms.ioff = (link_edit_addr + (symcmd.symoff - link_edit.fileoff)) - rx_map->avma; + strs = ML_(cur_from_sli)(msli); + strs.ioff = (link_edit_addr + (symcmd.stroff - link_edit.fileoff)) - rx_map->avma; + } else { + syms = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.symoff); + strs = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.stroff); + } + + if (VG_(clo_verbosity) > 1) { + if (has_dynamic) { VG_(message)(Vg_DebugMsg, - " reading syms from primary file (%d %d)\n", + " reading syms from primary file (%u %u)\n", dysymcmd.nextdefsym, dysymcmd.nlocalsym ); + } else { + VG_(message)(Vg_DebugMsg, + " reading syms from primary file (%u)\n", + symcmd.nsyms ); + } + } /* Read candidate symbols into 'candSyms', so we can truncate overlapping ends and generally tidy up, before presenting @@ -959,18 +1153,95 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) ML_(dinfo_free), sizeof(DiSym) ); - // extern symbols - read_symtab(candSyms, - di, - ML_(cur_plus)(syms, - dysymcmd.iextdefsym * sizeof(struct NLIST)), - dysymcmd.nextdefsym, strs, symcmd.strsize); - // static and private_extern symbols - read_symtab(candSyms, - di, - ML_(cur_plus)(syms, - dysymcmd.ilocalsym * sizeof(struct NLIST)), - dysymcmd.nlocalsym, strs, symcmd.strsize); + if (has_dynamic) { + // extern symbols + read_symtab(candSyms, + di, + ML_(cur_plus)(syms, + dysymcmd.iextdefsym * sizeof(struct NLIST)), + dysymcmd.nextdefsym, strs, symcmd.strsize); + // static and private_extern symbols + read_symtab(candSyms, + di, + ML_(cur_plus)(syms, + dysymcmd.ilocalsym * sizeof(struct NLIST)), + dysymcmd.nlocalsym, strs, symcmd.strsize); + +// Due to the usage of dyld_cache, I am unsure how to properly capture the stubs from there +// moreover we don't have a rw_map for those so loads of logic need to change above. +// This is only really useful when reading librairies from disk which is limited now. +// Finally, there is also a weird overflow of some kind on arm64 macOS 15. +// So I am disabling this for now. +#if 0 + { + DiCursor cmd_cur = ML_(cur_from_sli)(msli); + DiCursor indirs = DiCursor_INVALID; + + if (from_memory) { + Addr link_edit_addr = link_edit.vmaddr + kernel_slide; + indirs = ML_(cur_from_sli)(msli); + indirs.ioff = (link_edit_addr + (dysymcmd.indirectsymoff - link_edit.fileoff)) - rx_map->avma; + } else { + indirs = ML_(cur_plus)(ML_(cur_from_sli)(msli), dysymcmd.indirectsymoff); + } + + struct MACH_HEADER mh; + ML_(cur_step_get)(&mh, &cmd_cur, sizeof(mh)); + for (Int c = 0; c < mh.ncmds; c++) { + struct load_command cmd; + ML_(cur_read_get)(&cmd, cmd_cur, sizeof(cmd)); + + if (cmd.cmd == LC_SEGMENT_CMD) { + struct SEGMENT_COMMAND seg; + ML_(cur_read_get)(&seg, cmd_cur, sizeof(seg)); + + for (i = 0; i < seg.nsects; i += 1) { + DiCursor sect_cur = ML_(cur_plus)(cmd_cur, sizeof(seg)); + struct SECTION sect; + ML_(cur_read_get)(§, sect_cur, sizeof(sect)); + Int indexOfIndirects = sect.reserved1; + + if ((sect.flags & S_SYMBOL_STUBS) == S_SYMBOL_STUBS) { + Int sizeOfStub = sect.reserved2; + Int amountOfStubs = sect.size / sizeOfStub; + if (indexOfIndirects + amountOfStubs > dysymcmd.nindirectsyms) { + ML_(symerr)(di, False, "Invalid Mach-O file (invalid stub section)."); + goto fail; + } + // add symbols where we have stub assembly + add_indirect_symbols(candSyms, di, + §, sizeOfStub, + ML_(cur_plus)(indirs, indexOfIndirects * sizeof(UInt)), amountOfStubs, + syms, symcmd.nsyms, strs, symcmd.strsize); + } + if ((sect.flags & S_LAZY_SYMBOL_POINTERS) == S_LAZY_SYMBOL_POINTERS) { + Int sizeOfPointer = VG_WORDSIZE; + Int amountOfPointers = sect.size / sizeOfPointer; + if (indexOfIndirects + amountOfPointers > dysymcmd.nindirectsyms) { + ML_(symerr)(di, False, "Invalid Mach-O file (invalid lazy symbol section)."); + goto fail; + } + // add symbols where we have lazy symbol pointers + add_indirect_symbols(candSyms, di, + §, sizeOfPointer, + ML_(cur_plus)(indirs, indexOfIndirects * sizeof(UInt)), amountOfPointers, + syms, symcmd.nsyms, strs, symcmd.strsize); + } + + sect_cur = ML_(cur_plus)(sect_cur, sizeof(sect)); + } + } + + cmd_cur = ML_(cur_plus)(cmd_cur, cmd.cmdsize); + } + } +#endif + } else { + read_symtab(candSyms, + di, + syms, + symcmd.nsyms, strs, symcmd.strsize); + } /* tidy up the cand syms -- trim overlapping ends. May resize candSyms. */ @@ -1014,7 +1285,7 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " dSYM= %s\n", dsymfilename); - dsli = map_image_aboard( di, dsymfilename ); + dsli = map_image_aboard( di, dsymfilename, NULL ); if (!ML_(sli_is_valid)(dsli)) { ML_(symerr)(di, False, "Connect to debuginfo image failed " "(first attempt)."); @@ -1052,7 +1323,7 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) VG_(message)(Vg_DebugMsg, "%sdSYM directory %s; consider using " "--dsymutil=yes\n", VG_(clo_verbosity) > 1 ? " " : "", - dsymfilename ? "has wrong UUID" : "is missing"); + dsymfilename ? "has wrong UUID" : "is missing"); goto success; } @@ -1060,7 +1331,7 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) { Int r; const HChar* dsymutil = "/usr/bin/dsymutil "; - HChar* cmd = ML_(dinfo_zalloc)( "di.readmacho.tmp1", + HChar* cmd = ML_(dinfo_zalloc)( "di.readmacho.tmp1", VG_(strlen)(dsymutil) + VG_(strlen)(di->fsm.filename) + 32 /* misc */ ); @@ -1069,7 +1340,9 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) VG_(strcat)(cmd, "\""); VG_(strcat)(cmd, di->fsm.filename); VG_(strcat)(cmd, "\""); - VG_(message)(Vg_DebugMsg, "run: %s\n", cmd); + if (VG_(clo_verbosity) > 0) { + VG_(message)(Vg_DebugMsg, "run: %s\n", cmd); + } r = VG_(system)( cmd ); if (r) VG_(message)(Vg_DebugMsg, "run: %s FAILED\n", dsymutil); @@ -1084,7 +1357,7 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " dsyms= %s\n", dsymfilename); - dsli = map_image_aboard( di, dsymfilename ); + dsli = map_image_aboard( di, dsymfilename, NULL ); if (!ML_(sli_is_valid)(dsli)) { ML_(symerr)(di, False, "Connect to debuginfo image failed " "(second attempt)."); @@ -1160,13 +1433,13 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) eh_frame_svma + di->text_bias, True/*is_ehframe*/); } - + if (ML_(sli_is_valid)(debug_info_mscn)) { if (VG_(clo_verbosity) > 1) { if (0) VG_(message)(Vg_DebugMsg, "Reading dwarf3 for %s (%#lx) from %s" - " (%lld %lld %lld %lld %lld %lld)\n", + " (%llu %llu %llu %llu %llu %llu)\n", di->fsm.filename, di->text_avma, dsymfilename, debug_info_mscn.szB, debug_abbv_mscn.szB, debug_line_mscn.szB, debug_str_mscn.szB, diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index fa358df64f..ca69624174 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -733,7 +733,7 @@ static UInt local_sys_write_stderr ( const HChar* buf, Int n ) "1: " : "=a" (res), "=d" (err) : "S" (buf), "d" (n) - : "cc"); + : "rdi", "rcx", "r11", "cc"); restart = err && (res == VKI_EINTR || res == VKI_ERESTART); } while (restart); diff --git a/coregrind/m_demangle/ansidecl.h b/coregrind/m_demangle/ansidecl.h index 534b05251d..14231e8b0d 100644 --- a/coregrind/m_demangle/ansidecl.h +++ b/coregrind/m_demangle/ansidecl.h @@ -1,5 +1,5 @@ /* Compiler compatibility macros - Copyright (C) 1991-2025 Free Software Foundation, Inc. + Copyright (C) 1991-2026 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify diff --git a/coregrind/m_demangle/cp-demangle.c b/coregrind/m_demangle/cp-demangle.c index 3bf5a372ef..9ea5c96267 100644 --- a/coregrind/m_demangle/cp-demangle.c +++ b/coregrind/m_demangle/cp-demangle.c @@ -1,5 +1,5 @@ /* Demangler for g++ V3 ABI. - Copyright (C) 2003-2025 Free Software Foundation, Inc. + Copyright (C) 2003-2026 Free Software Foundation, Inc. Written by Ian Lance Taylor . This file is part of the libiberty library, which is part of GCC. diff --git a/coregrind/m_demangle/cp-demangle.h b/coregrind/m_demangle/cp-demangle.h index 9b33a2f84c..a89aa06bc1 100644 --- a/coregrind/m_demangle/cp-demangle.h +++ b/coregrind/m_demangle/cp-demangle.h @@ -1,5 +1,5 @@ /* Internal demangler interface for g++ V3 ABI. - Copyright (C) 2003-2025 Free Software Foundation, Inc. + Copyright (C) 2003-2026 Free Software Foundation, Inc. Written by Ian Lance Taylor . This file is part of the libiberty library, which is part of GCC. diff --git a/coregrind/m_demangle/cplus-dem.c b/coregrind/m_demangle/cplus-dem.c index 9d173c03db..8e55faffbb 100644 --- a/coregrind/m_demangle/cplus-dem.c +++ b/coregrind/m_demangle/cplus-dem.c @@ -1,5 +1,5 @@ /* Demangler for GNU C++ - Copyright (C) 1989-2025 Free Software Foundation, Inc. + Copyright (C) 1989-2026 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.uucp) Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling Modified by Satish Pai (pai@apollo.hp.com) for HP demangling diff --git a/coregrind/m_demangle/d-demangle.c b/coregrind/m_demangle/d-demangle.c index 2f44211eb7..a406ddd4bd 100644 --- a/coregrind/m_demangle/d-demangle.c +++ b/coregrind/m_demangle/d-demangle.c @@ -1,5 +1,5 @@ /* Demangler for the D programming language - Copyright (C) 2014-2025 Free Software Foundation, Inc. + Copyright (C) 2014-2026 Free Software Foundation, Inc. Written by Iain Buclaw (ibuclaw@gdcproject.org) This file is part of the libiberty library. diff --git a/coregrind/m_demangle/demangle.h b/coregrind/m_demangle/demangle.h index 010c103d0b..075660d642 100644 --- a/coregrind/m_demangle/demangle.h +++ b/coregrind/m_demangle/demangle.h @@ -1,5 +1,5 @@ /* Defs for interface to demanglers. - Copyright (C) 1992-2025 Free Software Foundation, Inc. + Copyright (C) 1992-2026 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License diff --git a/coregrind/m_demangle/dyn-string.c b/coregrind/m_demangle/dyn-string.c index 38ad5eb5ff..676178031d 100644 --- a/coregrind/m_demangle/dyn-string.c +++ b/coregrind/m_demangle/dyn-string.c @@ -1,5 +1,5 @@ /* An abstract string datatype. - Copyright (C) 1998-2025 Free Software Foundation, Inc. + Copyright (C) 1998-2026 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com). This file is part of GNU CC. diff --git a/coregrind/m_demangle/dyn-string.h b/coregrind/m_demangle/dyn-string.h index 7e07a4d926..5b0c0671f4 100644 --- a/coregrind/m_demangle/dyn-string.h +++ b/coregrind/m_demangle/dyn-string.h @@ -1,5 +1,5 @@ /* An abstract string datatype. - Copyright (C) 1998-2025 Free Software Foundation, Inc. + Copyright (C) 1998-2026 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com). This file is part of GCC. diff --git a/coregrind/m_demangle/rust-demangle.c b/coregrind/m_demangle/rust-demangle.c index 70f13d7c4d..717d8c45d9 100644 --- a/coregrind/m_demangle/rust-demangle.c +++ b/coregrind/m_demangle/rust-demangle.c @@ -1,5 +1,5 @@ /* Demangler for the Rust programming language - Copyright (C) 2016-2025 Free Software Foundation, Inc. + Copyright (C) 2016-2026 Free Software Foundation, Inc. Written by David Tolnay (dtolnay@gmail.com). Rewritten by Eduard-Mihai Burtescu (eddyb@lyken.rs) for v0 support. @@ -678,10 +678,17 @@ demangle_binder (struct rust_demangler *rdm) return; bound_lifetimes = parse_opt_integer_62 (rdm, 'G'); + /* Reject implausibly large lifetime counts to prevent + resource exhaustion from crafted symbols (PR demangler/106641). */ + if (bound_lifetimes > 1024) + { + rdm->errored = 1; + return; + } if (bound_lifetimes > 0) { PRINT ("for<"); - for (i = 0; i < bound_lifetimes; i++) + for (i = 0; i < bound_lifetimes && !rdm->errored; i++) { if (i > 0) PRINT (", "); diff --git a/coregrind/m_demangle/safe-ctype.c b/coregrind/m_demangle/safe-ctype.c index 95c41cd68f..bf8b2529e0 100644 --- a/coregrind/m_demangle/safe-ctype.c +++ b/coregrind/m_demangle/safe-ctype.c @@ -1,6 +1,6 @@ /* replacement macros. - Copyright (C) 2000-2025 Free Software Foundation, Inc. + Copyright (C) 2000-2026 Free Software Foundation, Inc. Contributed by Zack Weinberg . This file is part of the libiberty library. diff --git a/coregrind/m_demangle/safe-ctype.h b/coregrind/m_demangle/safe-ctype.h index c0f8042281..ae3d8cac14 100644 --- a/coregrind/m_demangle/safe-ctype.h +++ b/coregrind/m_demangle/safe-ctype.h @@ -1,6 +1,6 @@ /* replacement macros. - Copyright (C) 2000-2025 Free Software Foundation, Inc. + Copyright (C) 2000-2026 Free Software Foundation, Inc. Contributed by Zack Weinberg . This file is part of the libiberty library. diff --git a/coregrind/m_execontext.c b/coregrind/m_execontext.c index cd4b870e23..dbe1988149 100644 --- a/coregrind/m_execontext.c +++ b/coregrind/m_execontext.c @@ -611,6 +611,17 @@ ExeContext* VG_(null_ExeContext) (void) return null_ExeContext; } +const HChar* VG_(get_ExeContext_first_fnname)(ExeContext* ec) +{ + const HChar* fn_name; + vg_assert(ec->n_ips > 0); + Bool found_fn = VG_(get_fnname)(VG_(get_ExeContext_epoch)(ec), ec->ips[0], &fn_name); + if (found_fn) { + return fn_name; + } + return NULL; +} + /*--------------------------------------------------------------------*/ /*--- end m_execontext.c ---*/ /*--------------------------------------------------------------------*/ diff --git a/coregrind/m_extension/extension-s390x.c b/coregrind/m_extension/extension-s390x.c index 9c2df8d796..efb9b8ceca 100644 --- a/coregrind/m_extension/extension-s390x.c +++ b/coregrind/m_extension/extension-s390x.c @@ -7,7 +7,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright (C) IBM Corp. 2024 + Copyright (C) IBM Corp. 2024-2026 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -37,10 +37,14 @@ #undef SYSNO -#define READ_FUNCTION_CODE(tst, extname) \ +/* Divide by 4 and assure zero remainder (else force div. by zero) */ +#define S390_WORD_LEN(len) ((len) / ((len) % 4 ? 0 : 4)) + +#define READ_FUNCTION_CODE(tst, extname, ty) \ ({ \ - PRE_REG_READ(tst, extname "(func_code)", r0, 7, sizeof(UChar)); \ - tst->arch.vex.guest_r0 & 0xff; \ + PRE_REG_READ(tst, extname "(func_code)", r0, 8 - sizeof(ty), \ + sizeof(ty)); \ + (ty) tst->arch.vex.guest_r0; \ }) #define READ_GPR(tst, name, regno) \ @@ -107,7 +111,7 @@ union reg_pair { return cc >> 28; \ } -#define S390_DEFINE_DO_RR_INSN(fname, opc) \ +#define S390_DEFINE_DO_RR_INSN(fname, opc, m3) \ static Int fname(ULong func, ULong parms, ULong* addr1, ULong* len1, \ ULong* addr2, ULong* len2) \ { \ @@ -117,7 +121,7 @@ union reg_pair { register void* reg1 asm("1") = (void*)parms; \ UInt cc; \ \ - asm volatile(".insn rre, " #opc "0000, %[op1], %[op2]\n" \ + asm volatile(".insn rre, " #opc m3 "000, %[op1], %[op2]\n" \ "ipm %[cc]\n" \ : [cc] "=d"(cc), [op1] "+a"(op1.pair), [op2] "+a"(op2.pair) \ : "d"(reg0), "d"(reg1) \ @@ -129,7 +133,7 @@ union reg_pair { return cc >> 28; \ } -#define S390_DEFINE_DO_0R_INSN(fname, opc) \ +#define S390_DEFINE_DO_0R_INSN(fname, opc, m3) \ static Int fname(ULong func, ULong parms, ULong* addr2, ULong* len2) \ { \ union reg_pair op2 = {{*addr2, *len2}}; \ @@ -137,7 +141,7 @@ union reg_pair { register void* reg1 asm("1") = (void*)parms; \ UInt cc; \ \ - asm volatile(".insn rre, " #opc "0000, 0, %[op2]\n" \ + asm volatile(".insn rre, " #opc m3 "000, 0, %[op2]\n" \ "ipm %[cc]\n" \ : [cc] "=d"(cc), [op2] "+a"(op2.pair) \ : "d"(reg0), "d"(reg1) \ @@ -187,21 +191,22 @@ static void s390_filter_functions(ULong* fc, /*--- PRNO (perform random number operation) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_PRNO_insn, 0xb93c) +S390_DEFINE_DO_RR_INSN(do_PRNO_insn, 0xb93c, "0") /* PRNO functions that we support if the hardware does. */ static const ULong PRNO_functions[] = { (S390_SETBIT(0) // Query | S390_SETBIT(3)), // SHA-512-DRNG (S390_SETBIT(112) // TRNG-Query-Raw-to-Conditioned-Ratio - | S390_SETBIT(114)), // TRNG + | S390_SETBIT(114) // TRNG + | S390_SETBIT(127)), // PRNO-Query-Authentication-Information }; static enum ExtensionError do_extension_PRNO(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "PRNO"); + UChar func = READ_FUNCTION_CODE(tst, "PRNO", UChar); UChar fc = func & 0x7f; UChar mflag = func & 128; ULong parms = READ_GPR(tst, "PRNO(r1)", 1); @@ -263,6 +268,12 @@ static enum ExtensionError do_extension_PRNO(ThreadState* tst, ULong variant) POST_MEM_WRITE(tst, orig_addr1, orig_len1 - len1); POST_MEM_WRITE(tst, orig_addr2, orig_len2 - len2); break; + case 127: // Query authentication information + parms_len = 256; + PRE_MEM_WRITE(tst, "PRNO(parms)", parms, parms_len); + cc = do_PRNO_insn(func, parms, &addr1, &len1, &addr2, &len2); + POST_MEM_WRITE(tst, parms, parms_len); + break; default: return INSN_ERR("PRNO: unknown function code\n"); } @@ -809,7 +820,7 @@ static UWord do_extension_DFLTCC(ThreadState* tst, ULong variant) UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; UChar r3 = (variant >> 8) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "DFLTCC"); + UInt func = READ_FUNCTION_CODE(tst, "DFLTCC", UInt); UChar fc = func & 0x7f; Bool hbt = (func & 128) != 0; ULong parms = READ_GPR(tst, "DFLTCC(r1)", 1); @@ -956,7 +967,13 @@ static enum ExtensionError do_extension_STFLE(ThreadState* tst, ULong variant) /* 80: DFP packed-conversion, not supported */ /* 81: PPA-in-order, not supported */ | S390_SETBITS(82, 82) - /* 83-127: unassigned */), + /* 83: unassigned */ + | S390_SETBITS(84, 84) + /* 85: sequential-instruction, not supported */ + | S390_SETBITS(86, 86) + /* 87: PLO-extension, not supported */ + /* 88-127: unassigned */ + ), /* === 128 .. 191 === */ (S390_SETBITS(128, 131) @@ -984,7 +1001,9 @@ static enum ExtensionError do_extension_STFLE(ThreadState* tst, ULong variant) /* 192: vector-packed-decimal, not supported */ (S390_SETBITS(193, 194) /* 195: unassigned */ - | S390_SETBITS(196, 197)), + | S390_SETBITS(196, 198) + /* 199: vector-packed-decimal-enhancment 3, not supported */ + /* 200-255: unassigned */), }; cc = do_STFLE_insn((void*)addr, last_dw + 1, &gpr0); @@ -1004,7 +1023,7 @@ static enum ExtensionError do_extension_STFLE(ThreadState* tst, ULong variant) /*--- KM (cypher message) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_KM_insn, 0xb92e) +S390_DEFINE_DO_RR_INSN(do_KM_insn, 0xb92e, "0") /* List all the functions supported. This list provides the parameter block sizes and will also be used for filtering the supported functions. The @@ -1029,21 +1048,30 @@ S390_DEFINE_DO_RR_INSN(do_KM_insn, 0xb92e) S390_DO_FUNC(58, S390_KM_XTS_Encrypted_AES_128, 64) \ S390_DO_FUNC(60, S390_KM_XTS_Encrypted_AES_256, 80) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KM_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(82, S390_KM_Full_XTS_AES_128, 64) \ + S390_DO_FUNC(84, S390_KM_Full_XTS_AES_256, 96) \ + S390_DO_FUNC(90, S390_KM_Full_XTS_Encrypted_AES_128, 96) \ + S390_DO_FUNC(92, S390_KM_Full_XTS_Encrypted_AES_256, 128) \ + S390_DO_FUNC(127, S390_KM_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KM_parms_len[] = {S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KM_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KM_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 static enum ExtensionError do_extension_KM(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KM"); + UInt func = READ_FUNCTION_CODE(tst, "KM", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KM(r1)", 1); ULong parms_len = 0; @@ -1052,7 +1080,7 @@ static enum ExtensionError do_extension_KM(ThreadState* tst, ULong variant) ULong addr1 = 0, len1 = 0, addr2 = 0, len2 = 0; if (fc < sizeof(S390_KM_parms_len) / sizeof(S390_KM_parms_len[0])) - parms_len = S390_KM_parms_len[fc]; + parms_len = S390_KM_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KM: unknown function code\n"); @@ -1062,6 +1090,10 @@ static enum ExtensionError do_extension_KM(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KM_supported_fc, sizeof(S390_KM_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KM(parms)", parms, parms_len); + cc = do_KM_insn(func, parms, &addr1, &len1, &addr2, &len2); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr1 = orig_addr1 = READ_GPR(tst, "KM(op1_addr)", r1); addr2 = READ_GPR(tst, "KM(op2_addr)", r2); @@ -1083,7 +1115,7 @@ static enum ExtensionError do_extension_KM(ThreadState* tst, ULong variant) /*--- KMC (cypher message with chaining) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_KMC_insn, 0xb92f) +S390_DEFINE_DO_RR_INSN(do_KMC_insn, 0xb92f, "0") #define S390_DO_FUNCTIONS \ S390_DO_FUNC(0, S390_KMC_Query, 16) \ @@ -1100,9 +1132,11 @@ S390_DEFINE_DO_RR_INSN(do_KMC_insn, 0xb92f) S390_DO_FUNC(27, S390_KMC_Encrypted_AES_192, 72) \ S390_DO_FUNC(28, S390_KMC_Encrypted_AES_256, 80) -#define S390_DO_FUNCTIONS1 S390_DO_FUNC(67, S390_KMC_PRNG, 32) +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(67, S390_KMC_PRNG, 32) \ + S390_DO_FUNC(127, S390_KMC_Query_Authentication_Information, 256) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), static const UChar S390_KMC_parms_len[] = { S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC @@ -1119,7 +1153,7 @@ static enum ExtensionError do_extension_KMC(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KMC"); + UInt func = READ_FUNCTION_CODE(tst, "KMC", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMC(r1)", 1); ULong parms_len = 0; @@ -1128,7 +1162,7 @@ static enum ExtensionError do_extension_KMC(ThreadState* tst, ULong variant) ULong addr1 = 0, len1 = 0, addr2 = 0, len2 = 0; if (fc < sizeof(S390_KMC_parms_len) / sizeof(S390_KMC_parms_len[0])) - parms_len = S390_KMC_parms_len[fc]; + parms_len = S390_KMC_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMC: unknown function code\n"); @@ -1137,6 +1171,9 @@ static enum ExtensionError do_extension_KMC(ThreadState* tst, ULong variant) cc = do_KMC_insn(func, parms, &addr1, &len1, &addr2, &len2); s390_filter_functions((ULong*)parms, parms_len, S390_KMC_supported_fc, sizeof(S390_KMC_supported_fc)); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KMC(parms)", parms, parms_len); + cc = do_KMC_insn(func, parms, &addr1, &len1, &addr2, &len2); } else { addr1 = orig_addr1 = READ_GPR(tst, "KMC(op1_addr)", r1); addr2 = READ_GPR(tst, "KMC(op2_addr)", r2); @@ -1159,7 +1196,8 @@ static enum ExtensionError do_extension_KMC(ThreadState* tst, ULong variant) /*--- KIMD (compute intermediate message digest) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_0R_INSN(do_KIMD_insn, 0xb93e) +S390_DEFINE_DO_0R_INSN(do_KIMD_insn, 0xb93e, "0") +S390_DEFINE_DO_0R_INSN(do_KIMD8_insn, 0xb93e, "8") #define S390_DO_FUNCTIONS \ S390_DO_FUNC(0, S390_KIMD_Query, 16) \ @@ -1171,23 +1209,30 @@ S390_DEFINE_DO_0R_INSN(do_KIMD_insn, 0xb93e) S390_DO_FUNC(34, S390_KIMD_SHA3_384, 200) \ S390_DO_FUNC(35, S390_KIMD_SHA3_512, 200) \ S390_DO_FUNC(36, S390_KIMD_SHAKE_128, 200) \ - S390_DO_FUNC(37, S390_KIMD_SHAKE_256, 200) \ - S390_DO_FUNC(65, S390_KIMD_GHASH, 32) + S390_DO_FUNC(37, S390_KIMD_SHAKE_256, 200) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KIMD_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(65, S390_KIMD_GHASH, 32) \ + S390_DO_FUNC(127, S390_KIMD_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KIMD_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KIMD_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KIMD_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 static enum ExtensionError do_extension_KIMD(ThreadState* tst, ULong variant) { UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KIMD"); + UChar m3 = (variant >> 8) & 0xf; + UInt func = READ_FUNCTION_CODE(tst, "KIMD", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KIMD(r1)", 1); ULong parms_len = 0; @@ -1195,7 +1240,7 @@ static enum ExtensionError do_extension_KIMD(ThreadState* tst, ULong variant) ULong addr2 = 0, len2 = 0; if (fc < sizeof(S390_KIMD_parms_len) / sizeof(S390_KIMD_parms_len[0])) - parms_len = S390_KIMD_parms_len[fc]; + parms_len = S390_KIMD_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KIMD: unknown function code\n"); @@ -1205,13 +1250,23 @@ static enum ExtensionError do_extension_KIMD(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KIMD_supported_fc, sizeof(S390_KIMD_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + parms_len = 256; + PRE_MEM_WRITE(tst, "KIMD(parms)", parms, parms_len); + cc = do_KIMD_insn(func, parms, &addr2, &len2); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr2 = READ_GPR(tst, "KIMD(op2_addr)", r2); len2 = READ_GPR(tst, "KIMD(op2_len)", r2 + 1); - PRE_MEM_READ(tst, "KIMD(parms)", parms, parms_len); + + /* The parm block is an input unless the "no-ICV-parameter" applies */ + if ((m3 & 8) == 0 || (func & 0x8000) == 0 || fc < 32 || fc > 37) { + PRE_MEM_READ(tst, "KIMD(parms)", parms, parms_len); + } PRE_MEM_WRITE(tst, "KIMD(parms)", parms, parms_len); PRE_MEM_READ(tst, "KIMD(op2)", addr2, len2); - cc = do_KIMD_insn(func, parms, &addr2, &len2); + cc = (m3 & 8) == 0 ? do_KIMD_insn(func, parms, &addr2, &len2) + : do_KIMD8_insn(func, parms, &addr2, &len2); WRITE_GPR(tst, r2, addr2); WRITE_GPR(tst, r2 + 1, len2); POST_MEM_WRITE(tst, parms, parms_len); @@ -1224,7 +1279,8 @@ static enum ExtensionError do_extension_KIMD(ThreadState* tst, ULong variant) /*--- KLMD (compute last message digest) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_KLMD_insn, 0xb93f) +S390_DEFINE_DO_RR_INSN(do_KLMD_insn, 0xb93f, "0") +S390_DEFINE_DO_RR_INSN(do_KLMDf_insn, 0xb93f, "8") #define S390_DO_FUNCTIONS \ S390_DO_FUNC(0, S390_KLMD_Query, 16) \ @@ -1238,21 +1294,28 @@ S390_DEFINE_DO_RR_INSN(do_KLMD_insn, 0xb93f) S390_DO_FUNC(36, S390_KLMD_SHAKE_128, 200) \ S390_DO_FUNC(37, S390_KLMD_SHAKE_256, 200) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KLMD_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(127, S390_KLMD_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KLMD_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KLMD_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KLMD_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 static enum ExtensionError do_extension_KLMD(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - ULong func = READ_GPR(tst, "KLMD(r0)", 0); + UChar m3 = (variant >> 8) & 0xf; + UInt func = READ_FUNCTION_CODE(tst, "KLMD", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KLMD(r1)", 1); ULong parms_len = 0; @@ -1261,7 +1324,7 @@ static enum ExtensionError do_extension_KLMD(ThreadState* tst, ULong variant) ULong addr1 = 0, len1 = 0, addr2 = 0, len2 = 0; if (fc < sizeof(S390_KLMD_parms_len) / sizeof(S390_KLMD_parms_len[0])) - parms_len = S390_KLMD_parms_len[fc]; + parms_len = S390_KLMD_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KLMD: unknown function code\n"); PRE_MEM_WRITE(tst, "KLMD(parms)", parms, parms_len); @@ -1270,11 +1333,16 @@ static enum ExtensionError do_extension_KLMD(ThreadState* tst, ULong variant) cc = do_KLMD_insn(func, parms, &addr1, &len1, &addr2, &len2); s390_filter_functions((ULong*)parms, parms_len, S390_KLMD_supported_fc, sizeof(S390_KLMD_supported_fc)); + } else if (fc == 127) { // Query authentication information + cc = do_KLMD_insn(func, parms, &addr1, &len1, &addr2, &len2); } else { /* The "shake" functions use the first operand */ Bool have_op1 = fc >= 36 && fc <= 37; - PRE_MEM_READ(tst, "KLMD(parms)", parms, parms_len); + /* The parm block is an input unless the "no-ICV-parameter" applies */ + if ((m3 & 8) == 0 || (func & 0x8000) == 0 || fc < 32 || fc > 37) { + PRE_MEM_READ(tst, "KLMD(parms)", parms, parms_len); + } if (have_op1) { if (r1 == 0 || r1 % 2 != 0) return INSN_ERR("KLMD: bad r1 field"); @@ -1285,7 +1353,9 @@ static enum ExtensionError do_extension_KLMD(ThreadState* tst, ULong variant) addr2 = READ_GPR(tst, "KLMD(op2_addr)", r2); len2 = READ_GPR(tst, "KLMD(op2_len)", r2 + 1); PRE_MEM_READ(tst, "KLMD(op2)", addr2, len2); - cc = do_KLMD_insn(func, parms, &addr1, &len1, &addr2, &len2); + cc = (m3 & 8) == 0 + ? do_KLMD_insn(func, parms, &addr1, &len1, &addr2, &len2) + : do_KLMDf_insn(func, parms, &addr1, &len1, &addr2, &len2); if (have_op1) { WRITE_GPR(tst, r1, addr1); WRITE_GPR(tst, r1 + 1, len1); @@ -1303,7 +1373,7 @@ static enum ExtensionError do_extension_KLMD(ThreadState* tst, ULong variant) /*--- KMAC (compute message authentication code) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_0R_INSN(do_KMAC_insn, 0xb91e) +S390_DEFINE_DO_0R_INSN(do_KMAC_insn, 0xb91e, "0") #define S390_DO_FUNCTIONS \ S390_DO_FUNC(0, S390_KMAC_Query, 16) \ @@ -1320,20 +1390,34 @@ S390_DEFINE_DO_0R_INSN(do_KMAC_insn, 0xb91e) S390_DO_FUNC(27, S390_KMAC_Encrypted_AES_192, 72) \ S390_DO_FUNC(28, S390_KMAC_Encrypted_AES_256, 80) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KMAC_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(112, S390_KMAC_HMAC_SHA_224, 104) \ + S390_DO_FUNC(113, S390_KMAC_HMAC_SHA_256, 104) \ + S390_DO_FUNC(114, S390_KMAC_HMAC_SHA_384, 208) \ + S390_DO_FUNC(115, S390_KMAC_HMAC_SHA_512, 208) \ + S390_DO_FUNC(120, S390_KMAC_HMAC_Encrypted_SHA_224, 136) \ + S390_DO_FUNC(121, S390_KMAC_HMAC_Encrypted_SHA_256, 136) \ + S390_DO_FUNC(122, S390_KMAC_HMAC_Encrypted_SHA_384, 240) \ + S390_DO_FUNC(123, S390_KMAC_HMAC_Encrypted_SHA_512, 240) \ + S390_DO_FUNC(127, S390_KMAC_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KMAC_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KMAC_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KMAC_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 static enum ExtensionError do_extension_KMAC(ThreadState* tst, ULong variant) { UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KMAC"); + UInt func = READ_FUNCTION_CODE(tst, "KMAC", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMAC(r1)", 1); ULong parms_len = 0; @@ -1341,7 +1425,7 @@ static enum ExtensionError do_extension_KMAC(ThreadState* tst, ULong variant) ULong addr2 = 0, len2 = 0; if (fc < sizeof(S390_KMAC_parms_len) / sizeof(S390_KMAC_parms_len[0])) - parms_len = S390_KMAC_parms_len[fc]; + parms_len = S390_KMAC_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMAC: unknown function code\n"); @@ -1351,6 +1435,10 @@ static enum ExtensionError do_extension_KMAC(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KMAC_supported_fc, sizeof(S390_KMAC_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KMAC(parms)", parms, parms_len); + cc = do_KMAC_insn(func, parms, &addr2, &len2); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr2 = READ_GPR(tst, "KMAC(op2_addr)", r2); len2 = READ_GPR(tst, "KMAC(op2_len)", r2 + 1); @@ -1379,6 +1467,7 @@ enum PCC_function_class { PCC_Compute_Last_Block_CMAC, PCC_Compute_XTS_Parameter, PCC_Scalar_Multiply, + PCC_Query_Authentication_Information, }; #define S390_DO_FUNCTIONS \ @@ -1413,7 +1502,8 @@ enum PCC_function_class { S390_DO_FUNC(72, PCC_Scalar_Multiply, Ed25519, 64, 168) \ S390_DO_FUNC(73, PCC_Scalar_Multiply, Ed448, 128, 328) \ S390_DO_FUNC(80, PCC_Scalar_Multiply, X25519, 32, 104) \ - S390_DO_FUNC(81, PCC_Scalar_Multiply, X448, 64, 200) + S390_DO_FUNC(81, PCC_Scalar_Multiply, X448, 64, 200) \ + S390_DO_FUNC(127, PCC_Query_Authentication_Information, QAuth, 0, 256) #define S390_DO_FUNC(fc, class, name, rlen, plen) \ [fc] = {class, rlen / 8, plen / 8}, @@ -1434,7 +1524,7 @@ static const ULong S390_PCC_supported_fc[] = {0 S390_DO_FUNCTIONS, static enum ExtensionError do_extension_PCC(ThreadState* tst, ULong variant) { - UChar func = READ_FUNCTION_CODE(tst, "PCC"); + UChar func = READ_FUNCTION_CODE(tst, "PCC", UChar); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "PCC(r1)", 1); ULong parms_len = 0; @@ -1456,6 +1546,12 @@ static enum ExtensionError do_extension_PCC(ThreadState* tst, ULong variant) sizeof(S390_PCC_supported_fc)); result_offs = 0; break; + case PCC_Query_Authentication_Information: + PRE_MEM_WRITE(tst, "PCC(parms)", parms, parms_len); + cc = do_PCC_insn(func, parms); + result_offs = 0; + result_len = parms_len; + break; case PCC_Compute_Last_Block_CMAC: /* result_len == sizeof(ICV) == sizeof(message) */ PRE_MEM_READ(tst, "PCC(parms)", parms, 8); @@ -1533,15 +1629,21 @@ S390_DEFINE_DO_RRR_INSN(do_KMCTR_insn, 0xb92d) S390_DO_FUNC(27, S390_KMCTR_Encrypted_AES_192, 56) \ S390_DO_FUNC(28, S390_KMCTR_Encrypted_AES_256, 64) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KMCTR_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(127, S390_KMCTR_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KMCTR_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KMCTR_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KMCTR_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 enum { S390_KMCTR_parms_len_n = @@ -1553,7 +1655,7 @@ static enum ExtensionError do_extension_KMCTR(ThreadState* tst, ULong variant) UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; UChar r3 = (variant >> 8) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KMCTR"); + UChar func = READ_FUNCTION_CODE(tst, "KMCTR", UChar); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMCTR(r1)", 1); ULong parms_len = 0; @@ -1562,7 +1664,7 @@ static enum ExtensionError do_extension_KMCTR(ThreadState* tst, ULong variant) ULong addr1 = 0, addr2 = 0, addr3 = 0, len2 = 0, len3 = 0; if (fc < S390_KMCTR_parms_len_n) - parms_len = S390_KMCTR_parms_len[fc]; + parms_len = S390_KMCTR_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMCTR: unknown function code\n"); @@ -1572,6 +1674,10 @@ static enum ExtensionError do_extension_KMCTR(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KMCTR_supported_fc, sizeof(S390_KMCTR_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KMCTR(parms)", parms, parms_len); + cc = do_KMCTR_insn(func, parms, &addr1, &addr2, &len2, &addr3, &len3); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr1 = orig_addr1 = READ_GPR(tst, "KMCTR(op1_addr)", r1); addr2 = READ_GPR(tst, "KMCTR(op2_addr)", r2); @@ -1596,7 +1702,7 @@ static enum ExtensionError do_extension_KMCTR(ThreadState* tst, ULong variant) /*--- KMO (cypher message with output feedback) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_KMO_insn, 0xb92b) +S390_DEFINE_DO_RR_INSN(do_KMO_insn, 0xb92b, "0") /* Same functions and parameter block sizes as for KMCTR */ static const UChar* const S390_KMO_parms_len = S390_KMCTR_parms_len; @@ -1607,7 +1713,7 @@ static enum ExtensionError do_extension_KMO(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KMO"); + UChar func = READ_FUNCTION_CODE(tst, "KMO", UChar); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMO(r1)", 1); ULong parms_len = 0; @@ -1616,7 +1722,7 @@ static enum ExtensionError do_extension_KMO(ThreadState* tst, ULong variant) ULong addr1 = 0, len1 = 0, addr2 = 0, len2 = 0; if (fc < S390_KMO_parms_len_n) - parms_len = S390_KMO_parms_len[fc]; + parms_len = S390_KMO_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMO: unknown function code\n"); @@ -1625,6 +1731,8 @@ static enum ExtensionError do_extension_KMO(ThreadState* tst, ULong variant) cc = do_KMO_insn(func, parms, &addr1, &len1, &addr2, &len2); s390_filter_functions((ULong*)parms, parms_len, S390_KMO_supported_fc, sizeof(S390_KMO_supported_fc)); + } else if (fc == 127) { // Query authentication information + cc = do_KMO_insn(func, parms, &addr1, &len1, &addr2, &len2); } else { addr1 = orig_addr1 = READ_GPR(tst, "KMO(op1_addr)", r1); addr2 = READ_GPR(tst, "KMO(op2_addr)", r2); @@ -1644,10 +1752,10 @@ static enum ExtensionError do_extension_KMO(ThreadState* tst, ULong variant) } /*---------------------------------------------------------------*/ -/*--- KMF (cypher message with output feedback) ---*/ +/*--- KMF (cypher message with cypher feedback) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_RR_INSN(do_KMF_insn, 0xb92a) +S390_DEFINE_DO_RR_INSN(do_KMF_insn, 0xb92a, "0") /* Same functions and parameter block sizes as for KMCTR */ static const UChar* const S390_KMF_parms_len = S390_KMCTR_parms_len; @@ -1658,7 +1766,7 @@ static enum ExtensionError do_extension_KMF(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; - ULong func = READ_GPR(tst, "KLMD(r0)", 0); + UInt func = READ_FUNCTION_CODE(tst, "KMF", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMF(r1)", 1); ULong parms_len = 0; @@ -1667,7 +1775,7 @@ static enum ExtensionError do_extension_KMF(ThreadState* tst, ULong variant) ULong addr1 = 0, len1 = 0, addr2 = 0, len2 = 0; if (fc < S390_KMF_parms_len_n) - parms_len = S390_KMF_parms_len[fc]; + parms_len = S390_KMF_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMF: unknown function code\n"); @@ -1676,6 +1784,8 @@ static enum ExtensionError do_extension_KMF(ThreadState* tst, ULong variant) cc = do_KMF_insn(func, parms, &addr1, &len1, &addr2, &len2); s390_filter_functions((ULong*)parms, parms_len, S390_KMF_supported_fc, sizeof(S390_KMF_supported_fc)); + } else if (fc == 127) { // Query authentication information + cc = do_KMF_insn(func, parms, &addr1, &len1, &addr2, &len2); } else { addr1 = orig_addr1 = READ_GPR(tst, "KMF(op1_addr)", r1); addr2 = READ_GPR(tst, "KMF(op2_addr)", r2); @@ -1709,22 +1819,28 @@ S390_DEFINE_DO_RRR_INSN(do_KMA_insn, 0xb929) S390_DO_FUNC(27, S390_KMA_GCM_Encrypted_AES_192, 136) \ S390_DO_FUNC(28, S390_KMA_GCM_Encrypted_AES_256, 144) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen, -static const UChar S390_KMA_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(127, S390_KMA_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KMA_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KMA_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KMA_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS +#undef S390_DO_FUNCTIONS1 static enum ExtensionError do_extension_KMA(ThreadState* tst, ULong variant) { UChar r1 = variant & 0xf; UChar r2 = (variant >> 4) & 0xf; UChar r3 = (variant >> 8) & 0xf; - ULong func = READ_GPR(tst, "KMA(gpr0)", 0); + UInt func = READ_FUNCTION_CODE(tst, "KMA(gpr0)", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KMA(r1)", 1); ULong parms_len = 0; @@ -1733,7 +1849,7 @@ static enum ExtensionError do_extension_KMA(ThreadState* tst, ULong variant) ULong addr1 = 0, addr2 = 0, addr3 = 0, len2 = 0, len3 = 0; if (fc < sizeof(S390_KMA_parms_len) / sizeof(S390_KMA_parms_len[0])) - parms_len = S390_KMA_parms_len[fc]; + parms_len = S390_KMA_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KMA: unknown function code\n"); @@ -1743,6 +1859,10 @@ static enum ExtensionError do_extension_KMA(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KMA_supported_fc, sizeof(S390_KMA_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KMA(parms)", parms, parms_len); + cc = do_KMA_insn(func, parms, &addr1, &addr2, &len2, &addr3, &len3); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr1 = orig_addr1 = READ_GPR(tst, "KMA(op1_addr)", r1); addr2 = READ_GPR(tst, "KMA(op2_addr)", r2); @@ -1766,13 +1886,12 @@ static enum ExtensionError do_extension_KMA(ThreadState* tst, ULong variant) } /*---------------------------------------------------------------*/ -/*--- KDSA (compute intermediate message digest) ---*/ +/*--- KDSA (compute digital signature authentication) ---*/ /*---------------------------------------------------------------*/ -S390_DEFINE_DO_0R_INSN(do_KDSA_insn, 0xb93a) +S390_DEFINE_DO_0R_INSN(do_KDSA_insn, 0xb93a, "0") -/* We specify the parameter block size without the CSB here. Also note that - this approach only supports sizes that are a multiple of 8. */ +/* We specify the parameter block size without the CSB here. */ #define S390_DO_FUNCTIONS \ S390_DO_FUNC(0, S390_KDSA_Query, 16) \ S390_DO_FUNC(1, S390_KDSA_ECDSA_Verify_P256, 168) \ @@ -1791,12 +1910,17 @@ S390_DEFINE_DO_0R_INSN(do_KDSA_insn, 0xb93a) S390_DO_FUNC(48, S390_KDSA_Encrypted_EdDSA_Sign_Ed25519, 152) \ S390_DO_FUNC(52, S390_KDSA_Encrypted_EdDSA_Sign_Ed448, 248) -#define S390_DO_FUNC(fc, name, plen) [fc] = plen / 8, -static const UChar S390_KDSA_parms_len[] = {S390_DO_FUNCTIONS}; +#define S390_DO_FUNCTIONS1 \ + S390_DO_FUNC(127, S390_KDSA_Query_Authentication_Information, 256) + +#define S390_DO_FUNC(fc, name, plen) [fc] = S390_WORD_LEN(plen), +static const UChar S390_KDSA_parms_len[] = { + S390_DO_FUNCTIONS S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #define S390_DO_FUNC(fc, name, plen) | S390_SETBIT(fc) -static const ULong S390_KDSA_supported_fc[] = {0 S390_DO_FUNCTIONS}; +static const ULong S390_KDSA_supported_fc[] = {0 S390_DO_FUNCTIONS, + 0 S390_DO_FUNCTIONS1}; #undef S390_DO_FUNC #undef S390_DO_FUNCTIONS @@ -1804,7 +1928,7 @@ static const ULong S390_KDSA_supported_fc[] = {0 S390_DO_FUNCTIONS}; static enum ExtensionError do_extension_KDSA(ThreadState* tst, ULong variant) { UChar r2 = (variant >> 4) & 0xf; - UChar func = READ_FUNCTION_CODE(tst, "KDSA"); + UInt func = READ_FUNCTION_CODE(tst, "KDSA", UInt); UChar fc = func & 0x7f; ULong parms = READ_GPR(tst, "KDSA(r1)", 1); ULong parms_len = 0; @@ -1812,7 +1936,7 @@ static enum ExtensionError do_extension_KDSA(ThreadState* tst, ULong variant) ULong addr2 = 0, len2 = 0; if (fc < sizeof(S390_KDSA_parms_len) / sizeof(S390_KDSA_parms_len[0])) - parms_len = S390_KDSA_parms_len[fc] * 8; + parms_len = S390_KDSA_parms_len[fc] * 4; if (parms_len == 0) return INSN_ERR("KDSA: unknown function code\n"); @@ -1822,6 +1946,10 @@ static enum ExtensionError do_extension_KDSA(ThreadState* tst, ULong variant) s390_filter_functions((ULong*)parms, parms_len, S390_KDSA_supported_fc, sizeof(S390_KDSA_supported_fc)); POST_MEM_WRITE(tst, parms, parms_len); + } else if (fc == 127) { // Query authentication information + PRE_MEM_WRITE(tst, "KDSA(parms)", parms, parms_len); + cc = do_KDSA_insn(func, parms, &addr2, &len2); + POST_MEM_WRITE(tst, parms, parms_len); } else { addr2 = READ_GPR(tst, "KDSA(op2_addr)", r2); len2 = READ_GPR(tst, "KDSA(op2_len)", r2 + 1); diff --git a/coregrind/m_initimg/initimg-darwin.c b/coregrind/m_initimg/initimg-darwin.c index d4452fd9d5..e998c0a777 100644 --- a/coregrind/m_initimg/initimg-darwin.c +++ b/coregrind/m_initimg/initimg-darwin.c @@ -43,12 +43,42 @@ #include "pub_core_mallocfree.h" #include "pub_core_machine.h" #include "pub_core_ume.h" +#include "pub_core_mach.h" #include "pub_core_options.h" #include "pub_core_tooliface.h" /* VG_TRACK */ #include "pub_core_threadstate.h" /* ThreadArchState */ #include "pub_core_pathscan.h" /* find_executable */ #include "pub_core_initimg.h" /* self */ +// change this to one to see the env/apple pointer area that Darwin gives us +// and also the env and apple pointer area that we pass on to the guest +#define DEBUG_ENV_APPLE 0 + +#if (DEBUG_ENV_APPLE) +static void print_env_apple(HChar** envp, const HChar* where) +{ + int i; + int j; + HChar** apple; + VG_(printf)("Start env and apple pointer strings at %s\n", where); + + for (i = 0; envp[i]; ++i) { + VG_(printf)("initimg-darwin: i %d &envp[i] %p envp[i] %s\n", i, &envp[i], envp[i]); + } + // should be NULL + VG_(printf)("initimg-darwin: i %d &envp[i] %p envp[i] %s\n", i, &envp[i], envp[i]); + + apple = &envp[i]; + ++apple; + + for (j = 0; apple[j]; ++j) { + VG_(printf)("initimg-darwin: j %d &apple[j] %p apple[j] %s\n", j, &apple[j], apple[j]); + } + VG_(printf)("initimg-darwin: j %d &apple[j] %p apple[j] %s\n", j, &apple[j], apple[j]); + VG_(printf)("End env and apple pointer strings at %s\n", where); +} +#endif + /*====================================================================*/ /*=== Loading the client ===*/ @@ -63,6 +93,7 @@ static void load_client ( /*OUT*/ExeInfo* info, Int ret; vg_assert( VG_(args_the_exename) != NULL); + vg_assert( VG_(strlen)(VG_(args_the_exename)) >= 1 ); exe_name = VG_(find_executable)( VG_(args_the_exename) ); if (!exe_name) { @@ -72,6 +103,10 @@ static void load_client ( /*OUT*/ExeInfo* info, VG_(memset)(info, 0, sizeof(*info)); ret = VG_(do_exec)(exe_name, info); + if (ret < 0) { + VG_(printf)("valgrind: could not execute '%s'\n", exe_name); + VG_(exit)(1); + } // The client was successfully loaded! Continue. @@ -96,8 +131,31 @@ static void load_client ( /*OUT*/ExeInfo* info, Also, remove any binding for VALGRIND_LAUNCHER=. The client should not be able to see this. - Also, add DYLD_SHARED_REGION=avoid, because V doesn't know how - to process the dyld shared cache file. + There are up to three other environment variables that we need to + add or modify. + + PTHREAD_PTR_MUNGE_TOKEN: This is used by libc/libpthread to obfuscate + some saved context registers. + FIXME PJF - if we correctly propagate the apple parameter ptr_munge + would we still need this env var? + + DYLD_SHARED_REGION: Darwin switched to dematerialising system libraries. + On some versions of Darwin this environment variable can be used + with a value of 'avoid' to force using the physical libraries on disk. + Later versions removed the physical library files so we can + no longer use this option with 'avoid' and we need to start processing + the dyld shared cache file. Darwin 20 and 21 seem to work OK + without needing DYLD_SHARED_REGION. Darwin 22 does need it to be + set explicitly to 'use' even though that is the default. + + DYLD_INSERT_LIBRARIES: V uses this to preload its core and tool + shared libraries. + + The following macOS versions have the following requirements + All versions: DYLD_INSERT_LIBRARIES + DARWIN_VERS >= DARWIN_10_15 PTHREAD_PTR_MUNGE_TOKEN + DARWIN_VERS < DARWIN_11_00 DYLD_SHARED_REGION=avoid + DARWIN_VERS >= DARWIN_11_00 DYLD_SHARED_REGION=use Also, change VYLD_* (mangled by launcher) back to DYLD_*. @@ -109,13 +167,21 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) const HChar* preload_core = "vgpreload_core"; const HChar* ld_preload = "DYLD_INSERT_LIBRARIES="; const HChar* dyld_cache = "DYLD_SHARED_REGION="; +#if DARWIN_VERS < DARWIN_11_00 const HChar* dyld_cache_value= "avoid"; +#else + const HChar* dyld_cache_value= "use"; +#endif + Int dyld_cache_len = VG_(strlen)( dyld_cache ); + Bool dyld_cache_done = False; +#if DARWIN_VERS >= DARWIN_10_15 + Bool pthread_ptr_munge_token_present = False; +#endif const HChar* v_launcher = VALGRIND_LAUNCHER "="; + Int extra_env_vars; Int ld_preload_len = VG_(strlen)( ld_preload ); - Int dyld_cache_len = VG_(strlen)( dyld_cache ); Int v_launcher_len = VG_(strlen)( v_launcher ); Bool ld_preload_done = False; - Bool dyld_cache_done = False; Int vglib_len = VG_(strlen)(VG_(libdir)); HChar** cpp; @@ -123,6 +189,13 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) HChar* preload_tool_path; Int envc, i; + // number of env vars to add if not already present +#if DARWIN_VERS < DARWIN_10_15 + extra_env_vars = 2; // DYLD_INSERT_LIBRARIES and DYLD_SHARED_REGION +#else + extra_env_vars = 3; // DYLD_INSERT_LIBRARIES, DYLD_SHARED_REGION and PTHREAD_PTR_MUNGE_TOKEN +#endif + /* Alloc space for the vgpreload_core.so path and vgpreload_.so paths. We might not need the space for vgpreload_.so, but it doesn't hurt to over-allocate briefly. The 16s are just cautious @@ -153,12 +226,28 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) /* Count the original size of the env */ envc = 0; - for (cpp = origenv; cpp && *cpp; cpp++) + for (cpp = origenv; cpp && *cpp; cpp++) { + if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) { + --extra_env_vars; + } + if (VG_(memcmp)(*cpp, dyld_cache, dyld_cache_len) == 0) { + --extra_env_vars; + } +#if DARWIN_VERS >= DARWIN_10_15 + // strictly would should check for presence and that it is not set to zero + if (VG_(memcmp)(*cpp, "PTHREAD_PTR_MUNGE_TOKEN=", VG_(strlen)("PTHREAD_PTR_MUNGE_TOKEN=")) == 0) { + --extra_env_vars; + pthread_ptr_munge_token_present = True; + } +#endif envc++; + } + + vg_assert(extra_env_vars >= 0); /* Allocate a new space */ ret = VG_(malloc) ("initimg-darwin.sce.3", - sizeof(HChar *) * (envc+2+1)); /* 2 new entries + NULL */ + sizeof(HChar *) * (envc+extra_env_vars+1)); /* 1 to 3 new entries + NULL */ /* copy it over */ for (cpp = ret; *origenv; ) @@ -188,7 +277,7 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) *cpp = cp; - ld_preload_done = True; + dyld_cache_done = True; } } @@ -209,7 +298,12 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) ret[envc++] = cp; } - +#if DARWIN_VERS >= DARWIN_10_15 + // pthread really wants a non-zero value for ptr_munge + if (!pthread_ptr_munge_token_present) { + ret[envc++] = VG_(strdup)("initimg-darwin.sce.6", "PTHREAD_PTR_MUNGE_TOKEN=0x00000001"); + } +#endif /* ret[0 .. envc-1] is live now. */ /* Find and remove a binding for VALGRIND_LAUNCHER. */ @@ -230,7 +324,6 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) } } - VG_(free)(preload_string); ret[envc] = NULL; return ret; @@ -298,7 +391,7 @@ static HChar *copy_str(HChar **tab, const HChar *str) static Addr setup_client_stack( void* init_sp, - HChar** orig_envp, + HChar** envp, const ExeInfo* info, Addr clstack_end, SizeT clstack_max_size, @@ -338,6 +431,9 @@ Addr setup_client_stack( void* init_sp, stringsize += VG_(strlen)(info->interp_args) + 1; } + vg_assert( VG_(args_the_exename) ); + vg_assert( VG_(strlen)( VG_(args_the_exename) ) >= 1 ); + /* now scan the args we're given... */ stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; @@ -350,40 +446,60 @@ Addr setup_client_stack( void* init_sp, /* ...and the environment */ envc = 0; - for (cpp = orig_envp; cpp && *cpp; cpp++) { + for (cpp = envp; cpp && *cpp; cpp++) { envc++; stringsize += VG_(strlen)(*cpp) + 1; } - /* Darwin executable_path + NULL */ - auxsize += 2 * sizeof(Word); + /* NULL separator and executable path */ + auxsize += 2 * sizeof(HChar **); if (info->executable_path) { stringsize += 1 + VG_(strlen)(info->executable_path); +#if SDK_VERS >= SDK_10_14_6 + stringsize += 16; // executable_path= +#endif } +#if defined(VGA_arm64) + // This is required so that dyld can load our dylib specified in DYLD_INSERT_LIBRARIES +#define EXTRA_APPLE_ARG "arm64e_abi=all" + stringsize += VG_(strlen)(EXTRA_APPLE_ARG) + 1; + auxsize += sizeof(Word); +#endif + /* Darwin mach_header */ - if (info->dynamic) auxsize += sizeof(Word); + if (info->dynamic) + auxsize += sizeof(Word); /* OK, now we know how big the client stack is */ stacksize = sizeof(Word) + /* argc */ - sizeof(HChar **) + /* argc[0] == exename */ - sizeof(HChar **)*argc + /* argv */ + sizeof(HChar **) + /* argv[0] == exename */ + sizeof(HChar **)*argc + /* argv guest args */ sizeof(HChar **) + /* terminal NULL */ sizeof(HChar **)*envc + /* envp */ sizeof(HChar **) + /* terminal NULL */ auxsize + /* auxv */ - VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ + VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (Word aligned) */ - if (0) VG_(printf)("stacksize = %d\n", stacksize); + /* The stacksize will be rounded to 16. Any rounding could come from a combination of + rounding up stringsize to a multiple of sizeof(Word) plus rounding of the whole + from a multiple of sizeof(Word) to a multiple of 16. Need to keep both of these + in order to calculate stringbase. */ + size_t pointer_slop = VG_ROUNDUP(stacksize, 16) - stacksize; + stacksize = VG_ROUNDUP(stacksize, 16); + + if (0) VG_(printf)("stacksize = %u\n", stacksize); /* client_SP is the client's stack pointer */ + vg_assert(stacksize % 16 == 0); + vg_assert((clstack_end + 1) % 16 == 0); client_SP = clstack_end + 1 - stacksize; - client_SP = VG_ROUNDDN(client_SP, 32); /* make stack 32 byte aligned */ + vg_assert(client_SP % 16 == 0); /* base of the string table (aligned) */ - stringbase = strtab = (HChar *)clstack_end - - VG_ROUNDUP(stringsize, sizeof(int)); + stringbase = strtab = (HChar *)clstack_end + 1 - VG_ROUNDUP(stringsize, sizeof(Word)) - pointer_slop; + vg_assert((Addr)stringbase % sizeof(Word) == 0); /* The max stack size */ clstack_max_size = VG_PGROUNDUP(clstack_max_size); @@ -397,10 +513,10 @@ Addr setup_client_stack( void* init_sp, VG_(clstk_end) = clstack_end; if (0) - VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n" + VG_(printf)("stringsize=%u auxsize=%u stacksize=%u maxsize=0x%x\n" "clstack_start %p\n" "clstack_end %p\n", - stringsize, auxsize, stacksize, (Int)clstack_max_size, + stringsize, auxsize, stacksize, (UInt)clstack_max_size, (void*)clstack_start, (void*)clstack_end); /* ==================== allocate space ==================== */ @@ -412,7 +528,8 @@ Addr setup_client_stack( void* init_sp, ptr = (Addr*)client_SP; /* --- mach_header --- */ - if (info->dynamic) *ptr++ = info->text; + if (info->dynamic) + *ptr++ = info->text; /* --- client argc --- */ *ptr++ = (Addr)(argc + 1); @@ -435,19 +552,35 @@ Addr setup_client_stack( void* init_sp, /* --- envp --- */ VG_(client_envp) = (HChar **)ptr; - for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) + for (cpp = envp; cpp && *cpp; ptr++, cpp++) *ptr = (Addr)copy_str(&strtab, *cpp); *ptr++ = 0; - /* --- executable_path + NULL --- */ - if (info->executable_path) - *ptr++ = (Addr)copy_str(&strtab, info->executable_path); - else - *ptr++ = 0; + /* --- executable_path --- */ + vg_assert(info->executable_path); +#if SDK_VERS >= SDK_10_14_6 + Int executable_path_len = VG_(strlen)(info->executable_path) + 16 + 1; + HChar *executable_path = VG_(malloc)("initimg-darwin.scs.1", executable_path_len); + VG_(snprintf)(executable_path, executable_path_len, "executable_path=%s", info->executable_path); + *ptr++ = (Addr)copy_str(&strtab, executable_path); + VG_(free)(executable_path); +#else + *ptr++ = (Addr)copy_str(&strtab, info->executable_path); +#endif + +#if defined(VGA_arm64) + *ptr++ = (Addr)copy_str(&strtab, EXTRA_APPLE_ARG); +#endif + *ptr++ = 0; vg_assert((strtab-stringbase) == stringsize); +#if (DEBUG_ENV_APPLE) + VG_(printf)("initimg-darwin: ptr %p stringbase %p\n", ptr, stringbase); +#endif + vg_assert((HChar*)ptr == stringbase); + if (VG_(resolved_exename) == NULL) { const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename)); HChar interp_name[VKI_PATH_MAX]; @@ -455,10 +588,19 @@ Addr setup_client_stack( void* init_sp, exe_name = interp_name; } HChar resolved_name[VKI_PATH_MAX]; - VG_(realpath)(exe_name, resolved_name); - VG_(resolved_exename) = VG_(strdup)("initimg-darwin.sre.1", resolved_name); + if (VG_(realpath)(exe_name, resolved_name)) { + VG_(resolved_exename) = VG_(strdup)("initimg-darwin.scs.2", resolved_name); + } else { + /* This should not really happen. realpath tried and failed. + So lets just continue with the exe_name as is. */ + VG_(resolved_exename) = VG_(strdup)("initimg-darwin.scs.3", exe_name); + } } +#if (DEBUG_ENV_APPLE) + print_env_apple(VG_(client_envp), "final envp"); +#endif + /* client_SP is pointing at client's argc/argv */ if (0) VG_(printf)("startup SP = %#lx\n", client_SP); @@ -470,6 +612,38 @@ Addr setup_client_stack( void* init_sp, /*=== Record system memory regions ===*/ /*====================================================================*/ +void VG_(mach_record_system_memory)(void) { + /* Darwin only: tell the tools where the client's kernel commpage + is. It would be better to do this by telling aspacemgr about + it -- see the now disused record_system_memory() below -- + but that causes the sync checker to fail, + since the mapping doesn't appear in the kernel-supplied + process map. So do it here instead. */ + +#if defined(VGA_amd64) + VG_TRACK( new_mem_startup, + 0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000, + True, False, True, /* r-x */ + 0 /* di_handle: no associated debug info */ ); +#elif defined(VGA_x86) + VG_TRACK( new_mem_startup, + 0xfffec000, 0xfffff000-0xfffec000, + True, False, True, /* r-x */ + 0 /* di_handle: no associated debug info */ ); +#elif defined(VGA_arm64) + VG_TRACK( new_mem_startup, + 0xfffff4000, 0x1000, + True, False, True, /* r-- */ + 0 /* di_handle: no associated debug info */ ); + VG_TRACK( new_mem_startup, + 0xfffffc000, 0x1000, + True, False, True, /* r-x */ + 0 /* di_handle: no associated debug info */ ); +#else +# error "Unknown Darwin architecture" +#endif +} + static void record_system_memory(void) { /* JRS 2014-Jul-08: this messes up the sync checker, because the @@ -528,6 +702,10 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, load_client(&info, &iifii.initial_client_IP); +#if (DEBUG_ENV_APPLE) + print_env_apple(iicii.envp, "original envp"); +#endif + //-------------------------------------------------------------- // Set up client's environment // p: set-libdir [for VG_(libdir)] @@ -629,3 +807,4 @@ void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ + diff --git a/coregrind/m_initimg/initimg-freebsd.c b/coregrind/m_initimg/initimg-freebsd.c index 874d129f62..cccaf58252 100644 --- a/coregrind/m_initimg/initimg-freebsd.c +++ b/coregrind/m_initimg/initimg-freebsd.c @@ -10,7 +10,7 @@ Copyright (C) 2000-2009 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -410,7 +410,6 @@ static Addr setup_client_stack(const void* init_sp, Addr client_SP; /* client stack base (initial SP) */ Addr clstack_start; /* client_SP rounded down to nearest page */ Int i; - Bool have_exename; Word client_argv; vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1)); @@ -422,7 +421,11 @@ static Addr setup_client_stack(const void* init_sp, exe_name = interp_name; } HChar resolved_name[VKI_PATH_MAX]; - VG_(realpath)(exe_name, resolved_name); + if (!VG_(realpath)(exe_name, resolved_name)) { + /* This should not really happen. realpath tried and failed. + So lets just continue with the exe_name as is. */ + VG_(strcpy)(resolved_name, exe_name); + } /* use our own auxv as a prototype */ orig_auxv = find_auxv(init_sp); @@ -431,7 +434,6 @@ static Addr setup_client_stack(const void* init_sp, /* first of all, work out how big the client stack will be */ stringsize = 0; - have_exename = VG_(args_the_exename) != NULL; /* paste on the extra args if the loader needs them (ie, the #! interpreter and its argument) */ @@ -446,9 +448,7 @@ static Addr setup_client_stack(const void* init_sp, } /* now scan the args we're given... */ - if (have_exename) { - stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; - } + stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { argc++; @@ -477,17 +477,14 @@ static Addr setup_client_stack(const void* init_sp, break; case VKI_AT_CANARYLEN: canarylen = cauxv->u.a_val; - /*VG_ROUNDUP(stringsize, sizeof(Word));*/ stringsize += canarylen; break; case VKI_AT_PAGESIZESLEN: pagesizeslen = cauxv->u.a_val; - /*VG_ROUNDUP(stringsize, sizeof(Word));*/ stringsize += pagesizeslen; break; #if 0 case VKI_AT_TIMEKEEP: - /*VG_ROUNDUP(stringsize, sizeof(Word));*/ stringsize += sizeof(struct vki_vdso_timehands); break; #endif @@ -506,7 +503,7 @@ static Addr setup_client_stack(const void* init_sp, /* OK, now we know how big the client stack is */ used_stacksize = sizeof(Word) + /* argc */ - (have_exename ? sizeof(HChar **) : 0) + /* argc[0] == exename */ + sizeof(HChar **) + /* argc[0] == exename */ sizeof(HChar **)*argc + /* argv */ sizeof(HChar **) + /* terminal NULL */ sizeof(HChar **)*envc + /* envp */ @@ -523,7 +520,7 @@ static Addr setup_client_stack(const void* init_sp, client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */ /* base of the string table (aligned) */ - stringbase = strtab = (HChar *)clstack_end + stringbase = strtab = (HChar *)clstack_end + 1 - VG_ROUNDUP(stringsize, sizeof(int)); clstack_start = VG_PGROUNDDN(client_SP); @@ -545,7 +542,7 @@ static Addr setup_client_stack(const void* init_sp, higher address +-----------------+ <- clstack_end ^ ^ | args env auxv | | | | see above | | | - ower address +-----------------+ <- client_SP anon_size | + lower address +-----------------+ <- client_SP anon_size | | round to page | | | +-----------------+ <- clstack_start | | | one page | | clstack_max_size @@ -555,6 +552,10 @@ static Addr setup_client_stack(const void* init_sp, : : | | +-----------------+ <- resvn_start v v +(The "one page" below clstack_start is only present when VG_STACK_REDZONE_SZB +is not zero, which for FreeBSD is only on amd64. This page is not present +on other platforms.) + */ { @@ -641,7 +642,7 @@ static Addr setup_client_stack(const void* init_sp, ptr = (Addr*)client_SP; /* --- client argc --- */ - *ptr++ = argc + (have_exename ? 1 : 0); + *ptr++ = argc + 1; /* --- client argv --- */ client_argv = (Word)ptr; @@ -652,9 +653,7 @@ static Addr setup_client_stack(const void* init_sp, *ptr++ = (Addr)copy_str(&strtab, info->interp_args); } - if (have_exename) { - *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); - } + *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { *ptr++ = (Addr)copy_str( @@ -850,6 +849,8 @@ static Addr setup_client_stack(const void* init_sp, vg_assert((strtab-stringbase) == stringsize); + vg_assert((HChar*)auxv < stringbase); + /* client_SP is pointing at client's argc/argv */ if (0) { @@ -857,7 +858,7 @@ static Addr setup_client_stack(const void* init_sp, } if (VG_(resolved_exename) == NULL) { - VG_(resolved_exename) = VG_(strdup)("initimg-freebsd.sre.1", resolved_name); + VG_(resolved_exename) = VG_(strdup)("initimg-freebsd.scs.1", resolved_name); } return client_SP; diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 5477075555..acda16dda1 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -960,8 +960,13 @@ Addr setup_client_stack( void* init_sp, exe_name = interp_name; } HChar resolved_name[VKI_PATH_MAX]; - VG_(realpath)(exe_name, resolved_name); - VG_(resolved_exename) = VG_(strdup)("initimg-linux.sre.1", resolved_name); + if (VG_(realpath)(exe_name, resolved_name)) { + VG_(resolved_exename) = VG_(strdup)("initimg-linux.scs.1", resolved_name); + } else { + /* This should not really happen. realpath tried and failed. + So lets just continue with the exe_name as is. */ + VG_(resolved_exename) = VG_(strdup)("initimg-linux.scs.2", exe_name); + } } /* client_SP is pointing at client's argc/argv */ diff --git a/coregrind/m_initimg/initimg-solaris.c b/coregrind/m_initimg/initimg-solaris.c index 79072f3a85..1c6cd323e9 100644 --- a/coregrind/m_initimg/initimg-solaris.c +++ b/coregrind/m_initimg/initimg-solaris.c @@ -94,6 +94,20 @@ static void load_client(/*OUT*/ExeInfo *info, /*NOTREACHED*/ } VG_(strcpy)(out_exe_name, exe_name); + if (VG_(resolved_exename) == NULL) { + HChar interp_name[VKI_PATH_MAX]; + if (VG_(try_get_interp)(exe_name, interp_name, VKI_PATH_MAX)) { + exe_name = interp_name; + } + HChar resolved_name[VKI_PATH_MAX]; + if (VG_(realpath)(exe_name, resolved_name)) { + VG_(resolved_exename) = VG_(strdup)("initimg-solaris.lc.1", resolved_name); + } else { + /* This should not really happen. realpath tried and failed. + So lets just continue with the exe_name as is. */ + VG_(resolved_exename) = VG_(strdup)("initimg-solaris.lc.2", exe_name); + } + } /* Set initial brk values. */ if (info->ldsoexec) { @@ -485,11 +499,6 @@ static Addr setup_client_stack(Addr init_sp, /* Calculate the max stack size. */ clstack_max_size = VG_PGROUNDUP(clstack_max_size); - /* Record stack extent -- needed for stack-change code. */ - VG_(clstk_start_base) = clstack_start; - VG_(clstk_end) = clstack_end; - VG_(clstk_max_size) = clstack_max_size; - if (0) VG_(printf)("stringsize=%lu, auxsize=%lu, stacksize=%lu, maxsize=%#lx\n" "clstack_start %#lx\n" @@ -562,6 +571,14 @@ static Addr setup_client_stack(Addr init_sp, VG_(exit)(1); /*NOTREACHED*/ } + + /* Record stack extent -- needed for stack-change code. */ + VG_(clstk_start_base) = anon_start -inner_HACK; + VG_(clstk_end) = VG_(clstk_start_base) + anon_size +inner_HACK -1; + // Only Solaris sets this despite a comment in syswrap-generic.c + // that all platforms should set it. + VG_(clstk_max_size) = clstack_max_size; + } /* ==================== create client stack ==================== */ diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c index 5859912496..e757aa59e1 100644 --- a/coregrind/m_libcassert.c +++ b/coregrind/m_libcassert.c @@ -27,6 +27,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuglog.h" #include "pub_core_vki.h" #include "pub_core_vkiscnums.h" #include "pub_core_threadstate.h" @@ -499,6 +500,10 @@ static void report_and_quit ( const HChar* report, False, // exited_threads startRegsIN); + if (VG_(debugLog_getLevel)() > 0) { + VG_(am_show_nsegments) (1, "report_and_quit"); + (void) VG_(am_do_sync_check) ("report_and_quit", __FILE__, __LINE__); + } if (VG_(clo_xml)) // After flushing outputs VG_(printf_xml)("\n"); diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index e28ac15309..87af033150 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -712,12 +712,16 @@ struct vki_stat buf; res = VG_(do_syscall4)(__NR_fstatat, VKI_AT_FDCWD, (UWord)file_name, (UWord)&buf, VKI_AT_SYMLINK_NOFOLLOW); #endif -#else +#elif defined(VGO_darwin) /* check this on Darwin */ struct vki_stat buf; res = VG_(do_syscall2)(__NR_lstat, (UWord)file_name, (UWord)&buf); +#else + +#error Unknown OS + #endif if (!sr_isError(res)) { @@ -805,7 +809,6 @@ Int VG_(fcntl) ( Int fd, Int cmd, Addr arg ) # error "Unknown OS" # endif if (sr_isError(res)) { - VG_(debugLog)(1, "VG_(fcntl)", "fcntl error %lu %s\n", sr_Err(res), VG_(strerror)(sr_Err(res))); return -1; } return (Int)sr_Res(res); @@ -1464,10 +1467,9 @@ Int VG_(socket) ( Int domain, Int type, Int protocol ) if (!sr_isError(res)) { // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE Int optval = 1; - SysRes res2; - res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET, - VKI_SO_NOSIGPIPE, (UWord)&optval, - sizeof(optval)); + (void)VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET, + VKI_SO_NOSIGPIPE, (UWord)&optval, + sizeof(optval)); // ignore setsockopt() error } return sr_isError(res) ? -1 : sr_Res(res); @@ -1867,7 +1869,9 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved) } if (VKI_S_ISLNK(statbuf.mode)) { - SizeT link_len = VG_(readlink)(path, tmp, VKI_PATH_MAX); + SSizeT link_len = VG_(readlink)(path, tmp, VKI_PATH_MAX); + if (link_len < 0) + return False; tmp[link_len] = '\0'; resolved_name = tmp; } else { @@ -1886,6 +1890,9 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved) #elif defined(VGO_freebsd) res = VG_(do_syscall2)(__NR___getcwd, (UWord)wd, VKI_PATH_MAX); #endif + if (sr_isError(res)) { + return False; + } VG_(snprintf)(resolved, VKI_PATH_MAX, "%s/%s", wd, resolved_name); } else { VG_(snprintf)(resolved, VKI_PATH_MAX, "%s", resolved_name); diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c index 7c4d6acc9d..4c4b96eefb 100644 --- a/coregrind/m_libcproc.c +++ b/coregrind/m_libcproc.c @@ -1052,7 +1052,15 @@ UInt VG_(read_millisecond_timer) ( void ) struct vki_timeval tv_now = { 0, 0 }; res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL); vg_assert(! sr_isError(res)); +# if DARWIN_VERS >= DARWIN_10_13 + now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec; +# else + // Weird: it seems that gettimeofday() doesn't fill in the timeval, but + // rather returns the tv_sec as the low 32 bits of the result and the + // tv_usec as the high 32 bits of the result. (But the timeval cannot be + // NULL!) See bug 200990. now = sr_Res(res) * 1000000ULL + sr_ResHI(res); +#endif } # else diff --git a/coregrind/m_libcsignal.c b/coregrind/m_libcsignal.c index d8563a4d02..d28b0b9b21 100644 --- a/coregrind/m_libcsignal.c +++ b/coregrind/m_libcsignal.c @@ -240,19 +240,29 @@ Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset) #if defined(VGO_darwin) /* A helper function for sigaction on Darwin. */ -static -void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) { +static +void darwin_signal_demux(void* catcher, UWord infostyle, UWord sig, void* sinfo, void* uctx +# if defined(VGA_arm64) +, void* token +# endif +) { VG_(debugLog)(2, "libcsignal", - "PRE demux sig, a2 = %lu, signo = %lu\n", a2, a3); - if (a2 == 1) - ((void(*)(int))a1) (a3); + "PRE demux sig, infostyle = %s, signo = %lu\n", infostyle == VKI_UC_TRAD ? "TRAD" : "FLAVOR", sig); + if (infostyle == VKI_UC_TRAD) + ((void(*)(int))catcher) (sig); else - ((void(*)(int,void*,void*))a1) (a3,a4,a5); + ((void(*)(int,void*,void*))catcher) (sig, sinfo, uctx); VG_(debugLog)(2, "libcsignal", - "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3); - VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E); + "POST demux sig, infostyle = %s, signo = %lu\n", infostyle == VKI_UC_TRAD ? "TRAD" : "FLAVOR", sig); +# if defined(VGA_arm64) + VG_(do_syscall3)(__NR_sigreturn, (UWord)uctx, VKI_UC_FLAVOR, (UWord)token); + /* NOTREACHED */ + __asm__ __volatile__("udf #0"); +# else + VG_(do_syscall2)(__NR_sigreturn, (UWord)uctx, VKI_UC_FLAVOR); /* NOTREACHED */ __asm__ __volatile__("ud2"); +# endif } #endif diff --git a/coregrind/m_mach/dyld_cache.c b/coregrind/m_mach/dyld_cache.c new file mode 100644 index 0000000000..6257807004 --- /dev/null +++ b/coregrind/m_mach/dyld_cache.c @@ -0,0 +1,506 @@ + +/*--------------------------------------------------------------------*/ +/*--- DYLD Cache dyld_cache.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (c) 2020-2025 Louis Brunner + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "config.h" // for DARWIN_VERS + +// While dyld_caching as existed for longer than that +// we have used DYLD_SHARED_REGION=avoid in the past +// +// Starting with macOS 11 (Big Sur), it isn't an option anymore +// as some dylib are not provided in file format anymore +#if defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_11_00) + +#include "pub_core_debuginfo.h" // VG_(di_notify_dsc) +#include "pub_core_debuglog.h" // VG_(debugLog) +#include "pub_core_mach.h" // VG_(dyld_cache_*) +#include "pub_core_syscall.h" // VG_(do_syscall1) +#include "pub_core_libcbase.h" // VG_(strncmp) +#include "pub_core_libcprint.h" // VG_(dmsg) +#include "pub_core_libcfile.h" // VG_(stat) +#include "vki/vki-scnums-darwin.h" // __NR_shared_region_check_np +#include "priv_dyld_internals.h" // CACHE_MAGIC_*, dyld_cache_header, etc + +// Required by private headers underneath +#include "pub_core_libcassert.h" // vg_assert +#include "pub_core_threadstate.h" // ThreadState + +// FIXME: probably shouldn't include this directly? +#include "m_syswrap/priv_syswrap-generic.h" // ML_(notify_core_and_tool_of_mmap) + +#include +#include + +// Only supported on macOS 11 onwards which is 64bit only +# define MACH_HEADER mach_header_64 +# define MAGIC MH_MAGIC_64 + +static void output_text_debug_info(const dyld_cache_image_text_info* textInfo); +static void output_debug_info(const dyld_cache_header* dyld_cache); + +typedef struct { + const dyld_cache_header* header; + Addr slide; + Bool tried; +} DYLDCache; + +static DYLDCache dyld_cache = { + .header = NULL, + .slide = 0, + .tried = False, +}; + +static Addr calculate_relative(const dyld_cache_header * header, Addr offset) { + return (Addr)header + offset; +} + +static Addr calculate_unslid(Addr addr) { + return addr + dyld_cache.slide; +} + +static int try_to_init_header(Addr address) { + const dyld_cache_header* header = (const dyld_cache_header *) address; + + if ( +#if defined(VGA_amd64) + VG_(strcmp)(header->magic, CACHE_MAGIC_x86_64) != 0 + && VG_(strcmp)(header->magic, CACHE_MAGIC_x86_64_HASWELL) != 0 +#elif defined(VGA_arm64) + VG_(strcmp)(header->magic, CACHE_MAGIC_arm64) != 0 + && VG_(strcmp)(header->magic, CACHE_MAGIC_arm64e) != 0 +#else + 0 +#error "unknown architecture" +#endif + ) { + VG_(debugLog)(2, "dyld_cache", "ERROR: incompatible shared dyld cache (%s)\n", header->magic); + return 0; + } + + if (header->mappingCount < 1) { + VG_(debugLog)(2, "dyld_cache", "ERROR: no mappings in the dyld cache\n"); + return 0; + } + + VG_(debugLog)(2, "dyld_cache", "shared dyld cache format: %d / %#x\n", header->formatVersion, header->mappingOffset); + output_debug_info(header); + + const dyld_cache_mapping_info* mappings = (const dyld_cache_mapping_info*)(calculate_relative(header, header->mappingOffset)); + for (int i = 0; i < header->mappingCount; ++i) { + const dyld_cache_mapping_info* mapping = &mappings[i]; + Addr map_addr = calculate_unslid(mapping->address); + VG_(debugLog)(5, "dyld_cache", + "mapping[%d]{\n" + " .address: %#lx,\n" + " .size: %llu (%#llx),\n" + " .fileOffset: %#lx,\n" + " .maxProt: %#x,\n" + " .initProt: %#x,\n" + "}\n", + i, + map_addr, + mapping->size, + mapping->size, + calculate_relative(header, mapping->fileOffset), + mapping->maxProt, + mapping->initProt + ); + ML_(notify_core_and_tool_of_mmap)(map_addr, mapping->size, mapping->initProt, VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS, -1, 0); + } + + if (dyld_cache.header->mappingOffset >= __offsetof(dyld_cache_header, dynamicDataMaxSize) && header->dynamicDataMaxSize > 0) { + ML_(notify_core_and_tool_of_mmap)(calculate_relative(header, header->dynamicDataOffset), header->dynamicDataMaxSize, VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS, -1, 0); + } + + return 1; +} + +static int try_to_init(void) { + // Read address of the shared cache which is mapped in our address space + // and tell Valgrind about it so we avoid false-positives and massive suppression files + { + Addr cache_address; + if (sr_Res(VG_(do_syscall1)(__NR_shared_region_check_np, (UWord)&cache_address)) != 0) { + VG_(debugLog)(2, "dyld_cache", "ERROR: could not get shared dyld cache address\n"); + return 0; + } + VG_(debugLog)(2, "dyld_cache", "shared dyld cache found: %#lx\n", cache_address); + + // FIXME: should be after `try_to_init_header` but we also need the slide calculate _before_ + dyld_cache.header = (const dyld_cache_header *) cache_address; + const dyld_cache_mapping_info* mappings = (const dyld_cache_mapping_info*)(calculate_relative(dyld_cache.header, dyld_cache.header->mappingOffset)); + dyld_cache.slide = cache_address - mappings[0].address; + VG_(debugLog)(2, "dyld_cache", "dyld cache slide: %#lx\n", dyld_cache.slide); + + if (!try_to_init_header(cache_address)) { + return 0; + } + + if (dyld_cache.header->mappingOffset >= __offsetof(dyld_cache_header, subCacheArrayCount)) { + Bool sub_cache_v2 = dyld_cache.header->mappingOffset > __offsetof(dyld_cache_header, cacheSubType); + Addr sub_caches = calculate_relative(dyld_cache.header, dyld_cache.header->subCacheArrayOffset); + + for (int i = 0; i < dyld_cache.header->subCacheArrayCount; ++i) { + Addr sub_cache_addr; + + VG_(debugLog)(2, "dyld_cache", "found sub cache %d (v2: %d)\n", i, sub_cache_v2); + + if (sub_cache_v2) { + const dyld_subcache_entry* sub_cache = &((const dyld_subcache_entry*) sub_caches)[i]; + const uint8_t* u = sub_cache->uuid; + sub_cache_addr = calculate_relative(dyld_cache.header, sub_cache->cacheVMOffset); + VG_(debugLog)(5, "dyld_cache", + "sub_cache_v2[%d]{\n" + " .uuid: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x,\n" + " .cacheVMOffset: %#lx,\n" + " .fileSuffix: %s,\n" + "}\n", + i, + u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15], + sub_cache_addr, + sub_cache->fileSuffix + ); + + } else { + const dyld_subcache_entry_v1* sub_cache = &((const dyld_subcache_entry_v1*) sub_caches)[i]; + const uint8_t* u = sub_cache->uuid; + sub_cache_addr = calculate_relative(dyld_cache.header, sub_cache->cacheVMOffset); + VG_(debugLog)(5, "dyld_cache", + "sub_cache_v1[%d]{\n" + " .uuid: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x,\n" + " .cacheVMOffset: %#lx,\n" + "}\n", + i, + u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15], + sub_cache_addr + ); + } + + if (!try_to_init_header(sub_cache_addr)) { + return 0; + } + } + } + } + + return 1; +} + +Addr VG_(dyld_cache_get_slide)(void) { + return dyld_cache.slide; +} + +static int ensure_init(void) { + if (dyld_cache.header != NULL) { + return 1; + } + + // FIXME: unlikely race condition? + if (dyld_cache.tried) { + return 0; + } + dyld_cache.tried = True; + + if (!try_to_init()) { + VG_(dmsg)( + "WARNING: could not read from dyld shared cache (DSC)\n" + "Some reports (especially memory leaks) might be missing or incorrect (false-positives)\n" + ); + return 0; + } + // We currently detect if dyld is loading/using a library by checking if stat64 fails. + // However, dyld doesn't seem to call stat64 for all of them anymore. + // All arm64 binaries are executables but some x86 ones might not be so let's avoid them just to be safe. + VG_(dyld_cache_load_library)("/usr/lib/system/libsystem_kernel.dylib"); + VG_(dyld_cache_load_library)("/usr/lib/system/libsystem_pthread.dylib"); + VG_(dyld_cache_load_library)("/usr/lib/system/libsystem_platform.dylib"); + + return 1; +} + +void VG_(dyld_cache_init)(const HChar* tool) { + // drd crashes if you map memory segments in m_main + if (VG_(strcmp)(tool, "drd") == 0) { + return; + } + + ensure_init(); +} + +int VG_(dyld_cache_might_be_in)(const HChar* path) { + // If not init'd, there is no point + if (!ensure_init()) { + return 0; + } + + if (VG_(strncmp)(path, "/usr/lib/", 9) == 0) { + return 1; + } + if (VG_(strncmp)(path, "/System/Library/", 16) == 0) { + return 1; + } + // FIXME: more flexible heuristics around extensions? + return 0; +} + +static struct MACH_HEADER* find_image_text(const dyld_cache_header* header, const char* path, SizeT* len) { + vg_assert(len); + *len = 0; + + const dyld_cache_image_text_info* textInfos = (const dyld_cache_image_text_info*) calculate_relative(header, header->imagesTextOffset); + + for (int i = 0; i < header->imagesTextCount; ++i) { + const dyld_cache_image_text_info* textInfo = &textInfos[i]; + const char* imagePath = (const char*) calculate_relative(header, textInfo->pathOffset); + + if (VG_(strcmp)(imagePath, path) == 0) { + output_text_debug_info(textInfo); + *len = textInfo->textSegmentSize; + return (struct MACH_HEADER*) calculate_unslid(textInfo->loadAddress); + } + } + + return NULL; +} + +int VG_(dyld_cache_load_library)(const HChar* path) { + struct MACH_HEADER *image = NULL; + ULong res = 0; + SizeT len = 0; + + if (VG_(strstr)(path, "/PrivateFrameworks/") != NULL) { + return 0; + } + + // If not init'd, there is no point trying + if (!ensure_init()) { + return 0; + } + + VG_(debugLog)(2, "dyld_cache", "potential dylib to check in the cache: %s\n", path); + + image = find_image_text(dyld_cache.header, path, &len); + if (image == NULL) { + VG_(debugLog)(2, "dyld_cache", "image not found: %s\n", path); + return 0; + } + + if (image->magic != MAGIC) { + VG_(debugLog)(2, "dyld_cache", "image not mach-o (%#x): %s\n", image->magic, path); + return 0; + } + + VG_(debugLog)(2, "dyld_cache", "image (%p) is valid, forwarding to debuginfo: %s\n", image, path); + res = VG_(di_notify_dsc)(path, (Addr)image, len); + if (res == 0) { + VG_(debugLog)(2, "dyld_cache", "failed to load debuginfo from: %s\n", path); + return 0; + } + + VG_(debugLog)(2, "dyld_cache", "image fully loaded: %s\n", path); + + return 1; +} + +static void output_text_debug_info(const dyld_cache_image_text_info* textInfo) { + const uint8_t* u = textInfo->uuid; + VG_(debugLog)(5, "dyld_cache", + "image_text_info{\n" + " .uuid: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x,\n" + " .loadAddress: %#llx,\n" + " .textSegmentSize: %u,\n" + " .pathOffset: %#x,\n" + "}\n", + u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], + u[9], u[10], u[11], u[12], u[13], u[14], u[15], + textInfo->loadAddress, + textInfo->textSegmentSize, + textInfo->pathOffset + ); +} + +static void output_debug_info(const dyld_cache_header* cache) { + const uint8_t* u1 = cache->uuid; + const uint8_t* u2 = cache->symbolFileUUID; + VG_(debugLog)(5, "dyld_cache", + "shared dyld content: {\n" + " .magic: %s,\n" + " .mappingOffset: %#x,\n" + " .mappingCount: %u,\n" + " .imagesOffsetOld: %#x,\n" + " .imagesCountOld: %u,\n" + " .dyldBaseAddress: %#llx,\n" + " .codeSignatureOffset: %#llx,\n" + " .codeSignatureSize: %llu,\n" + " .slideInfoOffsetUnused: %#llx,\n" + " .slideInfoSizeUnused: %llu,\n" + " .localSymbolsOffset: %#llx,\n" + " .localSymbolsSize: %llu,\n" + " .uuid: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x,\n" + " .cacheType: %llu,\n" + " .branchPoolsOffset: %#x,\n" + " .branchPoolsCount: %u,\n" + " .dyldInCacheMH: %#llx,\n" + " .dyldInCacheEntry: %#llx,\n" + " .imagesTextOffset: %#llx,\n" + " .imagesTextCount: %llu,\n" + " .patchInfoAddr: %#llx,\n" + " .patchInfoSize: %llu,\n" + " .otherImageGroupAddrUnused: %#llx,\n" + " .otherImageGroupSizeUnused: %llu,\n" + " .progClosuresAddr: %#llx,\n" + " .progClosuresSize: %llu,\n" + " .progClosuresTrieAddr: %#llx,\n" + " .progClosuresTrieSize: %llu,\n" + " .platform: %#x,\n" + " .formatVersion: %#x,\n" + " .dylibsExpectedOnDisk: %d,\n" + " .simulator: %d,\n" + " .locallyBuiltCache: %d,\n" + " .builtFromChainedFixups: %d,\n" + " .padding: %d,\n" + " .sharedRegionStart: %#llx,\n" + " .sharedRegionSize: %llu,\n" + " .maxSlide: %#llx,\n" + " .dylibsImageArrayAddr: %#llx,\n" + " .dylibsImageArraySize: %llu,\n" + " .dylibsTrieAddr: %#llx,\n" + " .dylibsTrieSize: %llu,\n" + " .otherImageArrayAddr: %#llx,\n" + " .otherImageArraySize: %llu,\n" + " .otherTrieAddr: %#llx,\n" + " .otherTrieSize: %llu,\n" + " .mappingWithSlideOffset: %#x,\n" + " .mappingWithSlideCount: %u,\n" + " .dylibsPBLStateArrayAddrUnused: %llu,\n" + " .dylibsPBLSetAddr: %llx,\n" + " .programsPBLSetPoolAddr: %#llx,\n" + " .programsPBLSetPoolSize: %llu,\n" + " .programTrieAddr: %#llx,\n" + " .programTrieSize: %u,\n" + " .osVersion: %#x,\n" + " .altPlatform: %#x,\n" + " .altOsVersion: %#x,\n" + " .swiftOptsOffset: %#llx,\n" + " .swiftOptsSize: %llu,\n" + " .subCacheArrayOffset: %#x,\n" + " .subCacheArrayCount: %u,\n" + " .symbolFileUUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x,\n" + " .rosettaReadOnlyAddr: %#llx,\n" + " .rosettaReadOnlySize: %llu,\n" + " .rosettaReadWriteAddr: %#llx,\n" + " .rosettaReadWriteSize: %llu,\n" + " .imagesOffset: %#x,\n" + " .imagesCount: %u,\n" + " .cacheSubType: %#x,\n" + " .objcOptsOffset: %#llx,\n" + " .objcOptsSize: %llu,\n" + " .cacheAtlasOffset: %#llx,\n" + " .cacheAtlasSize: %llu,\n" + " .dynamicDataOffset: %#llx,\n" + " .dynamicDataMaxSize: %llu,\n" + "}\n", + cache->magic, + cache->mappingOffset, + cache->mappingCount, + cache->imagesOffsetOld, + cache->imagesCountOld, + cache->dyldBaseAddress, + cache->codeSignatureOffset, + cache->codeSignatureSize, + cache->slideInfoOffsetUnused, + cache->slideInfoSizeUnused, + cache->localSymbolsOffset, + cache->localSymbolsSize, + u1[0], u1[1], u1[2], u1[3], u1[4], u1[5], u1[6], u1[7], u1[8], + u1[9], u1[10], u1[11], u1[12], u1[13], u1[14], u1[15], + cache->cacheType, + cache->branchPoolsOffset, + cache->branchPoolsCount, + cache->dyldInCacheMH, + cache->dyldInCacheEntry, + cache->imagesTextOffset, + cache->imagesTextCount, + cache->patchInfoAddr, + cache->patchInfoSize, + cache->otherImageGroupAddrUnused, + cache->otherImageGroupSizeUnused, + cache->progClosuresAddr, + cache->progClosuresSize, + cache->progClosuresTrieAddr, + cache->progClosuresTrieSize, + cache->platform, + (UInt)cache->formatVersion, + cache->dylibsExpectedOnDisk, + cache->simulator, + cache->locallyBuiltCache, + cache->builtFromChainedFixups, + cache->padding, + cache->sharedRegionStart, + cache->sharedRegionSize, + cache->maxSlide, + cache->dylibsImageArrayAddr, + cache->dylibsImageArraySize, + cache->dylibsTrieAddr, + cache->dylibsTrieSize, + cache->otherImageArrayAddr, + cache->otherImageArraySize, + cache->otherTrieAddr, + cache->otherTrieSize, + cache->mappingWithSlideOffset, + cache->mappingWithSlideCount, + cache->dylibsPBLStateArrayAddrUnused, + cache->dylibsPBLSetAddr, + cache->programsPBLSetPoolAddr, + cache->programsPBLSetPoolSize, + cache->programTrieAddr, + cache->programTrieSize, + cache->osVersion, + cache->altPlatform, + cache->altOsVersion, + cache->swiftOptsOffset, + cache->swiftOptsSize, + cache->subCacheArrayOffset, + cache->subCacheArrayCount, + u2[0], u2[1], u2[2], u2[3], u2[4], u2[5], u2[6], u2[7], u2[8], + u2[9], u2[10], u2[11], u2[12], u2[13], u2[14], u2[15], + cache->rosettaReadOnlyAddr, + cache->rosettaReadOnlySize, + cache->rosettaReadWriteAddr, + cache->rosettaReadWriteSize, + cache->imagesOffset, + cache->imagesCount, + cache->cacheSubType, + cache->objcOptsOffset, + cache->objcOptsSize, + cache->cacheAtlasOffset, + cache->cacheAtlasSize, + cache->dynamicDataOffset, + cache->dynamicDataMaxSize + ); +} + +#endif diff --git a/coregrind/m_mach/mach_basics.c b/coregrind/m_mach/mach_basics.c index f0f45f5735..73b802bdd6 100644 --- a/coregrind/m_mach/mach_basics.c +++ b/coregrind/m_mach/mach_basics.c @@ -30,6 +30,7 @@ #include "pub_core_basics.h" #include "pub_core_mach.h" +#include "pub_core_libcassert.h" // vg_assert #include #include @@ -40,6 +41,7 @@ extern mach_port_name_t thread_self_trap(void); extern mach_port_t mach_reply_port(void); /* Global variables set in mach_init() */ +int vm_page_shift = 0; vm_size_t vm_page_size = 0; mach_port_name_t mach_task_self_ = 0; @@ -60,6 +62,10 @@ mach_port_t mig_get_reply_port(void) // its own behalf, and doesn't call mig outside the semaphore } +void mach_msg_destroy(mach_msg_header_t *msg) +{ + // TODO: copy from XNU? +} void mig_dealloc_reply_port(mach_port_t reply_port) { @@ -79,7 +85,11 @@ void VG_(mach_init)(void) mach_task_self_ = task_self_trap(); // GrP fixme host_page_size(host_self_trap(), &vm_page_size); - vm_page_size = 4096; + vm_page_shift = 12; + // FIXME: stored in COMM_PAGE + 0x025, (1 << 12) = 4096 + vm_page_size = 0x1000; + + vg_assert(1 << vm_page_shift == vm_page_size); } #endif // defined(VGO_darwin) diff --git a/coregrind/m_mach/mach_msg.c b/coregrind/m_mach/mach_msg.c index c21425472a..0a99e79816 100644 --- a/coregrind/m_mach/mach_msg.c +++ b/coregrind/m_mach/mach_msg.c @@ -39,12 +39,146 @@ #if defined(VGO_darwin) +#include "config.h" // for DARWIN_VERS #include "pub_core_basics.h" #include "pub_core_mach.h" #include #include +#if DARWIN_VERS >= DARWIN_13_00 +// All of those should be defined in mach/message.h, but they are not. +typedef uint64_t mach_msg_option64_t; +#define MACH64_SEND_MSG MACH_SEND_MSG +#define MACH64_RCV_MSG MACH_RCV_MSG +#define MACH64_RCV_LARGE MACH_RCV_LARGE +#define MACH64_RCV_LARGE_IDENTITY MACH_RCV_LARGE_IDENTITY +#define MACH64_SEND_TIMEOUT MACH_SEND_TIMEOUT +#define MACH64_SEND_OVERRIDE MACH_SEND_OVERRIDE +#define MACH64_SEND_INTERRUPT MACH_SEND_INTERRUPT +#define MACH64_SEND_NOTIFY MACH_SEND_NOTIFY +#define MACH64_SEND_FILTER_NONFATAL MACH_SEND_FILTER_NONFATAL +#define MACH64_SEND_TRAILER MACH_SEND_TRAILER +#define MACH64_SEND_NOIMPORTANCE MACH_SEND_NOIMPORTANCE +#define MACH64_SEND_NODENAP MACH_SEND_NODENAP +#define MACH64_SEND_SYNC_OVERRIDE MACH_SEND_SYNC_OVERRIDE +#define MACH64_SEND_PROPAGATE_QOS MACH_SEND_PROPAGATE_QOS +#define MACH64_SEND_SYNC_BOOTSTRAP_CHECKIN MACH_SEND_SYNC_BOOTSTRAP_CHECKIN +#define MACH64_RCV_TIMEOUT MACH_RCV_TIMEOUT +#define MACH64_RCV_INTERRUPT MACH_RCV_INTERRUPT +#define MACH64_RCV_VOUCHER MACH_RCV_VOUCHER +#define MACH64_RCV_GUARDED_DESC MACH_RCV_GUARDED_DESC +#define MACH64_RCV_SYNC_WAIT MACH_RCV_SYNC_WAIT +#define MACH64_RCV_SYNC_PEEK MACH_RCV_SYNC_PEEK +#define MACH64_MSG_STRICT_REPLY MACH_MSG_STRICT_REPLY +#define MACH64_MSG_VECTOR 0x0000000100000000ull +#define MACH64_SEND_KOBJECT_CALL 0x0000000200000000ull +#define MACH64_SEND_MQ_CALL 0x0000000400000000ull +#define MACH64_SEND_ANY 0x0000000800000000ull + +typedef struct { + /* a mach_msg_header_t* or mach_msg_aux_header_t* */ + mach_vm_address_t msgv_data; + /* if msgv_rcv_addr is non-zero, use it as rcv address instead */ + mach_vm_address_t msgv_rcv_addr; + mach_msg_size_t msgv_send_size; + mach_msg_size_t msgv_rcv_size; +} mach_msg_vector_t; + +extern mach_msg_return_t +mach_msg2(void *data, + mach_msg_option64_t options, + uint64_t msgh_bits_and_send_size, + uint64_t msgh_remote_and_local_port, + uint64_t msgh_voucher_and_id, + uint64_t desc_count_and_rcv_name, + uint64_t rcv_size_and_priority, + uint64_t timeout); +// end of defines + +#define LIBMACH_OPTIONS64 (MACH64_SEND_INTERRUPT|MACH64_RCV_INTERRUPT) + +extern mach_msg_return_t +mach_msg2_trap(void *data, + mach_msg_option64_t options, + uint64_t msgh_bits_and_send_size, + uint64_t msgh_remote_and_local_port, + uint64_t msgh_voucher_and_id, + uint64_t desc_count_and_rcv_name, + uint64_t rcv_size_and_priority, + uint64_t timeout); + +static inline mach_msg_option64_t +mach_msg_options_after_interruption(mach_msg_option64_t option64) +{ + if ((option64 & MACH64_SEND_MSG) && (option64 & MACH64_RCV_MSG)) { + /* + * If MACH_RCV_SYNC_WAIT was passed for a combined send-receive it must + * be cleared for receive-only retries, as the kernel has no way to + * discover the destination. + */ + option64 &= ~MACH64_RCV_SYNC_WAIT; + } + option64 &= ~(LIBMACH_OPTIONS64 | MACH64_SEND_MSG); + return option64; +} + +mach_msg_return_t mach_msg2( + void *data, + mach_msg_option64_t option64, + uint64_t msgh_bits_and_send_size, + uint64_t msgh_remote_and_local_port, + uint64_t msgh_voucher_and_id, + uint64_t desc_count_and_rcv_name, + uint64_t rcv_size_and_priority, + uint64_t timeout +) { + mach_msg_return_t mr; + + mr = mach_msg2_trap(data, + option64 & ~LIBMACH_OPTIONS64, + msgh_bits_and_send_size, + msgh_remote_and_local_port, + msgh_voucher_and_id, + desc_count_and_rcv_name, + rcv_size_and_priority, + timeout); + + if (mr == MACH_MSG_SUCCESS) { + return MACH_MSG_SUCCESS; + } + + if ((option64 & MACH64_SEND_INTERRUPT) == 0) { + while (mr == MACH_SEND_INTERRUPTED) { + mr = mach_msg2_trap(data, + option64 & ~LIBMACH_OPTIONS64, + msgh_bits_and_send_size, + msgh_remote_and_local_port, + msgh_voucher_and_id, + desc_count_and_rcv_name, + rcv_size_and_priority, + timeout); + } + } + + if ((option64 & MACH64_RCV_INTERRUPT) == 0) { + while (mr == MACH_RCV_INTERRUPTED) { + mr = mach_msg2_trap(data, + mach_msg_options_after_interruption(option64), + msgh_bits_and_send_size & 0xffffffffull, /* zero send size */ + msgh_remote_and_local_port, + msgh_voucher_and_id, + desc_count_and_rcv_name, + rcv_size_and_priority, + timeout); + } + } + + return mr; +} +#endif + + #define LIBMACH_OPTIONS (MACH_SEND_INTERRUPT|MACH_RCV_INTERRUPT) extern mach_msg_return_t @@ -56,16 +190,43 @@ mach_msg_trap(mach_msg_header_t *msg, mach_msg_timeout_t timeout, mach_port_t notify); -mach_msg_return_t -mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify) - mach_msg_header_t *msg; - mach_msg_option_t option; - mach_msg_size_t send_size; - mach_msg_size_t rcv_size; - mach_port_t rcv_name; - mach_msg_timeout_t timeout; - mach_port_t notify; -{ +mach_msg_return_t mach_msg( + mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify +) { + +#if DARWIN_VERS >= DARWIN_13_00 + mach_msg_base_t *base; + if (option & MACH64_MSG_VECTOR) { + base = (mach_msg_base_t *)((mach_msg_vector_t *)msg)->msgv_data; + } else { + base = (mach_msg_base_t *)msg; + } + + mach_msg_size_t descriptors = 0; + if (option & MACH_SEND_MSG && msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) { + descriptors = base->body.msgh_descriptor_count; + } + +#define MACH_MSG2_SHIFT_ARGS(lo, hi) ((uint64_t)hi << 32 | (uint32_t)lo) + return mach_msg2( + msg, + ((mach_msg_option64_t)option) | MACH64_SEND_KOBJECT_CALL, + MACH_MSG2_SHIFT_ARGS(msg->msgh_bits, send_size), + MACH_MSG2_SHIFT_ARGS(msg->msgh_remote_port, msg->msgh_local_port), + MACH_MSG2_SHIFT_ARGS(msg->msgh_voucher_port, msg->msgh_id), + MACH_MSG2_SHIFT_ARGS(descriptors, rcv_name), + MACH_MSG2_SHIFT_ARGS(rcv_size, 0), + timeout + ); +#undef MACH_MSG2_SHIFT_ARGS + +#else mach_msg_return_t mr; /* @@ -101,6 +262,7 @@ mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify) timeout, notify); return mr; +#endif } #endif // defined(VGO_darwin) diff --git a/coregrind/m_mach/mach_traps-amd64-darwin.S b/coregrind/m_mach/mach_traps-amd64-darwin.S index ae2d7d1cc9..2f1524d252 100644 --- a/coregrind/m_mach/mach_traps-amd64-darwin.S +++ b/coregrind/m_mach/mach_traps-amd64-darwin.S @@ -72,6 +72,18 @@ _mach_msg_trap: syscall ret +#if DARWIN_VERS >= DARWIN_13_00 + // mach_msg_return_t mach_msg2_trap(...) + .text + .align 4 + .globl _mach_msg2_trap +_mach_msg2_trap: + movq $__NR_mach_msg2_trap, %rax + movq %rcx, %r10 + syscall + ret +#endif + // mach_port_t mach_reply_port(...) .text .align 4 diff --git a/coregrind/m_mach/mig_strncpy.c b/coregrind/m_mach/mig_strncpy.c new file mode 100644 index 0000000000..9e07e8c85c --- /dev/null +++ b/coregrind/m_mach/mig_strncpy.c @@ -0,0 +1,121 @@ +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (c) 2020-2025 Louis Brunner + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ +/* + * This file contains mig_strncpy and mig_strncpy_zerofill reimplemented + * from comments left by Joshua Block in the original file + * `xnu/libsyscall/mach/mig_strncpy.c` + * + * Here they are for reference: + */ +/* + * mig_strncpy.c - by Joshua Block + * + * mig_strncpy -- Bounded string copy. Does what the library routine strncpy + * OUGHT to do: Copies the (null terminated) string in src into dest, a + * buffer of length len. Assures that the copy is still null terminated + * and doesn't overflow the buffer, truncating the copy if necessary. + * + * Parameters: + * + * dest - Pointer to destination buffer. + * + * src - Pointer to source string. + * + * len - Length of destination buffer. + * + * Result: + * length of string copied, INCLUDING the trailing 0. + * + * mig_strncpy_zerofill -- Bounded string copy. Does what the + * library routine strncpy OUGHT to do: Copies the (null terminated) + * string in src into dest, a buffer of length len. Assures that + * the copy is still null terminated and doesn't overflow the buffer, + * truncating the copy if necessary. If the string in src is smaller + * than given length len, it will zero fill the remaining bytes in dest. + * + * Parameters: + * + * dest - Pointer to destination buffer. + * + * src - Pointer to source string. + * + * len - Length of destination buffer. + * + * Result: + * length of string copied, INCLUDING the trailing 0. + */ + +#if defined(VGO_darwin) + +#include + +int mig_strncpy(char *dest, const char *src, int len) +{ + int i; + int src_len; + + for (src_len = 0; src[src_len]; ++src_len); + + if (len > src_len) { + for (i = 0; i < src_len; ++i) { + dest[i] = src[i]; + } + dest[i] = '\0'; + return i + 1; + } + + for (i = 0; i < len; ++i) { + dest[i] = src[i]; + } + dest[i - 1] = '\0'; + return i; +} + +int mig_strncpy_zerofill(char *dest, const char *src, int len) +{ + int i; + int src_len; + + for (src_len = 0; src[src_len]; ++src_len); + + if (len > src_len) { + for (i = 0; i < src_len; ++i) { + dest[i] = src[i]; + } + for (; i < len; ++i) { + dest[i] = '\0'; + } + return len; + } + + for (i = 0; i < len; ++i) { + dest[i] = src[i]; + } + dest[i - 1] = '\0'; + return len; +} + +#endif // defined(VGO_darwin) + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_mach/priv_dyld_internals.h b/coregrind/m_mach/priv_dyld_internals.h new file mode 100644 index 0000000000..32c31f9f95 --- /dev/null +++ b/coregrind/m_mach/priv_dyld_internals.h @@ -0,0 +1,146 @@ +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (c) 2020-2025 Louis Brunner + + 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 3 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, see . + + The GNU General Public License is contained in the file COPYING. +*/ +#ifndef __PRIV_DYLD_INTERNALS_H +#define __PRIV_DYLD_INTERNALS_H + +#if defined(VGO_darwin) + +// This file contains a bunch of structure defined in Apple's dyld + +// From Apple's `dyld/dyld/SharedCacheRuntime.cpp` +#define CACHE_MAGIC_x86_64 "dyld_v1 x86_64" +#define CACHE_MAGIC_x86_64_HASWELL "dyld_v1 x86_64h" +#define CACHE_MAGIC_arm64 "dyld_v1 arm64" +#define CACHE_MAGIC_arm64e "dyld_v1 arm64e" + +// From Apple's `dyld/cache-builder/dyld_cache_format.h` +typedef struct { + char magic[16]; // e.g. "dyld_v0 i386" + uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info + uint32_t mappingCount; // number of dyld_cache_mapping_info entries + uint32_t imagesOffsetOld; // UNUSED: moved to imagesOffset to prevent older dsc_extarctors from crashing + uint32_t imagesCountOld; // UNUSED: moved to imagesCount to prevent older dsc_extarctors from crashing + uint64_t dyldBaseAddress; // base address of dyld when cache was built + uint64_t codeSignatureOffset; // file offset of code signature blob + uint64_t codeSignatureSize; // size of code signature blob (zero means to end of file) + uint64_t slideInfoOffsetUnused; // unused. Used to be file offset of kernel slid info + uint64_t slideInfoSizeUnused; // unused. Used to be size of kernel slid info + uint64_t localSymbolsOffset; // file offset of where local symbols are stored + uint64_t localSymbolsSize; // size of local symbols information + uint8_t uuid[16]; // unique value for each shared cache file + uint64_t cacheType; // 0 for development, 1 for production, 2 for multi-cache + uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses + uint32_t branchPoolsCount; // number of uint64_t entries + uint64_t dyldInCacheMH; // (unslid) address of mach_header of dyld in cache + uint64_t dyldInCacheEntry; // (unslid) address of entry point (_dyld_start) of dyld in cache + uint64_t imagesTextOffset; // file offset to first dyld_cache_image_text_info + uint64_t imagesTextCount; // number of dyld_cache_image_text_info entries + uint64_t patchInfoAddr; // (unslid) address of dyld_cache_patch_info + uint64_t patchInfoSize; // Size of all of the patch information pointed to via the dyld_cache_patch_info + uint64_t otherImageGroupAddrUnused; // unused + uint64_t otherImageGroupSizeUnused; // unused + uint64_t progClosuresAddr; // (unslid) address of list of program launch closures + uint64_t progClosuresSize; // size of list of program launch closures + uint64_t progClosuresTrieAddr; // (unslid) address of trie of indexes into program launch closures + uint64_t progClosuresTrieSize; // size of trie of indexes into program launch closures + uint32_t platform; // platform number (macOS=1, etc) + uint32_t formatVersion : 8, // dyld3::closure::kFormatVersion + dylibsExpectedOnDisk : 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid + simulator : 1, // for simulator of specified platform + locallyBuiltCache : 1, // 0 for B&I built cache, 1 for locally built cache + builtFromChainedFixups : 1, // some dylib in cache was built using chained fixups, so patch tables must be used for overrides + padding : 20; // TBD + uint64_t sharedRegionStart; // base load address of cache if not slid + uint64_t sharedRegionSize; // overall size required to map the cache and all subCaches, if any + uint64_t maxSlide; // runtime slide of cache can be between zero and this value + uint64_t dylibsImageArrayAddr; // (unslid) address of ImageArray for dylibs in this cache + uint64_t dylibsImageArraySize; // size of ImageArray for dylibs in this cache + uint64_t dylibsTrieAddr; // (unslid) address of trie of indexes of all cached dylibs + uint64_t dylibsTrieSize; // size of trie of cached dylib paths + uint64_t otherImageArrayAddr; // (unslid) address of ImageArray for dylibs and bundles with dlopen closures + uint64_t otherImageArraySize; // size of ImageArray for dylibs and bundles with dlopen closures + uint64_t otherTrieAddr; // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures + uint64_t otherTrieSize; // size of trie of dylibs and bundles with dlopen closures + uint32_t mappingWithSlideOffset; // file offset to first dyld_cache_mapping_and_slide_info + uint32_t mappingWithSlideCount; // number of dyld_cache_mapping_and_slide_info entries + uint64_t dylibsPBLStateArrayAddrUnused; // unused + uint64_t dylibsPBLSetAddr; // (unslid) address of PrebuiltLoaderSet of all cached dylibs + uint64_t programsPBLSetPoolAddr; // (unslid) address of pool of PrebuiltLoaderSet for each program + uint64_t programsPBLSetPoolSize; // size of pool of PrebuiltLoaderSet for each program + uint64_t programTrieAddr; // (unslid) address of trie mapping program path to PrebuiltLoaderSet + uint32_t programTrieSize; + uint32_t osVersion; // OS Version of dylibs in this cache for the main platform + uint32_t altPlatform; // e.g. iOSMac on macOS + uint32_t altOsVersion; // e.g. 14.0 for iOSMac + uint64_t swiftOptsOffset; // VM offset from cache_header* to Swift optimizations header + uint64_t swiftOptsSize; // size of Swift optimizations header + uint32_t subCacheArrayOffset; // file offset to first dyld_subcache_entry + uint32_t subCacheArrayCount; // number of subCache entries + uint8_t symbolFileUUID[16]; // unique value for the shared cache file containing unmapped local symbols + uint64_t rosettaReadOnlyAddr; // (unslid) address of the start of where Rosetta can add read-only/executable data + uint64_t rosettaReadOnlySize; // maximum size of the Rosetta read-only/executable region + uint64_t rosettaReadWriteAddr; // (unslid) address of the start of where Rosetta can add read-write data + uint64_t rosettaReadWriteSize; // maximum size of the Rosetta read-write region + uint32_t imagesOffset; // file offset to first dyld_cache_image_info + uint32_t imagesCount; // number of dyld_cache_image_info entries + uint32_t cacheSubType; // 0 for development, 1 for production, when cacheType is multi-cache(2) + uint64_t objcOptsOffset; // VM offset from cache_header* to ObjC optimizations header + uint64_t objcOptsSize; // size of ObjC optimizations header + uint64_t cacheAtlasOffset; // VM offset from cache_header* to embedded cache atlas for process introspection + uint64_t cacheAtlasSize; // size of embedded cache atlas + uint64_t dynamicDataOffset; // VM offset from cache_header* to the location of dyld_cache_dynamic_data_header + uint64_t dynamicDataMaxSize; // maximum size of space reserved from dynamic data +} dyld_cache_header; + +// From Apple's `dyld/cache-builder/dyld_cache_format.h` +typedef struct { + uint64_t address; + uint64_t size; + uint64_t fileOffset; + uint32_t maxProt; + uint32_t initProt; +} dyld_cache_mapping_info; + +// From Apple's `dyld/cache-builder/dyld_cache_format.h` +typedef struct { + uint8_t uuid[16]; // The UUID of the subCache file + uint64_t cacheVMOffset; // The offset of this subcache from the main cache base address + char fileSuffix[32]; // The file name suffix of the subCache file e.g. ".25.data", ".03.development" +} dyld_subcache_entry; + +// From Apple's `dyld/cache-builder/dyld_cache_format.h` +typedef struct { + uint8_t uuid[16]; // The UUID of the subCache file + uint64_t cacheVMOffset; // The offset of this subcache from the main cache base address +} dyld_subcache_entry_v1; + +// From Apple's `dyld/cache-builder/dyld_cache_format.h` +typedef struct { + uuid_t uuid; + uint64_t loadAddress; // unslid address of start of __TEXT + uint32_t textSegmentSize; + uint32_t pathOffset; // offset from start of cache file +} dyld_cache_image_text_info; + +#endif + +#endif diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index c93eaf98a0..8ca52c99e7 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -513,10 +513,10 @@ Int VG_(machine_arm_archlevel) = 4; #endif -/* For hwcaps detection on ppc32/64, s390x, and arm we'll need to do SIGILL +/* For hwcaps detection on ppc32/64, mips and arm we'll need to do SIGILL testing, so we need a VG_MINIMAL_JMP_BUF. */ #if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ - || defined(VGA_arm) || defined(VGA_s390x) || defined(VGA_mips32) \ + || defined(VGA_arm) || defined(VGA_mips32) \ || defined(VGA_mips64) || defined(VGA_arm64) #include "pub_core_libcsetjmp.h" static VG_MINIMAL_JMP_BUF(env_unsup_insn); @@ -602,7 +602,7 @@ static UInt VG_(get_machine_model)(void) { static struct model_map { const HChar name[5]; - UInt id; + const UInt id; } model_map[] = { { "2064", VEX_S390X_MODEL_Z900 }, { "2066", VEX_S390X_MODEL_Z800 }, @@ -1545,114 +1545,56 @@ Bool VG_(machine_get_hwcaps)( void ) #elif defined(VGA_s390x) -# include "libvex_s390x_common.h" - { - /* Instruction set detection code borrowed from ppc above. */ - vki_sigset_t saved_set, tmp_set; - vki_sigaction_fromK_t saved_sigill_act; - vki_sigaction_toK_t tmp_sigill_act; - - volatile Bool have_LDISP, have_STFLE; - Int i, r, model; + Int i, model; /* If the model is "unknown" don't treat this as an error. Assume this is a brand-new machine model for which we don't have the identification yet. Keeping fingers crossed. */ model = VG_(get_machine_model)(); - /* Unblock SIGILL and stash away the old action for that signal */ - VG_(sigemptyset)(&tmp_set); - VG_(sigaddset)(&tmp_set, VKI_SIGILL); - - r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set); - vg_assert(r == 0); - - r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act); - vg_assert(r == 0); - tmp_sigill_act = saved_sigill_act; - - /* NODEFER: signal handler does not return (from the kernel's point of - view), hence if it is to successfully catch a signal more than once, - we need the NODEFER flag. */ - tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND; - tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO; - tmp_sigill_act.sa_flags |= VKI_SA_NODEFER; - tmp_sigill_act.ksa_handler = handler_unsup_insn; - VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL); + /* When upgrading the minimum machine model do not forget to adjust + VEX_HWCAPS_S390X_MMM below and in main_main.c */ + if (model < VEX_S390X_MODEL_Z196) { + VG_(message)(Vg_FailMsg, "Your machine is too old. " + "You need at least a z196 to run valgrind.\n"); + VG_(exit)(1); + } - /* Determine hwcaps. Note, we cannot use the stfle insn because it - is not supported on z900. */ + /* Get number of double words to store all facilities */ + unsigned long long dummy[1]; - have_LDISP = True; - if (VG_MINIMAL_SETJMP(env_unsup_insn)) { - have_LDISP = False; - } else { - /* BASR loads the address of the next insn into r1. Needed to avoid - a segfault in XY. */ - __asm__ __volatile__("basr %%r1,%%r0\n\t" - ".long 0xe3001000\n\t" /* XY 0,0(%r1) */ - ".short 0x0057" : : : "r0", "r1", "cc", "memory"); - } + register ULong r0 asm("0") = 0; + asm volatile(".insn s,0xb2b00000,%0\n" /* stfle */ + : "=Q" (dummy), "+d"(r0) + : + : "cc", "memory"); + UInt num_dw = r0 + 1; - /* Check availability of STFLE. If available store facility bits - in hoststfle. */ - ULong hoststfle[S390_NUM_FACILITY_DW]; + /* Get the facility bits */ + ULong hoststfle[num_dw]; - for (i = 0; i < S390_NUM_FACILITY_DW; ++i) + for (i = 0; i < num_dw; ++i) hoststfle[i] = 0; - have_STFLE = True; - if (VG_MINIMAL_SETJMP(env_unsup_insn)) { - have_STFLE = False; - } else { - register ULong reg0 asm("0") = S390_NUM_FACILITY_DW - 1; - - __asm__(".insn s,0xb2b00000,%0" /* stfle */ - : "=Q"(hoststfle), "+d"(reg0) + __asm__(".insn s,0xb2b00000,%0" /* stfle */ + : "=Q"(hoststfle), "+d"(r0) : : "cc"); - } - /* Restore signals */ - r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL); - vg_assert(r == 0); - r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); - vg_assert(r == 0); va = VexArchS390X; vai.endness = VexEndnessBE; vai.hwcaps = model; - if (have_STFLE) vai.hwcaps |= VEX_HWCAPS_S390X_STFLE; - if (have_LDISP) { - /* Use long displacement only on machines >= z990. For all other - machines it is millicoded and therefore slow. */ - if (model >= VEX_S390X_MODEL_Z990) - vai.hwcaps |= VEX_HWCAPS_S390X_LDISP; - } - /* Detect presence of certain facilities using the STFLE insn. - Note, that these facilities were introduced at the same time or later - as STFLE, so the absence of STLFE implies the absence of the facility - we're trying to detect. */ + /* Detect presence of certain facilities using the STFLE insn. */ struct fac_hwcaps_map { UInt installed; - UInt facility_bit; - UInt hwcaps_bit; + const UInt facility_bit; + const UInt hwcaps_bit; const HChar name[6]; // may need adjustment for new facility names } fac_hwcaps[] = { - { False, 18, VEX_HWCAPS_S390X_LDISP, "LDISP" }, - { False, 21, VEX_HWCAPS_S390X_EIMM, "EIMM" }, - { False, 34, VEX_HWCAPS_S390X_GIE, "GIE" }, - { False, 42, VEX_HWCAPS_S390X_DFP, "DFP" }, - { False, 41, VEX_HWCAPS_S390X_FGX, "FGX" }, - { False, 24, VEX_HWCAPS_S390X_ETF2, "ETF2" }, - { False, 7, VEX_HWCAPS_S390X_STFLE, "STFLE" }, - { False, 30, VEX_HWCAPS_S390X_ETF3, "ETF3" }, - { False, 25, VEX_HWCAPS_S390X_STCKF, "STCKF" }, - { False, 37, VEX_HWCAPS_S390X_FPEXT, "FPEXT" }, - { False, 45, VEX_HWCAPS_S390X_LSC, "LSC" }, - { False, 44, VEX_HWCAPS_S390X_PFPO, "PFPO" }, + { True, 0, VEX_HWCAPS_S390X_MRMM, "Z196" }, /* always first */ { False, 129, VEX_HWCAPS_S390X_VX, "VX" }, { False, 57, VEX_HWCAPS_S390X_MSA5, "MSA5" }, { False, 58, VEX_HWCAPS_S390X_MI2, "MI2" }, @@ -1662,17 +1604,17 @@ Bool VG_(machine_get_hwcaps)( void ) { False, 165, VEX_HWCAPS_S390X_NNPA, "NNPA" }, { False, 148, VEX_HWCAPS_S390X_VXE2, "VXE2" }, { False, 134, VEX_HWCAPS_S390X_VXD, "VXD" }, - { False, 17, VEX_HWCAPS_S390X_MSA, "MSA" }, - { False, 77, VEX_HWCAPS_S390X_MSA4, "MSA4" }, { False, 146, VEX_HWCAPS_S390X_MSA8, "MSA8" }, { False, 155, VEX_HWCAPS_S390X_MSA9, "MSA9" }, + { False, 61, VEX_HWCAPS_S390X_MI3, "MI3" }, + { False, 198, VEX_HWCAPS_S390X_VXE3, "VXE3" }, + { False, 86, VEX_HWCAPS_S390X_MSA12, "MSA12" }, }; /* Set hwcaps according to the detected facilities */ UChar dw_number = 0; UChar fac_bit = 0; for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) { - vg_assert(fac_hwcaps[i].facility_bit <= 191); // for now dw_number = fac_hwcaps[i].facility_bit / 64; fac_bit = fac_hwcaps[i].facility_bit % 64; if (hoststfle[dw_number] & (1ULL << (63 - fac_bit))) { @@ -2445,7 +2387,7 @@ Int VG_(machine_get_size_of_largest_guest_register) ( void ) return 8; # elif defined(VGA_s390x) - return 8; + return (vai.hwcaps & VEX_HWCAPS_S390X_VX) ? 16 : 8; # elif defined(VGA_arm) /* Really it depends whether or not we have NEON, but let's just diff --git a/coregrind/m_main.c b/coregrind/m_main.c index c7df35e5ca..2f85c4f3f2 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -255,8 +255,12 @@ static void usage_NORETURN ( int need_help ) " recovered by stack scanning [5]\n" " --resync-filter=no|yes|verbose [yes on MacOS, no on other OSes]\n" " attempt to avoid expensive address-space-resync operations\n" -" --max-threads= maximum number of threads that valgrind can\n" -" handle [%d]\n" +" --max-threads= maximum number of threads that valgrind can\n" +" handle [%d]\n" +#if defined(VGO_linux) +" --max-guard-pages= maximum number of madvise guard pages that\n" +" valgrind can handle [%d]\n" +#endif "\n"; const HChar usage2[] = @@ -340,8 +344,8 @@ static void usage_NORETURN ( int need_help ) " Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n" "\n" " %s is %s\n" -" Valgrind is Copyright (C) 2000-2024, and GNU GPL'd, by Julian Seward et al.\n" -" LibVEX is Copyright (C) 2004-2024, and GNU GPL'd, by OpenWorks LLP et al.\n" +" Valgrind is Copyright (C) 2000-2026, and GNU GPL'd, by Julian Seward et al.\n" +" LibVEX is Copyright (C) 2004-2026, and GNU GPL'd, by OpenWorks LLP et al.\n" "\n" " Bug reports, feedback, admiration, abuse, etc, to: %s.\n" "\n"; @@ -383,6 +387,9 @@ static void usage_NORETURN ( int need_help ) VG_(vgdb_prefix_default)() /* char* */, N_SECTORS_DEFAULT /* int */, MAX_THREADS_DEFAULT /* int */ +#if defined(VGO_linux) + , MAX_GUARDS_DEFAULT /* int */ +#endif ); if (need_help > 1 && VG_(details).name) { VG_(printf)(" user options for %s:\n", VG_(details).name); @@ -461,9 +468,9 @@ static void process_option (Clo_Mode mode, // in case someone has combined a prefix with a core-specific option, // eg. "--memcheck:verbose". if (*colon == ':') { - if (VG_STREQN(2, arg, "--") && - VG_STREQN(toolname_len, arg+2, VG_(clo_toolname)) && - VG_STREQN(1, arg+2+toolname_len, ":")) { + if (VG_STREQN(2, arg, "--") && + VG_(strncmp)(arg+2, VG_(clo_toolname), toolname_len)==0 && + VG_(strncmp)(arg+2+toolname_len, ":", 1)==0) { // Prefix matches, convert "--toolname:foo" to "--foo". // Two things to note: // - We cannot modify the option in-place. If we did, and then @@ -521,7 +528,19 @@ static void process_option (Clo_Mode mode, else if VG_INT_CLOM(cloE, arg, "--main-stacksize", VG_(clo_main_stacksize)) {} // Set up VG_(clo_max_threads); needed for VG_(tl_pre_clo_init) - else if VG_INT_CLOM(cloE, arg, "--max-threads", VG_(clo_max_threads)) {} + else if VG_INT_CLOM(cloE, arg, "--max-threads", VG_(clo_max_threads)) { +#if defined(VGO_linux) + // VG_(clo_max_guard_pages) defaults to VG_(clo_max_threads) + // unless explititly set otherwise - below. With glibc upstream + // commit a6fbe36b7f31 and others, a guard page is installed for + // each new thread. + VG_(clo_max_guard_pages) = VG_(clo_max_threads); +#endif + } +#if defined(VGO_linux) + // Set up VG_(clo_max_guard_pages); needed for aspacemgr init + else if VG_INT_CLOM(cloE, arg, "--max-guard-pages", VG_(clo_max_guard_pages)) {} +#endif // Set up VG_(clo_sim_hints). This is needed a.o. for an inner // running in an outer, to have "no-inner-prefix" enabled @@ -730,7 +749,7 @@ static void process_option (Clo_Mode mode, else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {} else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {} else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {} - else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1, + else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 2, VG_DEEPEST_BACKTRACE) {} else if VG_BINT_CLO(arg, "--num-transtab-sectors", VG_(clo_num_transtab_sectors), @@ -1342,8 +1361,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) /* Start the debugging-log system ASAP. First find out how many "-d"s were specified. This is a pre-scan of the command line. Also get --profile-heap=yes, --core-redzone-size, --redzone-size - --aspace-minaddr which are needed by the time we start up dynamic - memory management. */ + --aspace-minaddr, --max-guard-pages which are needed by the time + we start up dynamic memory management. */ loglevel = 0; for (i = 1; i < argc; i++) { const HChar* tmp_str; @@ -1364,6 +1383,18 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) &errmsg)) VG_(fmsg_bad_option)(argv[i], "%s\n", errmsg); } + if VG_INT_CLOM(cloE, argv[i], "--max-threads", VG_(clo_max_threads)) { +#if defined(VGO_linux) + // VG_(clo_max_guard_pages) defaults to VG_(clo_max_threads) + // unless explititly set otherwise - below. With glibc upstream + // commit a6fbe36b7f31 and others, a guard page is installed for + // each new thread. + VG_(clo_max_guard_pages) = VG_(clo_max_threads); +#endif + } +#if defined(VGO_linux) + if VG_INT_CLOM(cloE, argv[i], "--max-guard-pages", VG_(clo_max_guard_pages)) {} +#endif } /* ... and start the debug logger. Now we can safely emit logging @@ -1539,7 +1570,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(printf)(" * ARM (armv7)\n"); VG_(printf)(" * MIPS (mips32 and above; mips64 and above)\n"); VG_(printf)(" * PowerPC (most; ppc405 and above)\n"); - VG_(printf)(" * System z (64bit only - s390x; z990 and above)\n"); + VG_(printf)(" * System z (64bit only - s390x; z196 and above)\n"); VG_(printf)("\n"); VG_(exit)(1); } @@ -1687,13 +1718,13 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(cl_psinfo_fd) = -1; #endif -#if defined(VGO_linux) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) if (!need_help) { HChar buf[50]; // large enough HChar buf2[VG_(mkstemp_fullname_bufsz)(sizeof buf - 1)]; Int fd, r; -#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) +#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) || defined(VGO_freebsd) /* Fake /proc//cmdline only on Linux and Solaris if supported. */ HChar nul[1]; const HChar* exename; @@ -1726,7 +1757,9 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2); VG_(cl_cmdline_fd) = fd; -#endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) +#endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) || defined(VGO_freebsd) + +#if !defined(VGO_freebsd) /* Fake /proc//auxv on both Linux and Solaris. */ VG_(debugLog)(1, "main", "Create fake /proc//auxv\n"); @@ -1758,6 +1791,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(cl_auxv_fd) = fd; +#endif + #if defined(VGO_solaris) /* Fake /proc//psinfo on Solaris. * Contents will be fetched and partially faked later on the fly. */ @@ -1919,7 +1954,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2", VG_(free), sizeof(Addr_n_ULong) ); -# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_darwin) || defined(VGO_freebsd) { Addr* seg_starts; Int n_seg_starts; Addr_n_ULong anu; @@ -1941,22 +1976,6 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) } } - VG_(free)( seg_starts ); - } -# elif defined(VGO_darwin) - { Addr* seg_starts; - Int n_seg_starts; - seg_starts = VG_(get_segment_starts)( SkFileC, &n_seg_starts ); - vg_assert(seg_starts && n_seg_starts >= 0); - - /* show them all to the debug info reader. - Don't read from V segments (unlike Linux) */ - // GrP fixme really? - for (i = 0; i < n_seg_starts; i++) { - VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/, - -1/*don't use_fd*/); - } - VG_(free)( seg_starts ); } # else @@ -1995,6 +2014,18 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(init_Threads)(); + //-------------------------------------------------------------- + // Initialize the dyld cache, which is required with macOS 11 (Big Sur) and onwards + // as some system libraries aren't provided on the disk anymore + // p: none + // Note: some tools don't like to start mapping memory right way, so we do it lazily in those cases. + //-------------------------------------------------------------- +# if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_11_00 + if (the_iifii.dynamic) { + VG_(dyld_cache_init)(VG_(clo_toolname)); + } +# endif + //-------------------------------------------------------------- // Initialise the scheduler (phase 1) [generates tid_main] // p: none, afaics @@ -2110,22 +2141,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) True /* executable? */, 0 /* di_handle: no associated debug info */ ); - /* Darwin only: tell the tools where the client's kernel commpage - is. It would be better to do this by telling aspacemgr about - it -- see the now disused record_system_memory() in - initimg-darwin.c -- but that causes the sync checker to fail, - since the mapping doesn't appear in the kernel-supplied - process map. So do it here instead. */ -# if defined(VGP_amd64_darwin) - VG_TRACK( new_mem_startup, - 0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000, - True, False, True, /* r-x */ - 0 /* di_handle: no associated debug info */ ); -# elif defined(VGP_x86_darwin) - VG_TRACK( new_mem_startup, - 0xfffec000, 0xfffff000-0xfffec000, - True, False, True, /* r-x */ - 0 /* di_handle: no associated debug info */ ); +#if defined(VGO_darwin) + VG_(mach_record_system_memory)(); # endif /* Clear the running thread indicator */ diff --git a/coregrind/m_options.c b/coregrind/m_options.c index d344db9fb5..b1e9066fe9 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -189,6 +189,9 @@ Bool VG_(clo_keep_debuginfo) = False; Bool VG_(clo_show_emwarns) = False; Word VG_(clo_max_stackframe) = 2000000; UInt VG_(clo_max_threads) = MAX_THREADS_DEFAULT; +#if defined(VGO_linux) +UInt VG_(clo_max_guard_pages) = MAX_GUARDS_DEFAULT; +#endif Word VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */ Word VG_(clo_valgrind_stacksize) = VG_DEFAULT_STACK_ACTIVE_SZB; Bool VG_(clo_wait_for_gdb) = False; diff --git a/coregrind/m_pathscan.c b/coregrind/m_pathscan.c index 841c674e33..a1193c3875 100644 --- a/coregrind/m_pathscan.c +++ b/coregrind/m_pathscan.c @@ -102,12 +102,12 @@ static Bool match_executable(const HChar *entry) // matching executable later in the path. if (VG_(access)(buf, True/*r*/, False/*w*/, True/*x*/) == 0) { VG_(free)(executable_name_out); - executable_name_out = VG_(strdup)("match_executable", buf); + executable_name_out = VG_(strdup)("match_executable.1", buf); return True; // Stop looking } else if (VG_(access)(buf, True/*r*/, False/*w*/, False/*x*/) == 0 && executable_name_out == NULL) { - executable_name_out = VG_(strdup)("match_executable", buf); + executable_name_out = VG_(strdup)("match_executable.2", buf); return False; // Keep looking } else { return False; // Keep looking diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index e0f596fbee..0c43731ded 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -402,10 +402,8 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) Bool isText; const HChar* newdi_soname; Bool dehacktivate_pthread_stack_cache_var_search = False; - const HChar* const pthread_soname = "libpthread.so.0"; const HChar* const pthread_stack_cache_actsize_varname = "stack_cache_actsize"; - const HChar* const libc_soname = "libc.so.6"; const HChar* const libc_gnu_get_libc_version_funcname = "gnu_get_libc_version"; #if defined(VGO_solaris) Bool vg_vfork_fildes_var_search = False; @@ -421,11 +419,19 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) newdi_soname = VG_(DebugInfo_get_soname)(newdi); vg_assert(newdi_soname != NULL); +#if defined(VGO_linux) /* libc is special, because it contains some of the core redirects. Make sure it is fully loaded. */ + /* If ever it is needed on other platforms + * FreeBSD libc is libc.so.7 libpthread is libthr.so.3 + * Solaris libc is libc.so.1 libpthread is libpthread.so.1 + * older Darwin has some system dylib, newer Darwin just has libs in memory */ + const HChar* const libc_soname = "libc.so.6"; + const HChar* const pthread_soname = "libpthread.so.0"; if (0 == VG_(strcmp)(newdi_soname, libc_soname) || 0 == VG_(strcmp)(newdi_soname, pthread_soname)) VG_(di_load_di)(newdi); +#endif #ifdef ENABLE_INNER { @@ -512,10 +518,12 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) specList = NULL; /* the spec list we're building up */ +#if defined(VGO_linux) dehacktivate_pthread_stack_cache_var_search = SimHintiS(SimHint_no_nptl_pthread_stackcache, VG_(clo_sim_hints)) && (0 == VG_(strcmp)(newdi_soname, pthread_soname) || 0 == VG_(strcmp)(newdi_soname, libc_soname)); +#endif #if defined(VGO_solaris) vg_vfork_fildes_var_search = @@ -539,7 +547,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) * set a global flag. * * https://bugs.kde.org/show_bug.cgi?id=497723 but not for - * callgrind because demangled overloaded manes get + * callgrind because demangled overloaded names get * incorrectly counted together. */ if (!isText && VG_(strcmp)(*names, "__gnat_ada_main_program_name") == 0 && @@ -685,6 +693,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) } free_symname_array(names_init, &twoslots[0]); } +#if defined(VGO_linux) if (dehacktivate_pthread_stack_cache_var_search) { VG_(message)(Vg_DebugMsg, "WARNING: could not find symbol for var %s in %s\n", @@ -692,6 +701,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) VG_(message)(Vg_DebugMsg, "=> pthread stack cache cannot be disabled!\n"); } +#endif #if defined(VGO_solaris) if (vg_vfork_fildes_var_search) { VG_(message)(Vg_DebugMsg, @@ -925,6 +935,24 @@ void generate_and_add_actives ( } /* for (sp = specs; sp; sp = sp->next) */ } /* iterating over names[] */ +#if defined(VGO_freebsd) + /* + * See https://bugs.kde.org/show_bug.cgi?id=518609 + * + * With VG_(clo_verbosity) > 2 the code that gets symbol names + * from addesses can trigger reading split .debug files. That + * in turn can modify the symtab that this loop is iterating over. + * This can cause redirection to fail. + * + * So set nsyms to the new number of symbols and reset the loop + * counter to 0. That may cause a few "Ignoring duplicate redirection" + * messages. + */ + if (nsyms != VG_(DebugInfo_syms_howmany)(di)) { + nsyms = VG_(DebugInfo_syms_howmany)(di); + i = 0; + } +#endif free_symname_array(names_init, &twoslots[0]); } /* for (i = 0; i < nsyms; i++) */ @@ -1628,6 +1656,8 @@ void VG_(redir_initialise) ( void ) (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL); add_hardwired_spec("dyld", "strlcat", (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL); + add_hardwired_spec("dyld", "bcmp", + (Addr)&VG_(amd64_darwin_REDIR_FOR_bcmp), NULL); // DDD: #warning fixme rdar://6166275 add_hardwired_spec("dyld", "arc4random", (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL); diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index c3f42b8633..5672eda097 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -306,7 +306,7 @@ extern int * __error(void) __attribute__((weak)); \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ - MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ + MALLOC_TRACE(#fnname "(%lu)", n ); \ \ v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ MALLOC_TRACE(" = %p\n", v ); \ @@ -329,7 +329,7 @@ extern int * __error(void) __attribute__((weak)); TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=n, .alloc_kind=AllocKind##tag}; \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ + MALLOC_TRACE(#fnname "(%lu, %lu)", n, alignment ); \ \ if ((alignment == 0) \ || ((alignment & (alignment - 1)) != 0)) { \ @@ -356,7 +356,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ - MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \ + MALLOC_TRACE(#fnname "(%p, %lu)", zone, n ); \ \ v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ MALLOC_TRACE(" = %p\n", v ); \ @@ -376,8 +376,8 @@ extern int * __error(void) __attribute__((weak)); void* v; \ \ DO_INIT; \ - TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ - MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + MALLOC_TRACE(#fnname "(%lu)", n ); \ \ v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ MALLOC_TRACE(" = %p\n", v ); \ @@ -407,7 +407,7 @@ extern int * __error(void) __attribute__((weak)); TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=n, .alloc_kind=AllocKind##tag }; \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ + MALLOC_TRACE(#fnname "(%lu, %lu)", n, alignment ); \ \ if ((alignment == 0) \ || ((alignment & (alignment - 1)) != 0)) { \ @@ -455,6 +455,19 @@ extern int * __error(void) __attribute__((weak)); ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc); ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc); ZONEALLOC_or_NULL(SO_SYN_MALLOC, malloc_zone_malloc, malloc); +#if DARWIN_VERS >= DARWIN_15_00 +#if defined(VGA_arm64) + // on arm64, malloc_type_malloc is used for malloc, new and new[] + // __typed_operator_new_impl[abi:ne180100]@libc++abi.dylib calls it for new and new[] + // all other usages (Swift, ObjC, C) it calls it for malloc + // this matters as we need to put the right tag in the allocation + // otherwise the tool might report a mismatch between allocation func and free func + TYPE_ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_type_malloc); +#else + ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_type_malloc, malloc); +#endif + ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_type_zone_malloc, malloc); +#endif #elif defined(VGO_solaris) ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc); @@ -503,18 +516,11 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - // operator new(unsigned int) - #if VG_WORDSIZE == 4 - ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); - ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znwj, __builtin_new); - ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new); - #endif + // both 32bit and 64bit // operator new(unsigned long) - #if VG_WORDSIZE == 8 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znwm, __builtin_new); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new); - #endif #elif defined(VGO_solaris) // operator new(unsigned int) @@ -563,16 +569,10 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); - #endif - #if VG_WORDSIZE == 8 + // both 32bit and 64bit ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); - #endif #elif defined(VGO_solaris) // operator new(unsigned int, std::align_val_t) @@ -623,18 +623,11 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - // operator new(unsigned, std::nothrow_t const&) - #if VG_WORDSIZE == 4 - ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); - ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); - ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new); - #endif + // both 32bit and 64bit // operator new(unsigned long, std::nothrow_t const&) - #if VG_WORDSIZE == 8 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new); - #endif #elif defined(VGO_solaris) // operator new(unsigned, std::nothrow_t const&) @@ -683,16 +676,10 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); - #endif - #if VG_WORDSIZE == 8 + // both 32bit and 64bit ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); - #endif #elif defined(VGO_solaris) // operator new(unsigned, std::align_val_t, std::nothrow_t const&) @@ -745,18 +732,11 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - // operator new[](unsigned int) - #if VG_WORDSIZE == 4 - ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); - ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znaj, __builtin_vec_new ); - ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new ); - #endif + // both 32bit and 64bit // operator new[](unsigned long) - #if VG_WORDSIZE == 8 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znam, __builtin_vec_new ); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new ); - #endif #elif defined(VGO_solaris) // operator new[](unsigned int) @@ -806,17 +786,11 @@ extern int * __error(void) __attribute__((weak)); #elif defined(VGO_darwin) - #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); - #endif + // both 32bit and 64bit // operator new[](unsigned long, std::align_val_t) - #if VG_WORDSIZE == 8 ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); - #endif #elif defined(VGO_solaris) // operator new[](unsigned int, std::align_val_t) @@ -866,18 +840,11 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - // operator new[](unsigned, std::nothrow_t const&) - #if VG_WORDSIZE == 4 - ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); - ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); - ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new ); - #endif + // both 32bit and 64bit // operator new[](unsigned long, std::nothrow_t const&) - #if VG_WORDSIZE == 8 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new ); - #endif #elif defined(VGO_solaris) // operator new[](unsigned, std::nothrow_t const&) @@ -927,17 +894,10 @@ extern int * __error(void) __attribute__((weak)); #elif defined(VGO_darwin) - #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); - #endif - // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&) - #if VG_WORDSIZE == 8 + // both 32bit and 64bit ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); - #endif #elif defined(VGO_solaris) // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&) @@ -996,6 +956,8 @@ extern int * __error(void) __attribute__((weak)); #elif defined(VGO_darwin) FREE(VG_Z_LIBC_SONAME, free, free ); FREE(SO_SYN_MALLOC, free, free ); + FREE(VG_Z_LIBC_SONAME, vfree, free ); + FREE(SO_SYN_MALLOC, vfree, free ); ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free ); ZONEFREE(SO_SYN_MALLOC, malloc_zone_free, free ); @@ -1022,7 +984,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(%p)\n", p ); \ + MALLOC_TRACE(#fnname "(%p, %lu)\n", p, size ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ @@ -1065,7 +1027,7 @@ extern int * __error(void) __attribute__((weak)); TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(%p)\n", p ); \ + MALLOC_TRACE(#fnname "(%p, %lu, %lu)\n", p, size, alignment ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ @@ -1163,7 +1125,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(%p)\n", p ); \ + MALLOC_TRACE(#fnname "(%p, %lu)\n", p, size ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ @@ -1198,17 +1160,11 @@ extern int * __error(void) __attribute__((weak)); #endif #elif defined(VGO_darwin) - // operator delete(void*, unsigned int) -#if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete, DeleteSized ); -#elif __SIZEOF_SIZE_T__ == 8 + // both 32bit and 64bit // operator delete(void*, unsigned long) DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete, DeleteSized ); -#endif #elif defined(VGO_solaris) // operator delete(void*, unsigned long) @@ -1238,7 +1194,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(%p)\n", p ); \ + MALLOC_TRACE(#fnname "(%p, %lu)\n", p, alignment ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ @@ -1255,7 +1211,7 @@ extern int * __error(void) __attribute__((weak)); TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE(#fnname "(%p)\n", p ); \ + MALLOC_TRACE(#fnname "(%p, %lu, %lu)\n", p, size, alignment ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ @@ -1307,17 +1263,10 @@ extern int * __error(void) __attribute__((weak)); DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); - // operator delete(void*, unsigned int, std::align_val_t) -#if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); - // operator delete(void*, unsigned long, std::align_val_t) -#elif __SIZEOF_SIZE_T__ == 8 + // both 32bit and 64bit DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); -#endif #elif defined(VGO_solaris) @@ -1461,15 +1410,10 @@ extern int * __error(void) __attribute__((weak)); #elif defined(VGO_darwin) - #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); - #elif __SIZEOF_SIZE_T__ == 8 + // both 32bit and 64bit DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); - #endif #elif defined(VGO_solaris) // operator delete[](void*, unsigned int) @@ -1532,17 +1476,11 @@ extern int * __error(void) __attribute__((weak)); DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); - // operator delete[](void*, unsigned int, std::align_val_t) - #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + // both 32bit and 64bit // operator delete[](void*, unsigned long, std::align_val_t) - #elif __SIZEOF_SIZE_T__ == 8 DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); -#endif #elif defined(VGO_solaris) @@ -1709,7 +1647,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(ptrV); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(new_size); \ - MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \ + MALLOC_TRACE("zone_realloc(%p,%p,%lu)", zone, ptrV, new_size ); \ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ MALLOC_TRACE(" = %p\n", v ); \ if (v == NULL) { \ @@ -1732,7 +1670,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(ptrV); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(new_size); \ - MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \ + MALLOC_TRACE("realloc(%p,%lu)", ptrV, new_size ); \ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ MALLOC_TRACE(" = %p\n", v ); \ if (v == NULL) { \ @@ -1755,7 +1693,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(ptrV); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(new_size); \ - MALLOC_TRACE("reallocf(%p,%llu)", ptrV, (ULong)new_size ); \ + MALLOC_TRACE("reallocf(%p,%lu)", ptrV, new_size ); \ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ MALLOC_TRACE(" = %p\n", v ); \ if (v == NULL) { \ @@ -1781,7 +1719,7 @@ extern int * __error(void) __attribute__((weak)); TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(ptrV); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ - MALLOC_TRACE("reallocarray(%p,%llu,%llu)", ptrV, (ULong)nmemb, (ULong)size ); \ + MALLOC_TRACE("reallocarray(%p,%lu,%lu)", ptrV, nmemb, size ); \ if (nmemb > 0 && (SizeT)-1 / nmemb < size) { \ SET_ERRNO_ENOMEM; \ MALLOC_TRACE(" = 0\n"); \ @@ -1791,7 +1729,6 @@ extern int * __error(void) __attribute__((weak)); MALLOC_TRACE(" = %p\n", v ); \ if (v == NULL) { \ if (!(size*nmemb == 0U && info.clo_realloc_zero_bytes_frees == True)) {\ - VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ SET_ERRNO_ENOMEM; \ } \ } \ @@ -1883,8 +1820,8 @@ extern int * __error(void) __attribute__((weak)); VERIFY_ALIGNMENT(&aligned_alloc_info); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)zone); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ - MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", zone, \ - (ULong)alignment, (ULong)n); \ + MALLOC_TRACE("zone_memalign(%p, %lu, %lu)", zone, \ + alignment, n); \ \ if (alignment == 0 || alignment % sizeof(void*) != 0 || \ (alignment & (alignment - 1)) != 0) { \ @@ -1952,8 +1889,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE("memalign(al %llu, size %llu)", \ - (ULong)alignment, (ULong)n ); \ + MALLOC_TRACE("memalign(%lu, %lu)", alignment, n ); \ \ /* Round up to minimum alignment if necessary. */ \ if (alignment < VG_MIN_MALLOC_SZB) \ @@ -1986,8 +1922,7 @@ extern int * __error(void) __attribute__((weak)); \ DO_INIT; \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE("memalign(alignment %llu, size %llu)", (ULong)alignment, \ - (ULong)size); \ + MALLOC_TRACE("memalign(%lu, %lu)", alignment, size); \ if ((VG_MEMALIGN_NO_SIZE_ZERO && (size == 0)) || \ (VG_MEMALIGN_NO_ALIGN_ZERO && (alignment == 0)) || \ (VG_MEMALIGN_ALIGN_POWER_TWO && \ @@ -2193,8 +2128,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE("posix_memalign(al %llu, size %llu)", \ - (ULong)alignment, (ULong)size ); \ + MALLOC_TRACE("posix_memalign(%p, %lu, %lu)", memptr, alignment, size ); \ /* Test whether the alignment argument is valid. It must be \ a power of two multiple of sizeof (void *). */ \ if (alignment == 0 \ @@ -2236,8 +2170,9 @@ extern int * __error(void) __attribute__((weak)); POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign); #elif defined(VGO_darwin) -#if (DARWIN_VERSIO >= DARWIN_10_6) +#if (DARWIN_VERS >= DARWIN_10_6) POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); + POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign); #endif #elif defined(VGO_solaris) @@ -2337,8 +2272,7 @@ extern int * __error(void) __attribute__((weak)); DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \ - (ULong)alignment, (ULong)size ); \ + MALLOC_TRACE("aligned_alloc(%lu, %lu)", alignment, size ); \ \ /* Round up to minimum alignment if necessary. */ \ if (alignment < VG_MIN_MALLOC_SZB) \ @@ -2370,8 +2304,7 @@ extern int * __error(void) __attribute__((weak)); \ DO_INIT; \ VERIFY_ALIGNMENT(&aligned_alloc_info); \ - MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \ - (ULong)alignment, (ULong)size ); \ + MALLOC_TRACE("aligned_alloc(%lu, %lu)", alignment, size ); \ if ((VG_ALIGNED_ALLOC_NO_SIZE_ZERO && (size == 0)) \ || (VG_ALIGNED_ALLOC_NO_ALIGN_ZERO && (alignment == 0)) \ || (VG_ALIGNED_ALLOC_SIZE_MULTIPLE_ALIGN && alignment && (size % alignment != 0)) \ @@ -2404,11 +2337,11 @@ extern int * __error(void) __attribute__((weak)); ALIGNED_ALLOC(SO_SYN_MALLOC, aligned_alloc); #elif defined(VGO_freebsd) - ALIGNED_ALLOC(G_Z_LIBC_SONAME, aligned_alloc); + ALIGNED_ALLOC(VG_Z_LIBC_SONAME, aligned_alloc); ALIGNED_ALLOC(SO_SYN_MALLOC, aligned_alloc); #elif defined(VGO_darwin) - //ALIGNED_ALLOC(VG_Z_LIBC_SONAME, aligned_alloc); + ALIGNED_ALLOC(VG_Z_LIBC_SONAME, aligned_alloc); #elif defined(VGO_solaris) ALIGNED_ALLOC(VG_Z_LIBC_SONAME, aligned_alloc); @@ -2431,7 +2364,7 @@ extern int * __error(void) __attribute__((weak)); return 0; \ \ pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \ - MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \ + MALLOC_TRACE(" = %lu\n", pszB ); \ \ return pszB; \ } @@ -2577,6 +2510,17 @@ static size_t my_malloc_size ( void* zone, void* ptr ) return res; } +#define ZONE_DESTROY(soname, fnname) \ + \ + void VG_REPLACE_FUNCTION_EZU(10291,soname,fnname)(void* zone); \ + void VG_REPLACE_FUNCTION_EZU(10291,soname,fnname)(void* zone) \ + { \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \ + } + +ZONE_DESTROY(VG_Z_LIBC_SONAME, malloc_zone_destroy); +ZONE_DESTROY(SO_SYN_MALLOC, malloc_zone_destroy); + /* Note that the (void*) casts below are a kludge which stops compilers complaining about the fact that the replacement functions aren't really of the right type. */ @@ -2589,7 +2533,7 @@ static vki_malloc_zone_t vg_default_zone = { (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc), (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free), (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc), - NULL, // GrP fixme: destroy + (void*)VG_REPLACE_FUNCTION_EZU(10291,VG_Z_LIBC_SONAME,malloc_zone_destroy), "ValgrindMallocZone", NULL, // batch_malloc NULL, // batch_free diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 59c8f8287b..88f0c5847b 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -2041,6 +2041,28 @@ void do_client_request ( ThreadId tid ) SET_CLREQ_RETVAL(tid, RUNNING_ON_VALGRIND+1); break; + case VG_USERREQ__VALGRIND_REPLACES_MALLOC: + SET_CLREQ_RETVAL(tid, VG_(needs).malloc_replacement); + break; + + case VG_USERREQ__VALGRIND_GET_TOOLNAME: { + HChar* buf = (HChar *)arg[1]; + SizeT len_needed = VG_(strlen)(VG_(clo_toolname)) + 1; + SizeT buflen = (SizeT)arg[2]; + if (buflen > 0) { + if (buf != NULL) { + VG_(strncpy)(buf, VG_(clo_toolname), buflen); + if (len_needed > buflen) { + buf[buflen-1] = '\0'; + } + VG_TRACK( post_mem_write, Vg_CoreClientReq, tid, + (Addr)buf, VG_MIN(len_needed, buflen)); + } + } + SET_CLREQ_RETVAL(tid, len_needed); + break; + } + case VG_USERREQ__PRINTF: { const HChar* format = (HChar *)arg[1]; /* JRS 2010-Jan-28: this is DEPRECATED; use the diff --git a/coregrind/m_sigframe/sigframe-amd64-freebsd.c b/coregrind/m_sigframe/sigframe-amd64-freebsd.c index 084f177f9d..8b5ac04745 100644 --- a/coregrind/m_sigframe/sigframe-amd64-freebsd.c +++ b/coregrind/m_sigframe/sigframe-amd64-freebsd.c @@ -10,7 +10,7 @@ Copyright (C) 2000-2009 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2024 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or diff --git a/coregrind/m_sigframe/sigframe-x86-freebsd.c b/coregrind/m_sigframe/sigframe-x86-freebsd.c index 73c51fcae7..6795f9f5b3 100644 --- a/coregrind/m_sigframe/sigframe-x86-freebsd.c +++ b/coregrind/m_sigframe/sigframe-x86-freebsd.c @@ -10,7 +10,7 @@ Copyright (C) 2000-2009 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2024 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index a914cd0c28..17069df415 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -1041,7 +1041,7 @@ extern void my_sigreturn(void); ".text\n" \ ".globl my_sigreturn\n" \ "my_sigreturn:\n" \ - " movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \ + " movl $" VG_STRINGIFY(__NR_darwin_fake_sigreturn) ",%eax\n" \ " int $0x80\n" #elif defined(VGP_amd64_darwin) @@ -1049,7 +1049,7 @@ extern void my_sigreturn(void); ".text\n" \ ".globl my_sigreturn\n" \ "my_sigreturn:\n" \ - " movq $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%rax\n" \ + " movq $" VG_STRINGIFY(__NR_darwin_fake_sigreturn) ",%rax\n" \ " syscall\n" #elif defined(VGP_s390x_linux) @@ -1693,7 +1693,7 @@ const HChar *VG_(signame)(Int sigNo) /* Hit ourselves with a signal using the default handler */ void VG_(kill_self)(Int sigNo) { - Int r; + Int r __attribute__((unused)); vki_sigset_t mask, origmask; vki_sigaction_toK_t sa, origsa2; vki_sigaction_fromK_t origsa; diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index f9d4eaf24d..d727be1950 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -46,6 +46,11 @@ #include "pub_core_trampoline.h" #include "config.h" +#if defined(VGO_darwin) +// FIXME PJF this is bad (it's a syswrap private function) +// but the alternative for the moment is crashes when trying to produce stack traces +extern Bool ML_(safe_to_deref) ( const void *start, SizeT size ); +#endif /*------------------------------------------------------------*/ /*--- ---*/ @@ -691,7 +696,20 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, fact that we are prodding at & ((UWord*)fp)[1] and so need to adjust the limit check accordingly. Omitting this has been observed to cause segfaults on rare occasions. */ - if (fp_min <= uregs.xbp && uregs.xbp <= fp_max - 1 * sizeof(UWord)) { + if (fp_min <= uregs.xbp && uregs.xbp <= fp_max - 1 * sizeof(UWord) +#if defined(VGO_darwin) + // FIXME PJF temporary? workaround for segfaults + // without this extra check there will be some SIGSEGVs which end stuck + // in an infinite loop + + // The faulting address seems to be in a fairly small rw- mapping + // (according to lldb) + // happens in Helgrind multithread apps, error arises in + // sync_signalhandler (called from darwin_signal_demux with signal 11) + + && ML_(safe_to_deref)((void*)uregs.xbp, 2*sizeof(UWord)) +#endif + ) { /* fp looks sane, so use it. */ uregs.xip = (((UWord*)uregs.xbp)[1]); if (0 == uregs.xip || 1 == uregs.xip) break; diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c index cb3c603f8f..eb7d6ee9a7 100644 --- a/coregrind/m_syscall.c +++ b/coregrind/m_syscall.c @@ -768,8 +768,8 @@ extern UWord do_syscall_WRK ( UWord a5, /* %r9 */ UWord a6, /* 8(%rsp) */ UWord a7, /* 16(%rsp) */ - UInt *flags, /* 32(%rsp) */ - UWord *rv2 /* 40(%rsp) */ + UInt *flags, /* 24(%rsp) */ + UWord *rv2 /* 32(%rsp) */ ); asm( ".text\n" @@ -808,7 +808,7 @@ asm( * Arguments a1 to a7 are in registers x0 to x6. * Which is just what we want for a syscall. * - * The syscall number is in x9 + * The syscall number is in x7 * The flags are at the top of the stack, sp and * second return value at sp+8. */ @@ -823,7 +823,7 @@ asm( ".text\n" ".globl do_syscall_WRK\n" "do_syscall_WRK:\n" - " mov x8, x9\n" // get the syscall number from x9 + " mov x8, x7\n" // get the syscall number from x7 " svc 0x0\n" // do the syscall " mov x9, 1\n" // flags for error will be 1 or 0 " csel x9, x9, xzr, cs\n" // conditionally select 1 or 0 into x9 diff --git a/coregrind/m_syswrap/priv_syswrap-darwin.h b/coregrind/m_syswrap/priv_syswrap-darwin.h index 67c3412d36..20817c2525 100644 --- a/coregrind/m_syswrap/priv_syswrap-darwin.h +++ b/coregrind/m_syswrap/priv_syswrap-darwin.h @@ -39,14 +39,6 @@ void start_thread_NORETURN ( Word arg ); void assign_port_name(mach_port_t port, const char *name); void record_named_port(ThreadId tid, mach_port_t port, mach_port_right_t right, const char *name); -extern const SyscallTableEntry ML_(mach_trap_table)[]; -extern const SyscallTableEntry ML_(syscall_table)[]; -extern const SyscallTableEntry ML_(mdep_trap_table)[]; - -extern const UInt ML_(syscall_table_size); -extern const UInt ML_(mach_trap_table_size); -extern const UInt ML_(mdep_trap_table_size); - void VG_(show_open_ports)(void); Bool ML_(sync_mappings)(const HChar *when, const HChar *where, UWord num); @@ -240,7 +232,7 @@ DECL_TEMPLATE(darwin, csops_audittoken); // 170 // NYI kdebug_typefilter // 177 #endif /* DARWIN_VERS >= DARWIN_10_12 */ #if DARWIN_VERS >= DARWIN_10_11 -// NYI kdebug_trace_string // 178 +DECL_TEMPLATE(darwin, kdebug_trace_string); // 178 #endif /* DARWIN_VERS >= DARWIN_10_11 */ // 179 DECL_TEMPLATE(darwin, kdebug_trace); // 180 @@ -248,7 +240,7 @@ DECL_TEMPLATE(darwin, kdebug_trace); // 180 DECL_TEMPLATE(darwin, setegid); // 182 DECL_TEMPLATE(darwin, seteuid); // 183 DECL_TEMPLATE(darwin, sigreturn); // 184 -DECL_TEMPLATE(darwin, FAKE_SIGRETURN); +DECL_TEMPLATE(darwin, fake_sigreturn); // 1000 // NYI chud 185 #if DARWIN_VERS >= DARWIN_10_13 // NYI thread_selfcounts // 186 @@ -282,7 +274,7 @@ DECL_TEMPLATE(darwin, __sysctl); // 202 // 213 Reserved for AppleTalk // NYI kqueue_from_portset_np 214 // NYI kqueue_portset_np 215 -// NYI mkcomplex 216 +DECL_TEMPLATE(darwin, open_dprotected_np) // 216 // NYI statv 217 // NYI lstatv 218 // NYI fstatv 219 @@ -370,7 +362,9 @@ DECL_TEMPLATE(darwin, gettid); // 286 // NYI mkfifo_extended 291 // NYI mkdir_extended 292 // NYI identitysvc 293 -// NYI shared_region_check_np 294 +#if DARWIN_VERS >= DARWIN_11_00 +DECL_TEMPLATE(darwin, shared_region_check_np); // 294 +#endif // NYI shared_region_map_np 295 #if DARWIN_VERS >= DARWIN_10_6 // NYI vm_pressure_monitor 296 @@ -548,7 +542,9 @@ DECL_TEMPLATE(darwin, fileport_makeport); // 430 // NYI pid_shutdown_sockets 436 #endif /* DARWIN_VERS >= DARWIN_10_10 */ // old old shared_region_slide_np 437 -// NYI shared_region_map_and_slide_np // 438 +#if DARWIN_VERS >= DARWIN_11_00 +DECL_TEMPLATE(darwin, shared_region_map_and_slide_np); // 438 +#endif // NYI kas_info // 439 // NYI memorystatus_control // 440 DECL_TEMPLATE(darwin, guarded_open_np); // 441 @@ -589,7 +585,7 @@ DECL_TEMPLATE(darwin, faccessat); // 466 // NYI fstatat // 469 DECL_TEMPLATE(darwin, fstatat64); // 470 // NYI linkat // 471 -// NYI unlinkat // 472 +DECL_TEMPLATE(darwin, unlinkat); // 472 DECL_TEMPLATE(darwin, readlinkat); // 473 // NYI symlinkat // 474 DECL_TEMPLATE(darwin, mkdirat); // 475 @@ -613,7 +609,7 @@ DECL_TEMPLATE(darwin, guarded_writev_np); // 487 // NYI stack_snapshot_with_config // 491 // NYI microstackshot // 492 // NYI grab_pgo_data // 493 -// NYI persona // 494 +DECL_TEMPLATE(darwin, persona); // 494 // 495 // 496 // 497 @@ -654,6 +650,42 @@ DECL_TEMPLATE(darwin, abort_with_payload); // 521 // NYI ntp_gettime // 528 // NYI os_fault_with_payload // 529 #endif /* DARWIN_VERS >= DARWIN_10_13 */ +#if DARWIN_VERS >= DARWIN_10_14 +// NYI kqueue_workloop_ctl // 530 +// NYI __mach_bridge_remote_time // 531 +#endif /* DARWIN_VERS >= DARWIN_10_14 */ +#if DARWIN_VERS >= DARWIN_10_15 +// NYI coalition_ledger // 532 +// NYI log_data // 533 +// NYI memorystatus_available_memory // 534 +#endif +#if DARWIN_VERS >= DARWIN_11_00 +DECL_TEMPLATE(darwin, objc_bp_assist_cfg_np); // 535 +// NYI shared_region_map_and_slide_2_np // 536 +// NYI pivot_root // 537 +// NYI task_inspect_for_pid // 538 +DECL_TEMPLATE(darwin, task_read_for_pid); // 539 +// NYI sys_preadv // 540 +// NYI sys_pwritev // 541 +// NYI sys_preadv_nocancel // 542 +// NYI sys_pwritev_nocancel // 543 +DECL_TEMPLATE(darwin, ulock_wait2); // 544 +// NYI proc_info_extended_id // 545 +#endif +#if DARWIN_VERS >= DARWIN_12_00 +// NYI tracker_action // 546 +// NYI debug_syscall_reject // 547 +#endif +#if DARWIN_VERS >= DARWIN_13_00 +// NYI sys_debug_syscall_reject_config // 548 +// NYI graftdmg // 549 +DECL_TEMPLATE(darwin, map_with_linking_np); // 550 +// NYI freadlink // 551 +// NYI sys_record_system_event // 552 +// NYI mkfifoat // 553 +// NYI mknodat // 554 +// NYI ungraftdmg // 555 +#endif // Mach message helpers DECL_TEMPLATE(darwin, mach_port_set_context); @@ -730,11 +762,13 @@ DECL_TEMPLATE(darwin, mach_msg_bootstrap); DECL_TEMPLATE(darwin, mach_msg_host); DECL_TEMPLATE(darwin, mach_msg_task); DECL_TEMPLATE(darwin, mach_msg_thread); +DECL_TEMPLATE(darwin, mach_voucher_extract_attr_recipe_trap); // MACH 72 // Mach traps #if DARWIN_VERS >= DARWIN_10_8 -DECL_TEMPLATE(darwin, kernelrpc_mach_vm_allocate_trap); -DECL_TEMPLATE(darwin, kernelrpc_mach_vm_deallocate_trap); +DECL_TEMPLATE(darwin, kernelrpc_mach_vm_allocate_trap); // MACH 10 +DECL_TEMPLATE(darwin, kernelrpc_mach_vm_purgable_control_trap); // MACH 11 +DECL_TEMPLATE(darwin, kernelrpc_mach_vm_deallocate_trap); // MACH 12 DECL_TEMPLATE(darwin, kernelrpc_mach_vm_protect_trap); DECL_TEMPLATE(darwin, kernelrpc_mach_vm_map_trap); DECL_TEMPLATE(darwin, kernelrpc_mach_port_allocate_trap); @@ -768,6 +802,7 @@ DECL_TEMPLATE(darwin, semaphore_wait_signal); DECL_TEMPLATE(darwin, semaphore_timedwait); DECL_TEMPLATE(darwin, semaphore_timedwait_signal); DECL_TEMPLATE(darwin, task_for_pid); +DECL_TEMPLATE(darwin, task_name_for_pid); DECL_TEMPLATE(darwin, pid_for_task); #if DARWIN_VERS >= DARWIN_10_13 @@ -791,6 +826,20 @@ DECL_TEMPLATE(darwin, iokit_user_client_trap); DECL_TEMPLATE(darwin, swtch); DECL_TEMPLATE(darwin, swtch_pri); +#if DARWIN_VERS >= DARWIN_10_14 +DECL_TEMPLATE(darwin, kernelrpc_mach_port_get_attributes_trap); +#endif /* DARWIN_VERS >= DARWIN_10_14 */ + +#if DARWIN_VERS >= DARWIN_10_15 +DECL_TEMPLATE(darwin, task_restartable_ranges_register); +DECL_TEMPLATE(darwin, kernelrpc_mach_port_type_trap); +DECL_TEMPLATE(darwin, kernelrpc_mach_port_request_notification_trap); +#endif /* DARWIN_VERS >= DARWIN_10_15 */ + +#if DARWIN_VERS >= DARWIN_13_00 +DECL_TEMPLATE(darwin, mach_msg2); +#endif + // Machine-dependent traps DECL_TEMPLATE(darwin, thread_fast_set_cthread_self); @@ -826,7 +875,7 @@ extern void pthread_hijack_asm(void); extern void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, Addr stacksize, Addr flags, Addr sp); extern void wqthread_hijack_asm(void); -extern void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, Int reuse, Addr sp); +extern void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, UInt reuse, Int kevent_count, Addr sp); extern Addr pthread_starter; extern Addr wqthread_starter; diff --git a/coregrind/m_syswrap/priv_syswrap-freebsd.h b/coregrind/m_syswrap/priv_syswrap-freebsd.h index 6aaa36abab..2251d91dce 100644 --- a/coregrind/m_syswrap/priv_syswrap-freebsd.h +++ b/coregrind/m_syswrap/priv_syswrap-freebsd.h @@ -9,7 +9,7 @@ Copyright (C) 2000-2008 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -50,7 +50,7 @@ DECL_TEMPLATE(freebsd, sys_exit) // 1 DECL_TEMPLATE(freebsd, sys_fork) // 2 // generic read 3 // generic write 4 -// generic open 5 +DECL_TEMPLATE(freebsd, sys_open) // 5 // generic close 6 // generic wait4 7 // generic link 9 @@ -84,7 +84,7 @@ DECL_TEMPLATE(freebsd, sys_fchflags) // 35 DECL_TEMPLATE(freebsd, sys_freebsd10_pipe) // 42 // generic getegid 43 // generic profil redirect to ni_syscall 44 -// sys_ktrace refirect to ni_syscall 45 +// sys_ktrace redirect to ni_syscall 45 // generic getgid 47 DECL_TEMPLATE(freebsd, sys_getlogin) // 49 DECL_TEMPLATE(freebsd, sys_setlogin) // 50 @@ -552,6 +552,10 @@ DECL_TEMPLATE(freebsd, sys_inotify_rm_watch) // 594 DECL_TEMPLATE(freebsd, sys_jail_attach_jd) // 597 DECL_TEMPLATE(freebsd, sys_jail_remove_jd) // 598 +DECL_TEMPLATE(freebsd, sys_kexec_load) // 599 +// generic sys_pdrfork redirect to ni_syscall 600 +DECL_TEMPLATE(freebsd, sys_pdwait) // 601 +// generic renameat2 602 DECL_TEMPLATE(freebsd, sys_fake_sigreturn) diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index a59cdf5efd..7bbb3e2a3c 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -101,6 +101,9 @@ ML_(notify_core_and_tool_of_munmap) ( Addr a, SizeT len ); extern void ML_(notify_core_and_tool_of_mprotect) ( Addr a, SizeT len, Int prot ); +extern void +ML_(notify_core_and_tool_of_madv_guard) ( Addr a, SizeT len, Bool install ); + extern void ML_(pre_mem_read_sockaddr) ( ThreadId tid, const HChar *description, struct vki_sockaddr *sa, UInt salen ); @@ -120,14 +123,6 @@ void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg); extern void ML_(pre_argv_envp)(Addr a, ThreadId tid, const HChar *s1, const HChar *s2); -extern Bool -ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, - int flags); - -extern Bool -ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, - int flags); - /* Helper function for generic mprotect and linux pkey_mprotect. */ extern void handle_sys_mprotect (ThreadId tid, SyscallStatus *status, Addr *addr, SizeT *len, Int *prot); @@ -276,6 +271,7 @@ DECL_TEMPLATE(generic, sys_getdents64); // * (SVr4,SVID?) DECL_TEMPLATE(generic, sys_statfs64); // * (?) DECL_TEMPLATE(generic, sys_fstatfs64); // * (?) DECL_TEMPLATE(generic, sys_mlock2); // * L +DECL_TEMPLATE(generic, sys_renameat2); // * L, F /* --------------------------------------------------------------------- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 21cb32829a..38755b60c8 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -181,7 +181,6 @@ DECL_TEMPLATE(linux, sys_futimesat); DECL_TEMPLATE(linux, sys_newfstatat); DECL_TEMPLATE(linux, sys_unlinkat); DECL_TEMPLATE(linux, sys_renameat); -DECL_TEMPLATE(linux, sys_renameat2); DECL_TEMPLATE(linux, sys_linkat); DECL_TEMPLATE(linux, sys_symlinkat); DECL_TEMPLATE(linux, sys_readlinkat); @@ -372,6 +371,13 @@ DECL_TEMPLATE(linux, sys_statmount); // Since Linux 6.10 DECL_TEMPLATE(linux, sys_mseal); +DECL_TEMPLATE(linux, sys_lsm_get_self_attr); +DECL_TEMPLATE(linux, sys_lsm_set_self_attr); +DECL_TEMPLATE(linux, sys_lsm_list_modules); + +// Since Linux 6.17-rc1 +DECL_TEMPLATE(linux, sys_file_getattr); +DECL_TEMPLATE(linux, sys_file_setattr); /* --------------------------------------------------------------------- Wrappers for sockets and ipc-ery. These are split into standalone diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index 0ce26bd33d..45c0f03fda 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -50,7 +50,14 @@ /* Arguments for a syscall. */ typedef struct SyscallArgs { - Word sysno; + Word canonical_sysno; +#if defined(VGO_freebsd) || defined(VGO_darwin) + /* + * This may be the same as canonical_sysno (normal syscalls) + * Or it may be __NR_syscall or __NR___syscall + */ + Word original_sysno; +#endif RegWord arg1; RegWord arg2; RegWord arg3; @@ -59,9 +66,6 @@ typedef RegWord arg6; RegWord arg7; RegWord arg8; -#if defined(VGO_freebsd) - Word klass; -#endif } SyscallArgs; @@ -121,7 +125,7 @@ typedef Int s_arg6; Int s_arg7; Int s_arg8; -# elif defined(VGP_amd64_freebsd) +# elif defined(VGP_amd64_freebsd) || defined(VGP_amd64_darwin) Int o_arg1; Int o_arg2; Int o_arg3; @@ -164,7 +168,7 @@ typedef Int s_arg6; Int s_arg7; Int s_arg8; -# elif defined(VGP_amd64_darwin) || defined(VGP_amd64_solaris) +# elif defined(VGP_amd64_solaris) Int o_arg1; Int o_arg2; Int o_arg3; @@ -240,12 +244,9 @@ extern SyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno ); #elif defined(VGO_darwin) -/* XXX: Darwin still uses the old scheme of exposing the table - array(s) and size(s) directly to syswrap-main.c. This should be - fixed. */ -extern const SyscallTableEntry ML_(syscall_table)[]; -extern const UInt ML_(syscall_table_size); +extern +const SyscallTableEntry* ML_(get_darwin_syscall_entry)( UInt sysno ); #elif defined(VGO_solaris) extern @@ -363,7 +364,7 @@ const SyscallTableEntry* ML_(get_freebsd_syscall_entry)( UInt sysno ); /* Reference to the syscall's arguments -- the ones which the pre-wrapper may have modified, not the original copy. */ -#define SYSNO (arrghs->sysno) +#define SYSNO (arrghs->canonical_sysno) #define ARG1 (arrghs->arg1) #define ARG2 (arrghs->arg2) #define ARG3 (arrghs->arg3) @@ -413,6 +414,18 @@ static inline UWord getERR ( SyscallStatus* st ) { return sr_Err(st->sres); } +/* + * On FreeBSD, syscalls can return an error code directly rather than + * setting the carry flag and returning the error code (with the + * syscall wrapper putting the error code into errno and returning -1). + * + * It is the carry flag that triggers using errno and returning -1. + * So we want a macro that sets the return value but does not set + * the error flag. Normally that's the job of SET_STATUS_Success. + * Since using a "Success" macro for a failure error code would + * be misleading this macro is used as an alias to make it more readable. + */ +#define SET_STATUS_FailureErrorCode SET_STATUS_Success /* Set the current result status/value in various ways. */ #define SET_STATUS_Success(zzz) \ @@ -490,7 +503,7 @@ static inline UWord getERR ( SyscallStatus* st ) { # define PRA7(s,t,a) PSRAn(7,s,t,a) # define PRA8(s,t,a) PSRAn(8,s,t,a) -#elif defined(VGP_amd64_freebsd) +#elif defined(VGP_amd64_freebsd) || defined(VGP_amd64_darwin) /* Up to 8 parameters, 6 in registers, 2 on the stack. */ /* or 7 in registers and 3 on the stack */ # define PRA1(s,t,a) PRRAn(1,s,t,a) @@ -530,7 +543,7 @@ static inline UWord getERR ( SyscallStatus* st ) { # define PRA7(s,t,a) PSRAn(7,s,t,a) # define PRA8(s,t,a) PSRAn(8,s,t,a) -#elif defined(VGP_amd64_darwin) || defined(VGP_amd64_solaris) +#elif defined(VGP_amd64_solaris) /* Up to 8 parameters, 6 in registers, 2 on the stack. */ # define PRA1(s,t,a) PRRAn(1,s,t,a) # define PRA2(s,t,a) PRRAn(2,s,t,a) diff --git a/coregrind/m_syswrap/syscall-amd64-darwin.S b/coregrind/m_syswrap/syscall-amd64-darwin.S index 9abfd998f5..fbc81ff5df 100644 --- a/coregrind/m_syswrap/syscall-amd64-darwin.S +++ b/coregrind/m_syswrap/syscall-amd64-darwin.S @@ -67,7 +67,8 @@ void* guest_state, // rsi const vki_sigset_t *sysmask, // rdx const vki_sigset_t *postmask, // rcx - Int sigsetSzB) // r8 + Int sigsetSzB, // r8 + UChar *cflag) // r9 Note that sigsetSzB is totally ignored (and irrelevant). */ @@ -90,6 +91,7 @@ pushq %rdx // -24(%rbp) sysmask pushq %rcx // -32(%rbp) postmask pushq %r8 // -40(%rbp) sigsetSzB + pushq %r9 // -48(%rbp) cflag // stack is now aligned L_$0_1: /* Even though we can't take a signal until the sigprocmask completes, @@ -97,18 +99,13 @@ L_$0_1: /* Even though we can't take a signal until the sigprocmask completes, If rip is in the range [1,2), the syscall hasn't been started yet */ /* Set the signal mask which should be current during the syscall. */ - /* GrP fixme signals - DDD: JRS fixme: use __NR___pthread_sigmask, not __NR_rt_sigprocmask - movq $__NR_rt_sigprocmask, %rax // syscall # - movq $VKI_SIG_SETMASK, %rdi // how + movq $$__NR___pthread_sigmask, %rax // syscall # + movq $$VKI_SIG_SETMASK, %rdi // how movq -24(%rbp), %rsi // sysmask movq -32(%rbp), %rdx // postmask - movq -40(%rbp), %r10 // sigsetSzB in r10 not rcx - DDD: fixme return address syscall - jnc 7f // sigprocmask failed - */ + jc L_$0_7 // sigprocmask failed /* OK, that worked. Now do the syscall proper. */ @@ -140,58 +137,40 @@ L_$0_3: /* In the range [3, 4), the syscall result is in %rax, but hasn't been committed to RAX. */ /* stack contents: 3 words for syscall above, plus our prologue */ - setc 0(%rsp) /* stash returned carry flag */ movq -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */ movq %rax, OFFSET_amd64_RAX(%r11) /* save back to RAX */ movq %rdx, OFFSET_amd64_RDX(%r11) /* save back to RDX */ .if $0 == UNIX - /* save carry flag to VEX */ - xor %rax, %rax - movb 0(%rsp), %al - movq %rax, %rdi /* arg1 = new flag */ - movq %r11, %rsi /* arg2 = vex state */ - addq $$24, %rsp /* remove syscall parameters */ - movl $$1, OFFSET_amd64_SETC(%r11) - call _LibVEX_GuestAMD64_put_rflag_c - movq -16(%rbp), %r11 - movl $$0, OFFSET_amd64_SETC(%r11) + movq -48(%rbp), %rcx + setc 0(%rcx) /* save returned carry flag */ .else - addq $$24, %rsp /* remove syscall parameters*/ + addq $$24, %rsp /* remove syscall parameters*/ .endif L_$0_4: /* Re-block signals. If eip is in [4,5), then the syscall is complete and we needn't worry about it. */ - /* GrP fixme signals - DDD: JRS fixme: use __NR___pthread_sigmask, not __NR_rt_sigprocmask - PUSH_di_si_dx_cx_8 - - movq $__NR_rt_sigprocmask, %rax // syscall # - movq $VKI_SIG_SETMASK, %rdi // how - movq %rcx, %rsi // postmask + movq $$__NR___pthread_sigmask, %rax // syscall # + movq $$VKI_SIG_SETMASK, %rdi // how + movq -32(%rbp), %rsi // postmask xorq %rdx, %rdx // NULL - movq %r8, %r10 // sigsetSzB - DDD: fixme return address syscall - POP_di_si_dx_cx_8 + jc L_$0_7 // sigprocmask failed - jnc 7f // sigprocmask failed - */ L_$0_5: /* now safe from signals */ movq $$0, %rax /* SUCCESS */ movq %rbp, %rsp popq %rbp ret -/* GrP fixme signals L_$0_7: // failure: return 0x8000 | error code - DDD: fixme return value + andq $$0x7FFF, %rax + orq $$0x8000, %rax movq %rbp, %rsp popq %rbp ret -*/ .endmacro diff --git a/coregrind/m_syswrap/syscall-amd64-freebsd.S b/coregrind/m_syswrap/syscall-amd64-freebsd.S index 0d25efdccc..5b298f7bde 100644 --- a/coregrind/m_syswrap/syscall-amd64-freebsd.S +++ b/coregrind/m_syswrap/syscall-amd64-freebsd.S @@ -9,7 +9,7 @@ Copyright (C) 2000-2008 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2025 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -69,7 +69,8 @@ void* guest_state, // rsi const vki_sigset_t *sysmask, // rdx const vki_sigset_t *postmask, // rcx - Int sigsetSzB) // r8 + Int sigsetSzB, // r8 + UCHar *cflag) // r9 */ /* from vki_arch.h */ @@ -85,6 +86,7 @@ ML_(do_syscall_for_client_WRK): pushq %rdx // -24(%rbp) sysmask pushq %rcx // -32(%rbp) postmask pushq %r8 // -40(%rbp) sigsetSzB + pushq %r9 // -48(%rbp) cflag 1: /* Even though we can't take a signal until the sigprocmask completes, start the range early. @@ -132,23 +134,12 @@ ML_(do_syscall_for_client_WRK): 3: /* In the range [3, 4), the syscall result is in %rax, but hasn't been committed to RAX. */ - /* stack contents: 3 words for syscall above, plus our prologue */ - setc 0(%rsp) /* stash returned carry flag */ - movq -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */ + movq -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */ movq %rax, OFFSET_amd64_RAX(%r11) /* save back to RAX */ movq %rdx, OFFSET_amd64_RDX(%r11) /* save back to RDX */ - - /* save carry flag to VEX */ - xorq %rax, %rax - movb 0(%rsp), %al - movq %rax, %rdi /* arg1 = new flag */ - movq %r11, %rsi /* arg2 = vex state */ - addq $24, %rsp /* remove syscall parameters */ - movl $1, OFFSET_amd64_SETC(%r11) - call LibVEX_GuestAMD64_put_rflag_c - movq -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */ - movl $0, OFFSET_amd64_SETC(%r11) + movq -48(%rbp), %rcx + setc 0(%rcx) /* save returned carry flag */ 4: /* Re-block signals. If eip is in [4,5), then the syscall is complete and we needn't worry about it. */ diff --git a/coregrind/m_syswrap/syscall-arm64-freebsd.S b/coregrind/m_syswrap/syscall-arm64-freebsd.S index fb7c687687..36ec03cd08 100644 --- a/coregrind/m_syswrap/syscall-arm64-freebsd.S +++ b/coregrind/m_syswrap/syscall-arm64-freebsd.S @@ -7,7 +7,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright (C) 2024 Paul Floyd + Copyright (C) 2024-2025 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -67,7 +67,8 @@ void* guest_state, // x1 const vki_sigset_t *sysmask, // x2 const vki_sigset_t *postmask, // x3 - Int nsigwords) // x4 + Int nsigwords, // x4 + UChar *cflag, // x5 */ /* from vki-arm64-freebsd.h */ #define VKI_SIG_SETMASK 3 @@ -110,23 +111,15 @@ ML_(do_syscall_for_client_WRK): 2: svc 0x00000000 3: - /* stash returned carry flag */ - mov x4, 1 - csel x4, x4, xzr, cs ldr x5, [sp, #8] /* saved x1 == guest_state */ str x0, [x5, #OFFSET_arm64_X0] str x1, [x5, #OFFSET_arm64_X1] - - /* save carry flag to VEX */ - mov x0, x4 /* arg1 = new flag */ - ldr x1, [sp, #8] /* arg2 = vex state */ - mov x20, 1 - str x20, [x1, #OFFSET_arm64_SETC] - bl LibVEX_GuestARM64_put_nzcv_c - ldr x1, [sp, #8] /* arg2 = vex state */ - mov x20, 0 - str x20, [x1, #OFFSET_arm64_SETC] + /* stash returned carry flag */ + mov x4, 1 + csel x4, x4, xzr, cs + ldr x5, [sp, #40] /* saved x5 == cflag */ + strb w4, [x5] 4: mov x8, #__NR_sigprocmask diff --git a/coregrind/m_syswrap/syscall-x86-darwin.S b/coregrind/m_syswrap/syscall-x86-darwin.S index 393cc8eb72..4ac1ef23a2 100644 --- a/coregrind/m_syswrap/syscall-x86-darwin.S +++ b/coregrind/m_syswrap/syscall-x86-darwin.S @@ -67,7 +67,8 @@ void* guest_state, // ebp+12 const vki_sigset_t *sysmask, // ebp+16 const vki_sigset_t *postmask, // ebp+20 - Int sigsetSzB) // ebp+24 + Int sigsetSzB, // ebp+24 + UChar *cflag) // ebp+28 Note that sigsetSzB is totally ignored (and irrelevant). */ @@ -145,22 +146,12 @@ L_$0_2: L_$0_3: /* In the range [3, 4), the syscall result is in %eax and %edx and C, but hasn't been committed to the thread state. */ - setc 0(%esp) /* stash returned carry flag */ movl 12(%ebp), %ecx movl %eax, OFFSET_x86_EAX(%ecx) /* save EAX to vex */ movl %edx, OFFSET_x86_EDX(%ecx) /* save EDX to vex */ .if $0 == UNIX - /* UNIX: save carry flag to vex */ - subl $$12, %esp - movl %ecx, 4(%esp) - movl $$0, 0(%esp) - movb 12(%esp), %al - movb %al, 0(%esp) - movl $$1, OFFSET_x86_SETC(%ecx) - call _LibVEX_GuestX86_put_eflag_c - movl 12(%ebp), %ecx - movl $$0, OFFSET_x86_SETC(%ecx) - addl $$12, %esp + movl 28(%ebp), %ecx + setc 0(%ecx) /* save returned carry flag */ .endif L_$0_4: /* Re-block signals. If eip is in [4,5), then the syscall is diff --git a/coregrind/m_syswrap/syscall-x86-freebsd.S b/coregrind/m_syswrap/syscall-x86-freebsd.S index 9e69d85bec..6bcc8c75d7 100644 --- a/coregrind/m_syswrap/syscall-x86-freebsd.S +++ b/coregrind/m_syswrap/syscall-x86-freebsd.S @@ -9,7 +9,7 @@ Copyright (C) 2000-2007 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2025 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -69,7 +69,8 @@ void* guest_state, // ebp+12 const vki_sigset_t *sysmask, // ebp+16 const vki_sigset_t *postmask, // ebp+20 - Int sigsetSzB) // ebp+24 + Int sigsetSzB, // ebp+24 + UChar* cflag) // ebp+28 Note that sigsetSzB is totally ignored (and irrelevant). */ @@ -133,21 +134,11 @@ ML_(do_syscall_for_client_WRK): 3: /* In the range [3, 4), the syscall result is in %eax and %edx and C, but hasn't been committed to the thread state. */ - setc 0(%esp) /* stash returned carry flag */ movl 12(%ebp), %ecx movl %eax, OFFSET_x86_EAX(%ecx) /* save EAX to vex */ movl %edx, OFFSET_x86_EDX(%ecx) /* save EDX to vex */ - /* save carry flag to vex */ - subl $12, %esp - movl %ecx, 4(%esp) - movl $0, 0(%esp) - movb 12(%esp), %al - movb %al, 0(%esp) - movl $1, OFFSET_x86_SETC(%ecx) - call LibVEX_GuestX86_put_eflag_c - movl 12(%ebp), %ecx - movl $0, OFFSET_x86_SETC(%ecx) - addl $12, %esp + movl 28(%ebp), %ecx + setc 0(%ecx) /* save returned carry flag */ 4: /* Re-block signals. If eip is in [4,5), then the syscall is complete and we needn't worry about it. */ diff --git a/coregrind/m_syswrap/syswrap-amd64-darwin.c b/coregrind/m_syswrap/syswrap-amd64-darwin.c index e6f284c9a6..01ebf1b7cb 100644 --- a/coregrind/m_syswrap/syswrap-amd64-darwin.c +++ b/coregrind/m_syswrap/syswrap-amd64-darwin.c @@ -416,7 +416,7 @@ void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, asm( ".globl _wqthread_hijack_asm\n" "_wqthread_hijack_asm:\n" -" movq %rsp,%r9\n" // original sp +" push %rsp\n" // original sp // other values stay where they are in registers " push $0\n" // fake return address " jmp _wqthread_hijack\n" @@ -431,7 +431,7 @@ asm( thread for every work item. */ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, - Int reuse, Addr sp) + UInt reuse, Int kevent_count, Addr sp) { ThreadState *tst; VexGuestAMD64State *vex; @@ -451,8 +451,8 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, if (0) VG_(printf)( "wqthread_hijack: self %#lx, kport %#lx, " - "stackaddr %#lx, workitem %#lx, reuse/flags %x, sp %#lx\n", - self, kport, stackaddr, workitem, (UInt)reuse, sp); + "stackaddr %#lx, workitem %#lx, reuse/flags %#x, kevent_count %d, sp %#lx\n", + self, kport, stackaddr, workitem, (UInt)reuse, kevent_count, sp); /* Start the thread with all signals blocked. VG_(scheduler) will set the mask correctly when we finally get there. */ @@ -476,7 +476,7 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, /* For whatever reason, tst->os_state.pthread appear to have a constant offset of 96 on 10.7, but zero on 10.6 and 10.5. No idea why. */ -# if DARWIN_VERS <= DARWIN_10_6 || DARWIN_VERS == DARWIN_10_13 +# if DARWIN_VERS <= DARWIN_10_6 || DARWIN_VERS >= DARWIN_10_13 UWord magic_delta = 0; # elif DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8 UWord magic_delta = 0x60; @@ -506,6 +506,10 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, tid, (void *)tst, tst->os_state.pthread, self); vex = &tst->arch.vex; + if (tst->os_state.pthread - magic_delta != self) { + VG_(printf)("wqthread_hijack reuse: tst->os_state.pthread %#lx vs self %#lx (diff: %#lx vs %#lx)\n", + tst->os_state.pthread, self, tst->os_state.pthread - self, magic_delta); + } vg_assert(tst->os_state.pthread - magic_delta == self); } else { @@ -525,7 +529,7 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, vex->guest_RDX = stackaddr; vex->guest_RCX = workitem; vex->guest_R8 = reuse; - vex->guest_R9 = 0; + vex->guest_R9 = kevent_count; vex->guest_RSP = sp; #if DARWIN_VERS >= DARWIN_10_12 vex->guest_GS_CONST = self + pthread_tsd_offset; diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index 3576f64b9b..0def45b075 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -9,7 +9,7 @@ Copyright (C) 2000-2005 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -859,7 +859,7 @@ PRE(sys_posix_fallocate) int, fd, vki_off_t, offset, vki_off_t, len); if (!ML_(fd_allowed)(ARG1, "posix_fallocate", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_posix_fadvise 531 @@ -873,7 +873,7 @@ PRE(sys_posix_fadvise) off_t, len, int, advice); if (!ML_(fd_allowed)(ARG1, "posix_fadvise", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_wait6 532 @@ -1025,6 +1025,18 @@ PRE(sys_cpuset_setdomain) PRE_MEM_READ( "cpuset_getdomain(mask)", ARG5, ARG4 ); } +// SYS_kexec_load 599 +// int kexec_load(uint64_t entry, unsigned long count, +// struct kexec_segment *segments, unsigned long flags); +PRE(sys_kexec_load) +{ + PRINT("sys_kexec_load ( %" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(int, "kexec_load", vki_uint64_t, entry, + unsigned long, count, struct kexec_segment*, segments, unsigned long, flag); + PRE_MEM_READ("kexec_load(segments)", ARG3, ARG2*(sizeof(struct vki_kexec_segment))); + // FIXME PJF should check the buf and bufsz fields +} + PRE(sys_fake_sigreturn) { ThreadState* tst; diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 234b056e58..1c9b0d7704 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -503,7 +503,7 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_mremap, sys_mremap), // 25 GENX_(__NR_msync, sys_msync), // 26 GENXY(__NR_mincore, sys_mincore), // 27 - GENX_(__NR_madvise, sys_madvise), // 28 + GENXY(__NR_madvise, sys_madvise), // 28 LINX_(__NR_shmget, sys_shmget), // 29 LINXY(__NR_shmat, sys_shmat), // 30 @@ -684,7 +684,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_delete_module, sys_delete_module), // 176 // (__NR_get_kernel_syms, sys_ni_syscall), // 177 // (__NR_query_module, sys_ni_syscall), // 178 - LINX_(__NR_quotactl, sys_quotactl), // 179 + LINXY(__NR_quotactl, sys_quotactl), // 179 // (__NR_nfsservctl, sys_nfsservctl), // 180 // (__NR_getpmsg, sys_ni_syscall), // 181 @@ -848,7 +848,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_finit_module, sys_finit_module), // 313 LINX_(__NR_sched_setattr, sys_sched_setattr), // 314 LINXY(__NR_sched_getattr, sys_sched_getattr), // 315 - LINX_(__NR_renameat2, sys_renameat2), // 316 + GENX_(__NR_renameat2, sys_renameat2), // 316 // LIN__(__NR_seccomp, sys_ni_syscall), // 317 LINXY(__NR_getrandom, sys_getrandom), // 318 LINXY(__NR_memfd_create, sys_memfd_create), // 319 @@ -875,7 +875,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_pkey_alloc, sys_pkey_alloc), // 330 LINX_(__NR_pkey_free, sys_pkey_free), // 331 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 333 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 333 LINXY(__NR_io_uring_setup, sys_io_uring_setup), // 425 LINXY(__NR_io_uring_enter, sys_io_uring_enter), // 426 @@ -896,7 +896,7 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -909,7 +909,12 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 LINXY(__NR_statmount, sys_statmount), // 457 LINXY(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_(__NR_mseal, sys_mseal), // 462 + LINXY(__NR_file_getattr, sys_file_getattr), // 468 + LINX_(__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 9e1b2efb48..4233ea9214 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -285,7 +285,6 @@ PRE(sys_fstatat64) PRE_REG_READ3(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf); ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); - SET_STATUS_Failure( VKI_EBADF ); PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); } @@ -708,7 +707,7 @@ static SyscallTableEntry syscall_main_table[] = { //zz //zz // Nb: get_kernel_syms() was removed 2.4-->2.6 // GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 - LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY(__NR_quotactl, sys_quotactl), // 131 GENX_(__NR_getpgid, sys_getpgid), // 132 GENX_(__NR_fchdir, sys_fchdir), // 133 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux @@ -814,7 +813,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_setfsgid32, sys_setfsgid), // 216 LINX_(__NR_pivot_root, sys_pivot_root), // 217 GENXY(__NR_mincore, sys_mincore), // 218 - GENX_(__NR_madvise, sys_madvise), // 219 + GENXY(__NR_madvise, sys_madvise), // 219 GENXY(__NR_getdents64, sys_getdents64), // 220 LINXY(__NR_fcntl64, sys_fcntl64), // 221 @@ -876,7 +875,7 @@ static SyscallTableEntry syscall_main_table[] = { GENXY(__NR_statfs64, sys_statfs64), // 268 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269 - LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux + LINXY(__NR_tgkill, sys_tgkill), // 270 */Linux GENX_(__NR_utimes, sys_utimes), // 271 GENX_(__NR_vserver, sys_ni_syscall), // 273 LINX_(__NR_mbind, sys_mbind), // 274 ?/? @@ -1012,7 +1011,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_sched_setattr, sys_sched_setattr), // 380 LINXY(__NR_sched_getattr, sys_sched_getattr), // 381 - LINX_(__NR_renameat2, sys_renameat2), // 382 + GENX_(__NR_renameat2, sys_renameat2), // 382 LINXY(__NR_getrandom, sys_getrandom), // 384 LINXY(__NR_memfd_create, sys_memfd_create), // 385 @@ -1068,7 +1067,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -1079,7 +1078,12 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 LINXY(__NR_statmount, sys_statmount), // 457 LINXY(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_(__NR_mseal, sys_mseal), // 462 + LINXY(__NR_file_getattr, sys_file_getattr), // 468 + LINX_(__NR_file_setattr, sys_file_setattr), // 469 }; diff --git a/coregrind/m_syswrap/syswrap-arm64-freebsd.c b/coregrind/m_syswrap/syswrap-arm64-freebsd.c index 29f5455c5c..c7924249d7 100644 --- a/coregrind/m_syswrap/syswrap-arm64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-arm64-freebsd.c @@ -7,7 +7,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright (C) 2024 Paul Floyd + Copyright (C) 2024-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -816,7 +816,7 @@ PRE(sys_posix_fallocate) PRE_REG_READ3(long, "posix_fallocate", int, fd, vki_off_t, offset, vki_off_t, len); if (!ML_(fd_allowed)(ARG1, "posix_fallocate", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_posix_fadvise 531 @@ -829,7 +829,7 @@ PRE(sys_posix_fadvise) PRE_REG_READ4(long, "posix_fadvise", int, fd, off_t, offset, off_t, len, int, advice); if (!ML_(fd_allowed)(ARG1, "posix_faadvise", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_wait6 532 @@ -999,6 +999,18 @@ PRE(sys_cpuset_setdomain) PRE_MEM_READ("cpuset_getdomain(mask)", ARG5, ARG4); } +// SYS_kexec_load 599 +// int kexec_load(uint64_t entry, unsigned long count, +// struct kexec_segment *segments, unsigned long flags); +PRE(sys_kexec_load) +{ + PRINT("sys_kexec_load ( %" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(int, "kexec_load", vki_uint64_t, entry, + unsigned long, count, struct kexec_segment*, segments, unsigned long, flag); + PRE_MEM_READ("kexec_load(segments)", ARG3, ARG2*(sizeof(struct vki_kexec_segment))); + // FIXME PJF should check the buf and bufsz fields +} + PRE(sys_fake_sigreturn) { ThreadState* tst; diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c index 418c78443f..4debcf8ab2 100644 --- a/coregrind/m_syswrap/syswrap-arm64-linux.c +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c @@ -608,7 +608,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_(__NR_close, sys_close), // 57 LINX_(__NR_vhangup, sys_vhangup), // 58 LINXY(__NR_pipe2, sys_pipe2), // 59 - LINX_(__NR_quotactl, sys_quotactl), // 60 + LINXY(__NR_quotactl, sys_quotactl), // 60 GENXY(__NR_getdents64, sys_getdents64), // 61 LINX_(__NR_lseek, sys_lseek), // 62 GENXY(__NR_read, sys_read), // 63 @@ -679,7 +679,7 @@ static SyscallTableEntry syscall_main_table[] = { // (__NR_restart_syscall, sys_ni_syscall), // 128 GENX_(__NR_kill, sys_kill), // 129 LINXY(__NR_tkill, sys_tkill), // 130 - LINX_(__NR_tgkill, sys_tgkill), // 131 + 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 @@ -781,7 +781,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_(__NR_mlockall, sys_mlockall), // 230 LINX_(__NR_munlockall, sys_munlockall), // 231 GENXY(__NR_mincore, sys_mincore), // 232 - GENX_(__NR_madvise, sys_madvise), // 233 + GENXY(__NR_madvise, sys_madvise), // 233 LINX_(__NR_remap_file_pages, sys_remap_file_pages), // 234 LINX_(__NR_mbind, sys_mbind), // 235 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 236 @@ -808,7 +808,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_finit_module, sys_finit_module), // 273 LINX_(__NR_sched_setattr, sys_sched_setattr), // 274 LINXY(__NR_sched_getattr, sys_sched_getattr), // 275 - LINX_(__NR_renameat2, sys_renameat2), // 276 + GENX_(__NR_renameat2, sys_renameat2), // 276 // (__NR_seccomp, sys_ni_syscall), // 277 LINXY(__NR_getrandom, sys_getrandom), // 278 LINXY(__NR_memfd_create, sys_memfd_create), // 279 @@ -824,7 +824,7 @@ static SyscallTableEntry syscall_main_table[] = { // (__NR_pkey_alloc, sys_ni_syscall), // 289 // (__NR_pkey_free, sys_ni_syscall), // 290 LINXY(__NR_statx, sys_statx), // 291 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 292 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 292 GENX_(__NR_rseq, sys_ni_syscall), // 293 @@ -847,7 +847,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -860,7 +860,12 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 LINXY(__NR_statmount, sys_statmount), // 457 LINXY(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_(__NR_mseal, sys_mseal), // 462 + LINXY(__NR_file_getattr, sys_file_getattr), // 468 + LINX_(__NR_file_setattr, sys_file_setattr), // 469 }; diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index de8c37fc3e..4e3be2b15a 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -44,6 +44,7 @@ #include "pub_core_libcprint.h" #include "pub_core_libcproc.h" #include "pub_core_libcsignal.h" +#include "pub_core_mach.h" // VG_(dyld_cache_*) #include "pub_core_machine.h" // VG_(get_SP) #include "pub_core_mallocfree.h" #include "pub_core_options.h" @@ -66,6 +67,7 @@ #include #include #include +#include /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ #define msgh_request_port msgh_remote_port @@ -75,6 +77,12 @@ typedef HChar name_t[BOOTSTRAP_MAX_NAME_LEN]; typedef uint64_t mig_addr_t; +// Apple started using more inclusive language in Xcode 12+ and macOS 12+ +#if !defined(HOST_IO_MAIN_PORT) +#define HOST_IO_MAIN_PORT HOST_IO_MASTER_PORT +#endif + + // Saved ports static mach_port_t vg_host_port = 0; @@ -247,8 +255,6 @@ static void run_a_thread_NORETURN ( Word tidW ) } else { - mach_msg_header_t msg; - VG_(debugLog)(1, "syswrap-darwin", "run_a_thread_NORETURN(tid=%u): " "not last one standing\n", @@ -262,6 +268,8 @@ static void run_a_thread_NORETURN ( Word tidW ) /* tid is now invalid. */ +# if DARWIN_VERS < DARWIN_10_14 + mach_msg_header_t msg; // GrP fixme exit race msg.msgh_bits = MACH_MSGH_BITS(17, MACH_MSG_TYPE_MAKE_SEND_ONCE); msg.msgh_request_port = VG_(gettid)(); @@ -271,9 +279,53 @@ static void run_a_thread_NORETURN ( Word tidW ) tst->status = VgTs_Empty; // GrP fixme race here! new thread may claim this V thread stack // before we get out here! - // GrP fixme use bsdthread_terminate for safe cleanup? mach_msg(&msg, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, sizeof(msg), 0, 0, MACH_MSG_TIMEOUT_NONE, 0); + +#else + /* We have to use this sequence to terminate the thread to + prevent a subtle race. If VG_(exit_thread)() had left the + ThreadState as Empty, then it could have been reallocated, + reusing the stack while we're doing these last cleanups. + Instead, VG_(exit_thread) leaves it as Zombie to prevent + reallocation. We need to make sure we don't touch the stack + between marking it Empty and exiting. Hence the + assembler. */ +#if defined(VGP_x86_darwin) + asm volatile ( + "movl %1, %0\n" /* set tst->status = VgTs_Empty */ + "movl %2, %%eax\n" /* set %eax = __NR_bsdthread_terminate */ + "movl $0, %%ebx\n" + "pushl %%ebx\n" /* args on stack */ + "pushl %%ebx\n" + "pushl %%ebx\n" + "pushl %%ebx\n" + "int $0x81\n" /* bsdthread_terminate(0, 0, 0, 0) */ + "popl %%ebx\n" /* pop args */ + "popl %%ebx\n" + "popl %%ebx\n" + "popl %%ebx\n" + : "=m" (tst->status) + : "n" (VgTs_Empty), "n" (__NR_bsdthread_terminate) + : "eax", "ebx" + ); +#elif defined(VGP_amd64_darwin) + asm volatile ( + "movl %1, %0\n" /* set tst->status = VgTs_Empty */ + "movq %2, %%rax\n" /* set %rax = __NR_bsdthread_terminate */ + "movq $0, %%rdi\n" + "movq $0, %%rsi\n" + "movq $0, %%rdx\n" + "movq $0, %%r10\n" + "syscall\n" /* bsdthread_terminate(0, 0, 0, 0) */ + : "=m" (tst->status) + : "n" (VgTs_Empty), "n" (__NR_bsdthread_terminate) + : "rax", "rdi", "rsi", "rdx", "r10" + ); +#else +# error Unknown platform +#endif +#endif // DDD: This is reached sometimes on none/tests/manythreads, maybe // because of the race above. @@ -358,7 +410,7 @@ static void log_decaying ( const HChar* format, ... ) // Now see if it already exists in the table of strings that we have. if (!decaying_string_table) { decaying_string_table - = VG_(newFM)( VG_(malloc), "syswrap-darwin.pd.1", + = VG_(newFM)( VG_(malloc), "syswrap-darwin.ld.1", VG_(free), decaying_string_table_cmp ); } @@ -369,7 +421,7 @@ static void log_decaying ( const HChar* format, ... ) // We haven't seen this string before, so strdup it and add // it to the table. vg_assert(key == NULL && val == 0); - key = VG_(strdup)("syswrap-darwin.pd.2", buf); + key = VG_(strdup)("syswrap-darwin.ld.2", buf); VG_(addToFM)(decaying_string_table, (UWord)key, (UWord)0); } @@ -670,6 +722,189 @@ void VG_(show_open_ports)(void) } +/* --------------------------------------------------------------------- + kdebug helpers + ------------------------------------------------------------------ */ + +// Adapted from https://newosxbook.com/tools/kdv.html +static const HChar *kdebug_std_codes[] = +{ + NULL, + "MACH", // #define DBG_MACH 1 + "NETWORK", // #define DBG_NETWORK 2 + "FSYSTEM", // #define DBG_FSYSTEM 3 + "BSD", // #define DBG_BSD 4 + "IOKIT", // #define DBG_IOKIT 5 + "DRIVERS", // #define DBG_DRIVERS 6 + "TRACE", // #define DBG_TRACE 7 + "DLIL", // #define DBG_DLIL 8 + "PTHREAD", // #define DBG_PTHREAD 9 + "CORESTORAGE", // #define DBG_CORESTORAGE 10 + "COREGRAPHICS", // #define DBG_CG 11 + "MONOTONICS", // #define DBG_MONOTONIC 12 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "MISC", // #define DBG_MISC 20 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "SECURITY", // As of 10.10 + "DYLD", // #define DBG_DYLD 31 + "QT", // #define DBG_QT 32 + "APPS", // #define DBG_APPS 33 + "LAUNCHD", // #define DBG_LAUNCHD 34 + "SILICON", // #define DBG_SILICON 35 + "HANGTRACER", // iOS 9: undocumented + "PERF" , // #define DBG_PERF 37 + // added in 10.9 + "IMPORTANCE", // #define DBG_IMPORTANCE 38 + NULL, // Apparently present in iOS? + // Added in 10.10 + "BANK", // #define DBG_BANK 40 + "XPC", //#define DBG_XPC 41 + "ATM" , // #define DBG_ATM 42 + "ARIADNE", // #define DBG_ARIADNE 43 + // Added in 10.11 + "DAEMON", // #define DBG_DAEMON 44 + "ENERGYTRACE", // #define DBG_ENERGYTRACE 45 + "DISPATCH", // #define DBG_DISPATCH 46 + NULL, NULL, + "IMG", // #define DBG_IMG 49 + NULL, + "UMALLOC", // #define DBG_UMALLOC 51 + NULL, + "TURNSTILE", // #define DBG_TURNSTILE 53 + "AUDIO", // #define DBG_AUDIO 54 + NULL, NULL, NULL, NULL, NULL, // 55-59 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 60-69 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 70-79 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 80-89 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 90-99 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 100-109 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 110-119 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 120-129 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 130-139 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 140-149 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 150-159 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 160-169 + "WINDOWSERVER", // apparently deprecated in 10.11 and merged with 49 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 171-179 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 180-189 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 190-199 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 200-209 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 210-219 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 220-229 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 230-238 + "IOS_APPS", // iOS: Used by tons of Apps, undocumented + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 240-249 + NULL, NULL, NULL, NULL, NULL, // 250-254 + "MIG", // #define DBG_MIG 255 +}; + +struct KDebugTraceCode { + ULong code; + const HChar name[64]; +}; + +static const HChar *kdebug_debugid(ULong did) +{ + static Bool kdebug_trace_codes_initd = False; + static UInt kdebug_trace_codes_count = 0; + static struct KDebugTraceCode* kdebug_trace_codes = NULL; + + static HChar buf[64]; + + Int class = KDBG_EXTRACT_CLASS(did); + ULong event_id = did & KDBG_EVENTID_MASK; + HChar dir = '\0'; + const HChar* found_class = NULL; + + if (!kdebug_trace_codes_initd) { + HChar rbuf[1024]; + Int leftover = 0; + + kdebug_trace_codes_initd = True; + SysRes fd = VG_(open)("/usr/share/misc/trace.codes", O_RDONLY, 0); + if (sr_isError(fd)) { + VG_(close)(sr_Res(fd)); + } else { + kdebug_trace_codes_count = 0; + while (1) { + Int count = VG_(read)(sr_Res(fd), rbuf, sizeof(rbuf)); + if (count <= 0) { + break; + } + for (HChar* p = rbuf; p < rbuf + count; p += 1) { + if (*p == '\n') { + kdebug_trace_codes_count += 1; + } + } + } + kdebug_trace_codes = VG_(malloc)("kdebug_trace_codes", + kdebug_trace_codes_count * + sizeof(struct KDebugTraceCode)); + VG_(lseek)(sr_Res(fd), 0, VKI_SEEK_SET); + kdebug_trace_codes_count = 0; + while (1) { + Int count = VG_(read)(sr_Res(fd), rbuf+leftover, sizeof(rbuf)-leftover); + if (count <= 0) { + break; + } + count += leftover; + Int start = 0; + for (HChar* p = rbuf; p < rbuf + count; p += 1) { + if (*p != '\n') { + continue; + } + + HChar* end = NULL; + *p = '\0'; + kdebug_trace_codes[kdebug_trace_codes_count].code = VG_(strtoll16)(rbuf+start, &end); + while (*end == ' ' || *end == '\t') { + end += 1; + } + // FIXME: gross cast! + VG_(strlcpy)((HChar*)(Addr)kdebug_trace_codes[kdebug_trace_codes_count].name, end, sizeof(kdebug_trace_codes[kdebug_trace_codes_count].name)); + kdebug_trace_codes_count += 1; + start = p - rbuf + 1; + } + if (start < count) { + leftover = count - start; + VG_(memmove)(rbuf, rbuf+start, leftover); + } + } + VG_(close)(sr_Res(fd)); + } + } + + for (Int i = 0; i < kdebug_trace_codes_count; i += 1) { + const struct KDebugTraceCode* entry = &kdebug_trace_codes[i]; + if (entry->code == event_id) { + found_class = entry->name; + break; + } + } + if (found_class == NULL) { + found_class = kdebug_std_codes[class]; + } + if (found_class == NULL) { + found_class = "UNKNOWN"; + } + + if (did & DBG_FUNC_START) { + dir = '>'; + } + if (did & DBG_FUNC_END) { + dir = '<'; + } + + if (dir) { + VG_(sprintf)(buf, "%c%s", dir, found_class); + } else { + VG_(sprintf)(buf, "%s", found_class); + } + + return buf; +} + + /* --------------------------------------------------------------------- sync_mappings ------------------------------------------------------------------ */ @@ -744,9 +979,19 @@ void update_syncstats ( CheckHowOften cho, // reorder static UInt reorder_ctr = 0; if (i > 0 && 0 == (1 & reorder_ctr++)) { +#if defined(VGA_amd64) + // Some kind of compiler xmm-based optimization which causes a EXC_I386_GPFLT + // happens on amd64 on later macOS versions (seen on 15.0). + // Instead we do a boring memcpy. + SyncStats tmp; + VG_(memcpy)(&tmp, &syncstats[i-1], sizeof(SyncStats)); + VG_(memcpy)(&syncstats[i-1], &syncstats[i], sizeof(SyncStats)); + VG_(memcpy)(&syncstats[i], &tmp, sizeof(SyncStats)); +#else SyncStats tmp = syncstats[i-1]; syncstats[i-1] = syncstats[i]; syncstats[i] = tmp; +#endif } } @@ -1539,6 +1784,15 @@ static const HChar *name_for_fcntl(UWord cmd) { F(F_BARRIERFSYNC); F(F_ADDFILESIGS_RETURN); # endif +# if DARWIN_VERS >= DARWIN_10_14 + F(F_CHECK_LV); +# endif +# if DARWIN_VERS >= DARWIN_10_15 + F(F_SPECULATIVE_READ); +# endif +#if defined(VKI_F_GETPROTECTIONCLASS) + F(F_GETPROTECTIONCLASS); +#endif default: return "UNKNOWN"; } @@ -1737,6 +1991,43 @@ PRE(fcntl) break; # endif +# if DARWIN_VERS >= DARWIN_10_14 + case VKI_F_CHECK_LV: /* Check if Library Validation allows this Mach-O file to be + mapped into the calling process */ + // FIXME: Dejan + break; +# endif + +# if DARWIN_VERS >= DARWIN_10_15 + case VKI_F_SPECULATIVE_READ: /* Synchronous advisory read fcntl for regular and compressed file */ + PRINT("fcntl ( %lu, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3); + PRE_REG_READ3(long, "fcntl", + unsigned int, fd, unsigned int, cmd, + fspecread_t *, args); + + { + fspecread_t *fspecread = (fspecread_t *)ARG3; + PRE_FIELD_READ( "fcntl(VKI_F_SPECULATIVE_READ, fspecread->fsr_flags)", + fspecread->fsr_flags); + PRE_FIELD_READ( "fcntl(VKI_F_SPECULATIVE_READ, fspecread->fsr_offset)", + fspecread->fsr_offset); + PRE_FIELD_READ( "fcntl(VKI_F_SPECULATIVE_READ, fspecread->fsr_length)", + fspecread->fsr_length); + + if (fspecread->fsr_offset < 0 || fspecread->fsr_length < 0) { + SET_STATUS_Failure( VKI_EINVAL ); + } + } + break; +# endif +#if defined(VKI_F_GETPROTECTIONCLASS) + case VKI_F_GETPROTECTIONCLASS: + PRINT("fcntl ( %lu, %s )", ARG1, name_for_fcntl(ARG2)); + PRE_REG_READ2(long, "fcntl", + unsigned int, fd, unsigned int, cmd); + break; +#endif + default: PRINT("fcntl ( %lu, %lu [??] )", ARG1, ARG2); log_decaying("UNKNOWN fcntl %lu!", ARG2); @@ -2010,7 +2301,7 @@ PRE(disconnectx) PRE(kevent) { PRINT("kevent( %ld, %#lx, %ld, %#lx, %ld, %#lx )", - SARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + SARG1, ARG2, SARG3, ARG4, SARG5, ARG6); PRE_REG_READ6(int,"kevent", int,kq, const struct vki_kevent *,changelist, int,nchanges, struct vki_kevent *,eventlist, int,nevents, @@ -2028,7 +2319,7 @@ PRE(kevent) POST(kevent) { - PRINT("kevent ret %ld dst %#lx (%zu)", RES, ARG4, sizeof(struct vki_kevent)); + PRINT("kevent ret %ld dst %#lx (%zu)", (Word)RES, ARG4, sizeof(struct vki_kevent)); if (RES > 0) POST_MEM_WRITE(ARG4, RES * sizeof(struct vki_kevent)); } @@ -2124,6 +2415,7 @@ static const HChar *workqop_name(int op) case VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY: return "SET_EVENT_MANAGER_PRIORITY"; case VKI_WQOPS_THREAD_WORKLOOP_RETURN: return "THREAD_WORKLOOP_RETURN"; case VKI_WQOPS_SHOULD_NARROW: return "SHOULD_NARROW"; + case VKI_WQOPS_SETUP_DISPATCH: return "SETUP_DISPATCH"; default: return "?"; } } @@ -2143,6 +2435,7 @@ PRE(workq_ops) // GrP fixme may block? break; case VKI_WQOPS_THREAD_KEVENT_RETURN: + case VKI_WQOPS_THREAD_WORKLOOP_RETURN: case VKI_WQOPS_THREAD_RETURN: { // The interesting case. The kernel will do one of two things: // 1. Return normally. We continue; libc proceeds to stop the thread. @@ -2176,16 +2469,37 @@ PRE(workq_ops) // RK fixme this just sets scheduling priorities - don't think we need // to do anything here break; - case VKI_WQOPS_THREAD_WORKLOOP_RETURN: case VKI_WQOPS_SHOULD_NARROW: // RK fixme need anything here? // RK fixme may block? break; + case VKI_WQOPS_SETUP_DISPATCH: { + // docs says: setup pthread workqueue-related operations +#if DARWIN_VERS >= DARWIN_10_15 +#pragma pack(4) + struct workq_dispatch_config { + uint32_t wdc_version; + uint32_t wdc_flags; + uint64_t wdc_queue_serialno_offs; + uint64_t wdc_queue_label_offs; + }; +#pragma pack() + PRE_MEM_READ("workq_ops(item)", ARG2, MIN(sizeof(struct workq_dispatch_config), SARG3)); + struct workq_dispatch_config* cfg = (struct workq_dispatch_config*)ARG2; + if (cfg->wdc_flags & ~VKI_WORKQ_DISPATCH_SUPPORTED_FLAGS || + cfg->wdc_version < VKI_WORKQ_DISPATCH_MIN_SUPPORTED_VERSION) { + SET_STATUS_Failure( VKI_ENOTSUP ); + } +#endif + break; + } default: - VG_(printf)("UNKNOWN workq_ops option %ld\n", ARG1); + PRINT("workq_ops ( %lu [??], ... )", ARG1); + log_decaying("UNKNOWN workq_ops option %lu!", ARG1); break; } } + POST(workq_ops) { ThreadState *tst = VG_(get_ThreadState)(tid); @@ -2334,25 +2648,21 @@ POST(__pthread_sigmask) // SYS___sigwait 330 -// int sigwait(const sigset_t * __restrict, int * __restrict) __DARWIN_ALIAS_C(sigwait); +// int __sigwait(const sigset_t * __restrict, int * __restrict) __DARWIN_ALIAS_C(sigwait); PRE(__sigwait) { *flags |= SfMayBlock; PRINT("__sigwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2); - PRE_REG_READ2(int, "sigwait", + PRE_REG_READ2(int, "__sigwait", const vki_sigset_t *, set, int *, sig); - if (ARG1 != 0) { - PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t)); - } - if (ARG2 != 0) { - PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int)); - } + PRE_MEM_READ( "__sigwait(set)", ARG1, sizeof(vki_sigset_t)); + PRE_MEM_WRITE( "__sigwait(sig)", ARG2, sizeof(int)); } POST(__sigwait) { - if (ARG2 != 0) { + if (RES == 0) { POST_MEM_WRITE( ARG2, sizeof(int)); } } @@ -2768,6 +3078,7 @@ PRE(fstat_extended) PRE_MEM_WRITE("fstat_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); PRE_MEM_READ( "fstat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); } + POST(fstat_extended) { POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); @@ -2789,6 +3100,7 @@ PRE(stat64_extended) PRE_MEM_WRITE("stat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); PRE_MEM_READ( "stat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); } + POST(stat64_extended) { POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); @@ -2797,7 +3109,6 @@ POST(stat64_extended) POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); } - PRE(lstat64_extended) { PRINT("lstat64_extended( %#lx(%s), %#lx, %#lx, %#lx )", @@ -2806,10 +3117,11 @@ PRE(lstat64_extended) void *, fsacl, vki_size_t *, fsacl_size); PRE_MEM_RASCIIZ( "lstat64_extended(file_name)", ARG1 ); PRE_MEM_WRITE( "lstat64_extended(buf)", ARG2, sizeof(struct vki_stat64) ); - if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) + if ( ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) PRE_MEM_WRITE( "lstat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); PRE_MEM_READ( "lstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); } + POST(lstat64_extended) { POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); @@ -2830,6 +3142,7 @@ PRE(fstat64_extended) PRE_MEM_WRITE("fstat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); PRE_MEM_READ( "fstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); } + POST(fstat64_extended) { POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); @@ -3012,10 +3325,34 @@ PRE(stat64) PRE_REG_READ2(long, "stat", const char *,path, struct stat64 *,buf); PRE_MEM_RASCIIZ("stat64(path)", ARG1); PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); + +#if DARWIN_VERS >= DARWIN_11_00 + // Starting with macOS 11.0, some system libraries are not provided on the disk but only though + // shared dyld cache, thus we try to detect if dyld tried (and failed) to load a dylib, + // in which case we do the same thing as dyld and load the info from the cache directly + // + // This is our entry point for checking a particular dylib: if it looks like one, + // we want to see the error result, if any, and subsequently check the cache + if (ARG1 != 0 && VG_(dyld_cache_might_be_in)((HChar *)ARG1)) { + *flags |= SfPostOnFail; + } +#endif } POST(stat64) { - POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); + if (SUCCESS) { + POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); + } + +#if DARWIN_VERS >= DARWIN_11_00 + if (SUCCESS || (FAILURE && ERR == VKI_ENOENT)) { + // It failed and `SfPostOnFail` was set, thus this is probably a dylib, + // try to load it from cache which will call VG_(di_notify_mmap) like the previous versions did + if (VG_(dyld_cache_load_library)((HChar *)ARG1)) { + ML_(sync_mappings)("after", "stat64", 0); + } + } +#endif } PRE(lstat64) @@ -3125,8 +3462,13 @@ static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, { ATTR_CMN_OWNERID, sizeof(uid_t) }, { ATTR_CMN_GRPID, sizeof(gid_t) }, { ATTR_CMN_ACCESSMASK, sizeof(uint32_t) }, +#if DARWIN_VERS >= DARWIN_10_15 + { ATTR_CMN_GEN_COUNT, sizeof(uint32_t) }, + { ATTR_CMN_DOCUMENT_ID, sizeof(uint32_t) }, +#else { ATTR_CMN_NAMEDATTRCOUNT, sizeof(uint32_t) }, { ATTR_CMN_NAMEDATTRLIST, -1 }, +#endif { ATTR_CMN_FLAGS, sizeof(uint32_t) }, { ATTR_CMN_USERACCESS, sizeof(uint32_t) }, { ATTR_CMN_EXTENDED_SECURITY, -1 }, @@ -3139,6 +3481,10 @@ static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, #endif #if DARWIN_VERS >= DARWIN_10_8 { ATTR_CMN_ADDEDTIME, -1 }, +#endif +#if DARWIN_VERS >= DARWIN_10_15 + { ATTR_CMN_ERROR, sizeof(uint32_t) }, + { ATTR_CMN_DATA_PROTECT_FLAGS, sizeof(uint32_t) }, #endif { 0, 0 } }; @@ -3165,6 +3511,10 @@ static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, { ATTR_VOL_CAPABILITIES, sizeof(vol_capabilities_attr_t) }, #if DARWIN_VERS >= DARWIN_10_6 { ATTR_VOL_UUID, sizeof(uuid_t) }, +#endif +#if DARWIN_VERS >= DARWIN_10_15 + { ATTR_VOL_QUOTA_SIZE, sizeof(off_t) }, + { ATTR_VOL_RESERVED_SIZE, sizeof(off_t) }, #endif { ATTR_VOL_ATTRIBUTES, sizeof(vol_attributes_attr_t) }, { 0, 0 } @@ -3174,6 +3524,11 @@ static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, { ATTR_DIR_LINKCOUNT, sizeof(uint32_t) }, { ATTR_DIR_ENTRYCOUNT, sizeof(uint32_t) }, { ATTR_DIR_MOUNTSTATUS, sizeof(uint32_t) }, +#if DARWIN_VERS >= DARWIN_10_15 + { ATTR_DIR_ALLOCSIZE, sizeof(off_t) }, + { ATTR_DIR_IOBLOCKSIZE, sizeof(uint32_t) }, + { ATTR_DIR_DATALENGTH, sizeof(off_t) }, +#endif { 0, 0 } }; static const attrspec fileattr[] = { @@ -3199,6 +3554,16 @@ static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, // This order is important. { ATTR_FORK_TOTALSIZE, sizeof(off_t) }, { ATTR_FORK_ALLOCSIZE, sizeof(off_t) }, +#if DARWIN_VERS >= DARWIN_10_15 + { ATTR_CMNEXT_RELPATH, sizeof(struct attrreference) }, + { ATTR_CMNEXT_PRIVATESIZE, sizeof(off_t) }, + { ATTR_CMNEXT_LINKID, sizeof(uint64_t) }, + { ATTR_CMNEXT_NOFIRMLINKPATH, sizeof(struct attrreference) }, + { ATTR_CMNEXT_REALDEVID, sizeof(uint32_t) }, + { ATTR_CMNEXT_REALFSID, sizeof(fsid_t) }, + { ATTR_CMNEXT_CLONEID, sizeof(uint64_t) }, + { ATTR_CMNEXT_EXT_FLAGS, sizeof(uint64_t) }, +#endif { 0, 0 } }; @@ -3271,6 +3636,43 @@ static void set1attr(ThreadId tid, void *attrData, SizeT attrDataSize) PRE_MEM_READ("setattrlist(attrBuf value)", (Addr)attrData, attrDataSize); } +// __NR_open_dprotected_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(216) +// int open_dprotected_np(const char *path, int flags, int dpclass, +// int dpflags, int mode); +PRE(open_dprotected_np) +{ + if (ARG2 & VKI_O_CREAT) { + // versiion that uses mode + PRINT("open_dprotected_np(path:%#lx(%s), flags:%#lx, " + "dpclass:%#lx, dpflags:%#lx, mode:%#lx)", + ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4, ARG5); + PRE_REG_READ5(int, "open_dprotected_np", const char*, path, + int, flags, int, dpclass, int, dpflags, + int, mode); + } else { + // version that does not use mode + PRINT("open_dprotected_np(path:%#lx(%s), flags:%#lx, " + "dpclass:%#lx, dpflags:%#lx)", + ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(int, "open_dprotected_np", const char*, path, + int, flags, int, dpclass, int, dpflags); + } + PRE_MEM_RASCIIZ("open_dprotected_np(path)", ARG1); +} + +POST(open_dprotected_np) +{ + vg_assert(SUCCESS); + POST_newFd_RES; + if (!ML_(fd_allowed)(RES, "open_dprotected_np", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) + ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1); + } +} + PRE(getattrlist) { PRINT("getattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)", @@ -3442,6 +3844,8 @@ static void pre_argv_envp(Addr a, ThreadId tid, const HChar* s1, const HChar* s2 Addr a_deref; Addr* a_p = (Addr*)a; PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) ); + if (!ML_(safe_to_deref)(a_p, sizeof(char*))) + return; a_deref = *a_p; if (0 == a_deref) break; @@ -3475,6 +3879,40 @@ static SysRes simple_pre_exec_check ( const HChar* exe_name, } return VG_(mk_SysRes_Success)(0); } + +/* + * FIXME PJF + * From the man page + * + * "The argument file_actions is either NULL, or it is a pointer to a file actions object that + * was initialized by a call to posix_spawn_file_actions_init(3) and represents zero or more + * file actions. + * + * File descriptors open in the calling process image remain open in the new process image, + * except for those for which the close-on-exec flag is set (see close(2) and fcntl(2)). + * Descriptors that remain open are unaffected by posix_spawn() unless their behaviour is + * modified by particular spawn flags or a file action; see posix_spawnattr_setflags(3) and + * posix_spawn_file_actions_init(3) for additional information." + * + * If file_arguments is non-NULL and --trace-children=yes is specified then we chould call + * VG_(unimplemented)(). + * + * file_actions and attrp are both pointers to types that are typedef'd to void* + * in userland headers. That means they are black bloxed in userland and only the + * kernel knows the type. We'll need to copy the type into Valgrind if we want to + * peek at what these arguments point to. + * + * To properly implement posix_spawn we would need a mechanism for a traced + * child process to "inherit" a list of opened files. I guess that would + * involve some way of passing info about filenanme, fd, open mode, offset, + * attributes to so that the child could open them before the child code runs. + */ + +// __NR_posix_spawn VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(244) +// int posix_spawn(pid_t *restrict pid, const char *restrict path, +// const posix_spawn_file_actions_t *file_actions, +// const posix_spawnattr_t *restrict attrp, char *const argv[restrict], +// char *const envp[restrict]); PRE(posix_spawn) { HChar* path = NULL; /* path to executable */ @@ -3487,31 +3925,37 @@ PRE(posix_spawn) Bool trace_this_child; /* args: pid_t* pid - char* path - posix_spawn_file_actions_t* file_actions + const char* path + const posix_spawn_file_actions_t* file_actions + const posix_spawnattr_t* attr char** argv char** envp + (ignoring restrict) */ - PRINT("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )", - ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 ); + PRINT("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx, %#lx )", + ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5, ARG6 ); /* Standard pre-syscall checks */ - PRE_REG_READ5(int, "posix_spawn", vki_pid_t*, pid, char*, path, - void*, file_actions, char**, argv, char**, envp ); - PRE_MEM_WRITE("posix_spawn(pid)", ARG1, sizeof(vki_pid_t) ); + PRE_REG_READ6(int, "posix_spawn", vki_pid_t*, pid, char*, path, + vki_posix_spawn_file_actions_t*, file_actions, + vki_posix_spawnattr_t*, attrp, + char**, argv, char**, envp ); + if (ARG1 != 0) { + PRE_MEM_WRITE("posix_spawn(pid)", ARG1, sizeof(vki_pid_t) ); + } PRE_MEM_RASCIIZ("posix_spawn(path)", ARG2); // DDD: check file_actions - if (ARG4 != 0) - pre_argv_envp( ARG4, tid, "posix_spawn(argv)", - "posix_spawn(argv[i])" ); if (ARG5 != 0) - pre_argv_envp( ARG5, tid, "posix_spawn(envp)", + pre_argv_envp( ARG5, tid, "posix_spawn(argv)", + "posix_spawn(argv[i])" ); + if (ARG6 != 0) + pre_argv_envp( ARG6, tid, "posix_spawn(envp)", "posix_spawn(envp[i])" ); if (0) - VG_(printf)("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )\n", - ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 ); + VG_(printf)("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx, %#lx )\n", + ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5, ARG6 ); /* Now follows a bunch of logic copied from PRE(sys_execve) in syswrap-generic.c. */ @@ -3526,7 +3970,7 @@ PRE(posix_spawn) // Decide whether or not we want to follow along { // Make 'child_argv' be a pointer to the child's arg vector // (skipping the exe name) - const HChar** child_argv = (const HChar**)ARG4; + const HChar** child_argv = (const HChar**)ARG5; if (child_argv && child_argv[0] == NULL) child_argv = NULL; trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG2, child_argv ); @@ -3588,21 +4032,21 @@ PRE(posix_spawn) // // Then, if tracing the child, set VALGRIND_LIB for it. // - if (ARG5 == 0) { + if (ARG6 == 0) { envp = NULL; } else { - envp = VG_(env_clone)( (HChar**)ARG5 ); + envp = VG_(env_clone)( (HChar**)ARG6 ); vg_assert(envp); VG_(env_remove_valgrind_env_stuff)( envp, /* ro_strings */ False, NULL); } if (trace_this_child) { - // Set VALGRIND_LIB in ARG5 (the environment) + // Set VALGRIND_LIB in ARG6 (the environment) VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir)); } // Set up the child's args. If not tracing it, they are - // simply ARG4. Otherwise, they are + // simply ARG5. Otherwise, they are // // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG2] ++ ARG4[1..] // @@ -3610,7 +4054,7 @@ PRE(posix_spawn) // are omitted. // if (!trace_this_child) { - argv = (HChar**)ARG4; + argv = (HChar**)ARG5; } else { vg_assert( VG_(args_for_valgrind) ); vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 ); @@ -3625,7 +4069,7 @@ PRE(posix_spawn) // name of client exe tot_args++; // args for client exe, skipping [0] - arg2copy = (HChar**)ARG4; + arg2copy = (HChar**)ARG5; if (arg2copy && arg2copy[0]) { for (i = 1; arg2copy[i]; i++) tot_args++; @@ -3666,12 +4110,13 @@ PRE(posix_spawn) /* Let the call go through as usual. However, we have to poke the altered arguments back into the argument slots. */ ARG2 = (UWord)path; - ARG4 = (UWord)argv; - ARG5 = (UWord)envp; + ARG5 = (UWord)argv; + ARG6 = (UWord)envp; /* not to mention .. */ *flags |= SfMayBlock; } + POST(posix_spawn) { vg_assert(SUCCESS); @@ -4329,7 +4774,7 @@ POST(mmap) ML_(notify_core_and_tool_of_mmap)(RES, ARG2, ARG3, ARG4, ARG5, ARG6); // Try to load symbols from the region VG_(di_notify_mmap)( (Addr)RES, False/*allow_SkFileV*/, - -1/*don't use_fd*/ ); + ARG5 ); ML_(sync_mappings)("after", "mmap", 0); } } @@ -5086,6 +5531,7 @@ POST(host_get_clock_service) Reply *reply = (Reply *)ARG1; + record_named_port(tid, reply->clock_serv.name, -1, "clock-%p"); assign_port_name(reply->clock_serv.name, "clock-%p"); PRINT("%s", name_for_port(reply->clock_serv.name)); } @@ -5142,7 +5588,8 @@ PRE(host_request_notification) } // GrP fixme only do this on success - assign_port_name(req->notify_port.name, "host_notify-%p"); + // PJF moved to POST(mach_msg_post) + //assign_port_name(req->notify_port.name, "host_notify-%p"); } @@ -5209,8 +5656,8 @@ PRE(host_get_special_port) PRINT("host_get_special_port(%s, HOST_PRIV_PORT)", name_for_port(MACH_REMOTE)); break; - case HOST_IO_MASTER_PORT: - PRINT("host_get_special_port(%s, HOST_IO_MASTER_PORT)", + case HOST_IO_MAIN_PORT: + PRINT("host_get_special_port(%s, HOST_IO_MAIN_PORT)", name_for_port(MACH_REMOTE)); break; // Not provided by kernel @@ -5271,7 +5718,7 @@ POST(host_get_special_port) case HOST_PRIV_PORT: assign_port_name(reply->port.name, "priv-%p"); break; - case HOST_IO_MASTER_PORT: + case HOST_IO_MAIN_PORT: assign_port_name(reply->port.name, "io-master-%p"); break; // Not provided by kernel @@ -6008,6 +6455,7 @@ POST(task_get_special_port) switch (MACH_ARG(task_get_special_port.which_port)) { case TASK_BOOTSTRAP_PORT: vg_bootstrap_port = reply->special_port.name; + record_named_port(tid, reply->special_port.name, -1, "bootstrap"); assign_port_name(reply->special_port.name, "bootstrap"); break; case TASK_KERNEL_PORT: @@ -6110,6 +6558,7 @@ POST(semaphore_create) Reply *reply = (Reply *)ARG1; + record_named_port(tid, reply->semaphore.name, -1, "semaphore-%p"); assign_port_name(reply->semaphore.name, "semaphore-%p"); PRINT("%s", name_for_port(reply->semaphore.name)); } @@ -8365,6 +8814,12 @@ PRE(mach_msg_task) CALL_PRE(mach_vm_purgable_control); return; +#if DARWIN_VERS >= DARWIN_10_15 + case 8000: + CALL_PRE(task_restartable_ranges_register); + return; +#endif + default: // unknown message to task self log_decaying("UNKNOWN task message [id %d, to %s, reply 0x%x]", @@ -8439,9 +8894,7 @@ PRE(mach_msg) { mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; mach_msg_option_t option = (mach_msg_option_t)ARG2; - // mach_msg_size_t send_size = (mach_msg_size_t)ARG3; mach_msg_size_t rcv_size = (mach_msg_size_t)ARG4; - // mach_port_t rcv_name = (mach_port_t)ARG5; size_t complex_header_size = 0; PRE_REG_READ7(long, "mach_msg", @@ -8504,6 +8957,7 @@ PRE(mach_msg) else if (mh->msgh_request_port == vg_host_port) { // message sent to mach_host_self() CALL_PRE(mach_msg_host); + AFTER = POST_FN(mach_msg_host); return; } else if (is_task_port(mh->msgh_request_port)) { @@ -8691,6 +9145,149 @@ POST(mach_msg) } } +#if DARWIN_VERS >= DARWIN_13_00 + +#define MACH64_MSG_VECTOR 0x0000000100000000ull + +typedef uint64_t mach_msg_option64_t; + +typedef struct { + /* a mach_msg_header_t* or mach_msg_aux_header_t* */ + mach_vm_address_t msgv_data; + /* if msgv_rcv_addr is non-zero, use it as rcv address instead */ + mach_vm_address_t msgv_rcv_addr; + mach_msg_size_t msgv_send_size; + mach_msg_size_t msgv_rcv_size; +} mach_msg_vector_t; + +PRE(mach_msg2) +{ +#define MACH_MSG2_UNSHIFT_HIGH(x) ((x) >> 32) +#define MACH_MSG2_UNSHIFT_LOW(x) ((x) & 0xffffffff) + + UWord msgh_bits = MACH_MSG2_UNSHIFT_LOW(ARG3); + UWord send_size = MACH_MSG2_UNSHIFT_HIGH(ARG3); + Word msgh_remote_port = MACH_MSG2_UNSHIFT_LOW(ARG4); + Word msgh_local_port = MACH_MSG2_UNSHIFT_HIGH(ARG4); + Word msgh_voucher = MACH_MSG2_UNSHIFT_LOW(ARG5); + UWord msgh_id = MACH_MSG2_UNSHIFT_HIGH(ARG5); + UWord desc_count = MACH_MSG2_UNSHIFT_LOW(ARG6); + Word rcv_name = MACH_MSG2_UNSHIFT_HIGH(ARG6); + UWord rcv_size = MACH_MSG2_UNSHIFT_LOW(ARG7); + UWord priority = MACH_MSG2_UNSHIFT_HIGH(ARG7); + +#undef MACH_MSG2_UNSHIFT_HIGH +#undef MACH_MSG2_UNSHIFT_LOW + + mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; + mach_msg_option64_t options = (mach_msg_option64_t)ARG2; + + PRINT( + "mach_msg2(%#lx " + "{id: %d, bits: %#x, size: %u, voucher: %s, local: %s, remote: %s}, " + "options %#llx, " + "%#lx (msgh_bits %#lx | send_size %lu), %#lx (remote %s | local %s), " + "%#lx (voucher %s | id %#lx), %#lx (desc_count %lu | rcv_name %s), " + "%#lx (rcv_size %lu | priority %lu), timeout %lu) ", + ARG1, + mh->msgh_id, mh->msgh_bits, mh->msgh_size, name_for_port(mh->msgh_voucher_port), name_for_port(mh->msgh_local_port), name_for_port(mh->msgh_remote_port), + options, + ARG3, msgh_bits, send_size, ARG4, name_for_port(msgh_remote_port), name_for_port(msgh_local_port), + ARG5, name_for_port(msgh_voucher), msgh_id, ARG6, desc_count, name_for_port(rcv_name), + ARG7, rcv_size, priority, ARG8 + ); + PRE_REG_READ8(kern_return_t, "mach_msg2", + void *, data, + mach_msg_option64_t, options, + uint64_t, msgh_bits_and_send_size, + uint64_t, msgh_remote_and_local_port, + uint64_t, msgh_voucher_and_id, + uint64_t, desc_count_and_rcv_name, + uint64_t, rcv_size_and_priority, + uint64_t, timeout); + SizeT size = sizeof(mach_msg_header_t); + SizeT trailer_size = 0; + if (options & MACH_SEND_MSG && msgh_bits & MACH_SEND_TRAILER) { + trailer_size = REQUESTED_TRAILER_SIZE(options); + } +// FIXME: loads of issues on macOS 13 and no computer to test on +// disabled for now +#if DARWIN_VERS != DARWIN_13_00 + if (options & MACH64_MSG_VECTOR) { + mach_msg_vector_t *msgv = (mach_msg_vector_t *)mh; + PRE_MEM_READ("mach_msg2(msgv)", (Addr)mh, sizeof(mach_msg_vector_t)); + if (options & MACH_SEND_MSG) { + PRE_MEM_READ("mach_msg2(msgv->data)", (Addr)msgv->msgv_data, msgv->msgv_send_size); + } + if (options & MACH_RCV_MSG) { + if (msgv->msgv_rcv_addr != 0) { + PRE_MEM_WRITE("mach_msg2(msgv->rcv_addr)", (Addr)msgv->msgv_rcv_addr, msgv->msgv_rcv_size); + } else { + PRE_MEM_WRITE("mach_msg2(msgv->data)", (Addr)msgv->msgv_data, msgv->msgv_rcv_size); + } + } + } else { + if (send_size > size) { + size = send_size; + } + if (options & MACH_SEND_MSG) { + PRE_MEM_READ("mach_msg2(msg)", (Addr)mh, size + trailer_size); + } + if (rcv_size > size) { + size = rcv_size; + } + if (options & MACH_RCV_MSG) { + PRE_MEM_WRITE("mach_msg2(msg)", (Addr)mh, size); + } + } +#endif + + // Assume call may block unless specified otherwise + *flags |= SfMayBlock; + + AFTER = NULL; + + if (options & MACH_SEND_MSG) { + MACH_REMOTE = msgh_remote_port; + MACH_MSGH_ID = msgh_id; + } + + // Call a PRE handler. The PRE handler may set an AFTER handler. + if (!(options & MACH_SEND_MSG)) { + // no message sent, receive only + CALL_PRE(mach_msg_receive); + return; + } else if (msgh_local_port == vg_host_port) { + // message sent to mach_host_self() + CALL_PRE(mach_msg_host); + return; + } else if (is_task_port(msgh_local_port)) { + // message sent to a task + CALL_PRE(mach_msg_task); + return; + } else if (msgh_local_port == vg_bootstrap_port) { + // message sent to bootstrap port + CALL_PRE(mach_msg_bootstrap); + return; + } else if (is_thread_port(msgh_local_port)) { + // message sent to one of this process's threads + CALL_PRE(mach_msg_thread); + return; + } else { + AFTER = POST_FN(mach_msg_unhandled); + return; + } +} + +POST(mach_msg2) +{ + // Call handler chosen by PRE(mach_msg2) + if (AFTER) { + (*AFTER)(tid, arrghs, status); + } +} +#endif + POST(mach_msg_unhandled) { @@ -8704,6 +9301,34 @@ POST(mach_msg_unhandled_check) PRINT("mach_msg_unhandled_check tid:%d missed mapping change()", tid); } +POST(mach_msg_host) +{ + mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; + + // FIXME PJF put this in a header rather than have a copy and paste duplicate +#pragma pack(4) + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t notify_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + host_flavor_t notify_type; + } Request; +#pragma pack() + + switch (mh->msgh_id) { + case 217: { + Request *req = (Request *)ARG1; + assign_port_name(req->notify_port.name, "host_notify-%p"); + } + break; + default: + break; + } +} + /* --------------------------------------------------------------------- other Mach traps @@ -8876,6 +9501,25 @@ PRE(__semwait_signal) // *flags |= SfMayBlock; //} +PRE(task_name_for_pid) +{ + PRINT("task_name_for_pid(%s, %ld, %#lx)", name_for_port(ARG1), SARG2, ARG3); + PRE_REG_READ3(long, "task_name_for_pid", + mach_port_t,"target", + vki_pid_t, "pid", mach_port_t *,"task"); + PRE_MEM_WRITE("task_name_for_pid(task)", ARG3, sizeof(mach_port_t)); +} + +POST(task_name_for_pid) +{ + mach_port_t task; + + POST_MEM_WRITE(ARG3, sizeof(mach_port_t)); + + task = *(mach_port_t *)ARG3; + record_named_port(tid, task, MACH_PORT_RIGHT_SEND, "task-name-%p"); + PRINT("task-name %#x", task); +} PRE(task_for_pid) { @@ -9042,7 +9686,7 @@ PRE(swtch_pri) } -PRE(FAKE_SIGRETURN) +PRE(fake_sigreturn) { /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for an explanation of what follows. */ @@ -9050,7 +9694,7 @@ PRE(FAKE_SIGRETURN) sigframe-x86-darwin.c. */ /* See also comments just below on PRE(sigreturn). */ - PRINT("FAKE_SIGRETURN ( )"); + PRINT("fake_sigreturn ( )"); vg_assert(VG_(is_valid_tid)(tid)); vg_assert(tid >= 1 && tid < VG_N_THREADS); @@ -9114,10 +9758,10 @@ PRE(sigreturn) 1. Change the second argument of VG_(sigframe_destroy) from "Bool isRT" to "UInt sysno", so we can pass the syscall number, so it can distinguish this case from the - __NR_DARWIN_FAKE_SIGRETURN case. + __NR_darwin_fake_sigreturn case. 2. In VG_(sigframe_destroy), look at sysno to distinguish the - cases. For __NR_DARWIN_FAKE_SIGRETURN, behave as at present. + cases. For __NR_darwin_fake_sigreturn, behave as at present. For this case, restore the thread's CPU state (or at least the integer regs) from the ucontext in ARG1 (and do all the other "signal-returns" stuff too). @@ -9427,6 +10071,17 @@ static void munge_wll(UWord* a1, ULong* a2, ULong* a3, # endif } +static void munge_wlww(UWord* a1, ULong* a2, UWord* a3, UWord* a4, + UWord aRG1, UWord aRG2, UWord aRG3, + UWord aRG4, UWord aRG5) +{ +# if defined(VGA_x86) + *a1 = aRG1; *a2 = LOHI64(aRG2,aRG3); *a3 = aRG4; *a4 = aRG5; +# else + *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = aRG4; +# endif +} + static void munge_wwlw(UWord* a1, UWord* a2, ULong* a3, UWord* a4, UWord aRG1, UWord aRG2, UWord aRG3, UWord aRG4, UWord aRG5) @@ -9487,6 +10142,7 @@ PRE(kernelrpc_mach_vm_allocate_trap) PRE_MEM_WRITE("kernelrpc_mach_vm_allocate_trap(address)", a2, sizeof(void*)); } + POST(kernelrpc_mach_vm_allocate_trap) { UWord a1; UWord a2; ULong a3; UWord a4; @@ -9508,6 +10164,20 @@ POST(kernelrpc_mach_vm_allocate_trap) } } +// MACH 11 +// kern_return_t _kernelrpc_mach_vm_purgable_control_trap(mach_port_name_t target, +// mach_vm_offset_t address, +// vm_purgable_t control, +// int *state); +PRE(kernelrpc_mach_vm_purgable_control_trap) +{ + // FIXME PJF munge? + PRINT("kernelrpc_mach_vm_purgable_control_trap" + "(target:%#lx, address:%#lx, control:%ld, state:%#lx)", + ARG1, ARG2, SARG3, ARG4); + // FIXME PJF PRE_REG_READ and READ/WRITE MEM +} + PRE(kernelrpc_mach_vm_deallocate_trap) { UWord a1; ULong a2; ULong a3; @@ -9712,9 +10382,12 @@ PRE(kernelrpc_mach_port_construct_trap) { UWord a1; UWord a2; ULong a3; UWord a4; munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); + mach_port_options_t* options = (mach_port_options_t*) a2; PRINT("kernelrpc_mach_port_construct_trap" - "(target: %s, options: %#lx, content: %llx, name: %p)", - name_for_port(a1), a2, a3, *(mach_port_name_t**)a4); + "(target: %s, options: %#lx {flags: %#x, mpl_ql: %#x}, context: %llx, name: %p)", + name_for_port(a1), a2, options->flags, options->mpl.mpl_qlimit, a3, *(mach_port_name_t**)a4); + PRE_MEM_READ("kernelrpc_mach_port_construct_trap(options)", a2, + sizeof(mach_port_options_t)); PRE_MEM_WRITE("kernelrpc_mach_port_construct_trap(name)", a4, sizeof(mach_port_name_t*)); } @@ -9880,6 +10553,15 @@ POST(fstatat64) POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); } +PRE(unlinkat) +{ + PRINT("unlinkat ( %ld, %#lx(%s), %#lx )", + SARG1, ARG2, (HChar*)ARG2, ARG3); + PRE_REG_READ3(long, "unlinkat", + int, fd, const char *, path, int, flag); + PRE_MEM_RASCIIZ( "unlinkat(path)", ARG2 ); +} + PRE(readlinkat) { PRINT("readlinkat ( %ld, %#lx(%s), %#lx, %ld )", @@ -9951,12 +10633,45 @@ POST(csrctl) } } +// __NR_guarded_open_dprotected_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(484) +// int guarded_open_dprotected_np(const char *path, const void *guard, +// u_int guardflags, int flags, int dpclass, +// int dpflags, int mode); PRE(guarded_open_dprotected_np) { - PRINT("guarded_open_dprotected_np(" - "path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx, " - "dpclass:%#lx, dpflags: %#lx) FIXME", - ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + if (ARG4 & VKI_O_CREAT) { + // versiion that uses mode + PRINT("guarded_open_dprotected_np(" + "path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx, " + "dpclass:%#lx, dpflags:%#lx, mode:%#lx)", + ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + PRE_REG_READ7(int, "guarded_open_dprotected_np", const char*, path, + const void*, guard, u_int, guardflags, int, flags, + int, dpclass, int, dpflags, int, mode); + } else { + // version that does not use mode + PRINT("guarded_open_dprotected_np(" + "path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx, " + "dpclass:%#lx, dpflags:%#lx)", + ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + PRE_REG_READ6(int, "guarded_open_dprotected_np", const char*, path, + const void*, guard, u_int, guardflags, int, flags, + int, dpclass, int, dpflags); + } + PRE_MEM_RASCIIZ("guarded_open_dprotected_np(path)", ARG1); +} + +POST(guarded_open_dprotected_np) +{ + vg_assert(SUCCESS); + POST_newFd_RES; + if (!ML_(fd_allowed)(RES, "guarded_open_dprotected_np", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) + ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1); + } } PRE(guarded_write_np) @@ -10035,6 +10750,15 @@ PRE(mkdirat) #if DARWIN_VERS >= DARWIN_10_11 +PRE(kdebug_trace_string) +{ + PRINT("kdebug_trace_string(%#lx (%s), %#lx, %s)", ARG1, kdebug_debugid(ARG1), ARG2, (HChar*)(Addr)ARG3); + if (ARG3 != 0) { + PRE_MEM_RASCIIZ("kdebug_trace_string(string)", ARG3); + } + SET_STATUS_Success(0); +} + PRE(kevent_qos) { PRINT("kevent_qos( %ld, %#lx, %ld, %#lx, %ld, %#lx, %ld, %ld )", @@ -10095,6 +10819,98 @@ PRE(pselect) #endif /* DARWIN_VERS >= DARWIN_10_11 */ +// SYS_persona 494 +// __persona(uint32_t operation, uint32_t flags, struct kpersona_info *info, uid_t *id, +// i size_t *idlen, char *path); +PRE(persona) +{ + // FIXME PJF macOS 10.13 and 10.14(?) do not have the path argument + PRINT("__persona ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + PRE_REG_READ6(int, "persona", uint32_t, operation, uint32_t, flags, struct kpersona_info*, info, uid_t*, id, size_t*, idlen, char*, path); + + struct vki_kpersona_info* info = (struct vki_kpersona_info*)ARG3; + SizeT* idlen = (SizeT*)ARG5; + switch (ARG1) { + case VKI_PERSONA_OP_PALLOC: + PRE_MEM_RASCIIZ("__persona(path", ARG6); + // fallthrough + case VKI_PERSONA_OP_ALLOC: + // read info, write to info persona_id field and id + PRE_MEM_READ("__persona(info)", ARG3, sizeof(struct vki_kpersona_info)); + PRE_FIELD_WRITE("__persona(info->persona_id", info->persona_id); + PRE_MEM_WRITE("__persona(id)", ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_DEALLOC: + PRE_MEM_READ("__persona(id)", ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_GET: + PRE_MEM_WRITE("__persona(id)", ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_INFO: + case VKI_PERSONA_OP_PIDINFO: + PRE_MEM_WRITE("__persona(info)", (Addr)info, sizeof(struct vki_kpersona_info)); + PRE_MEM_READ("__persona(id)", ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_FIND: + PRE_MEM_READ("__persona(info)", ARG3, sizeof(struct vki_kpersona_info)); + PRE_MEM_READ("__persona(idlen)", ARG5, sizeof(size_t)); + if (ML_(safe_to_deref)(idlen, sizeof(SizeT))) { + PRE_MEM_WRITE("__persona(id)", ARG4, *idlen*sizeof(vki_uid_t)); + ARG7 = *idlen; + } + PRE_MEM_WRITE("__persona(idlen)", ARG5, sizeof(size_t)); + break; + case VKI_PERSONA_OP_GETPATH: + PRE_MEM_READ("__persona(id)", ARG4, sizeof(vki_uid_t)); + PRE_MEM_WRITE("__persona(path)", ARG6, VKI_MAXPATHLEN); + break; + case VKI_PERSONA_OP_FIND_BY_TYPE: + PRE_MEM_READ("__persona(idlen)", ARG5, sizeof(size_t)); + PRE_FIELD_READ("__persona(info->type)", info->persona_type); + if (ML_(safe_to_deref)(idlen, sizeof(SizeT))) { + PRE_MEM_WRITE("__persona(id)", ARG4, *idlen*sizeof(vki_uid_t)); + ARG7 = *idlen; + } + PRE_MEM_WRITE("__persona(idlen)", ARG5, sizeof(size_t)); + break; + default: + // assert + break; + } +} + +POST(persona) +{ + struct vki_kpersona_info* info = (struct vki_kpersona_info*)ARG3; + SizeT* idlen = (SizeT*)ARG5; + switch (ARG1) { + case VKI_PERSONA_OP_PALLOC: + case VKI_PERSONA_OP_ALLOC: + POST_FIELD_WRITE(info->persona_id); + POST_MEM_WRITE(ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_GET: + POST_MEM_WRITE(ARG4, sizeof(vki_uid_t)); + break; + case VKI_PERSONA_OP_INFO: + case VKI_PERSONA_OP_PIDINFO: + POST_MEM_WRITE(ARG3, sizeof(struct vki_kpersona_info)); + break; + case VKI_PERSONA_OP_GETPATH: + POST_MEM_WRITE(ARG6, VG_(strlen)((char*)ARG6)+1); + break; + case VKI_PERSONA_OP_FIND: + case VKI_PERSONA_OP_FIND_BY_TYPE: + if (ML_(safe_to_deref)(idlen, sizeof(SizeT))) { + POST_MEM_WRITE(ARG4, VG_MIN(*idlen, ARG7)*sizeof(vki_uid_t)); + } + POST_MEM_WRITE(ARG5, sizeof(size_t)); + break; + default: + break; + } +} + /* --------------------------------------------------------------------- Added for macOS 10.12 (Sierra) @@ -10341,15 +11157,28 @@ PRE(host_create_mach_voucher_trap) PRINT("host_create_mach_voucher_trap" "(host:%s, recipes:%#lx, recipes_size:%ld, voucher:%#lx)", name_for_port(ARG1), ARG2, ARG3, ARG4); + // FIXME PJF PRE_REG_READ? PRE_MEM_READ( "host_create_mach_voucher_trap(recipes)", ARG2, ARG3 ); PRE_MEM_WRITE( "host_create_mach_voucher_trap(voucher)", ARG4, sizeof(mach_port_name_t) ); } + POST(host_create_mach_voucher_trap) { vg_assert(SUCCESS); POST_MEM_WRITE( ARG4, sizeof(mach_port_name_t) ); } +// MACH 72 +// kern_return_t mach_voucher_extract_attr_recipe(ipc_voucher_t voucher, +// mach_voucher_attr_key_t key, +// mach_voucher_attr_raw_recipe_t raw_recipe, +// mach_voucher_attr_raw_recipe_size_t *in_out_size) +PRE(mach_voucher_extract_attr_recipe_trap) +{ + PRINT("mach_voucher_extract_attr_recipe(voucher:%#lx, key:%lu, raw_recipe:%#lx, in_out_size:%#lx)", ARG1, ARG2, ARG3, ARG4); + // FIXME PJF add MEM READ/WRITE and POST as needed +} + PRE(task_register_dyld_image_infos) { //#pragma pack(4) @@ -10530,10 +11359,6 @@ POST(kevent_id) } } -PRE(thread_get_special_reply_port) -{ - PRINT("thread_get_special_reply_port()"); -} POST(thread_get_special_reply_port) { @@ -10541,8 +11366,267 @@ POST(thread_get_special_reply_port) PRINT("special reply port %s", name_for_port(RES)); } +PRE(thread_get_special_reply_port) +{ + PRINT("thread_get_special_reply_port()"); + AFTER = POST_FN(thread_get_special_reply_port); + +} + #endif /* DARWIN_VERS >= DARWIN_10_13 */ + +/* --------------------------------------------------------------------- + Added for macOS 10.14 (Mojave) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS >= DARWIN_10_14 +PRE(kernelrpc_mach_port_get_attributes_trap) +{ + PRINT("kernelrpc_mach_port_get_attributes_trap( %s, %s, %ld, %#lx, %#lx )", + name_for_port(ARG1), name_for_port(ARG2), SARG3, ARG4, ARG5); + PRE_REG_READ5(kern_return_t, "kernelrpc_mach_port_get_attributes_trap", + mach_port_name_t, target, mach_port_name_t, name, mach_port_flavor_t, flavor, + mach_port_info_t, port_info_out, mach_msg_type_number_t*, port_info_outCnt); + PRE_MEM_READ( "kernelrpc_mach_port_get_attributes_trap(port_info_outCnt)", ARG5, sizeof(mach_msg_type_number_t)); + PRE_MEM_WRITE( "kernelrpc_mach_port_get_attributes_trap(port_info_outCnt)", ARG5, sizeof(mach_msg_type_number_t)); + mach_msg_type_number_t count = *(mach_msg_type_number_t*)ARG5; + if (count > 0) { + PRE_MEM_WRITE( "kernelrpc_mach_port_get_attributes_trap(port_info_out)", ARG4, count * sizeof(integer_t)); + } +} +#endif /* DARWIN_VERS >= DARWIN_10_14 */ + + +/* --------------------------------------------------------------------- + Added for macOS 10.15 (Catalina) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS >= DARWIN_10_15 + +PRE(task_restartable_ranges_register) +{ + PRINT("task_restartable_ranges_register(%s, %#lx, %ld)", name_for_port(ARG1), ARG2, SARG3); +} + +POST(task_restartable_ranges_register) +{ +#pragma pack(4) + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } Reply; +#pragma pack() + + Reply *reply = (Reply *)ARG1; + + if (!reply->RetCode) { + } else { + PRINT("mig return %d", reply->RetCode); + } +} + +PRE(kernelrpc_mach_port_request_notification_trap) +{ + PRINT("kernelrpc_mach_port_request_notification_trap(%s, %s, %ld, %ld, %s, %ld, %#lx)", + name_for_port(ARG1), name_for_port(ARG2), SARG3, SARG4, name_for_port(ARG5), SARG6, ARG7); + PRE_REG_READ7(kern_return_t, "kernelrpc_mach_port_request_notification_trap", + ipc_space_t, task, mach_port_name_t, name, mach_msg_id_t, msgid, + mach_port_mscount_t, sync, mach_port_name_t, notify, mach_msg_type_name_t, notifyPoly, + mach_port_name_t*, previous); + if (ARG7 != 0) { + PRE_MEM_WRITE("kernelrpc_mach_port_request_notification_trap(previous)", ARG7, sizeof(mach_port_name_t)); + } +} + +POST(kernelrpc_mach_port_request_notification_trap) +{ + if (RES == 0 && ARG7 != 0) { + POST_MEM_WRITE(ARG7, sizeof(mach_port_name_t)); + PRINT("-> previous:%s", name_for_port(*(mach_port_name_t*)ARG7)); + } +} + +PRE(kernelrpc_mach_port_type_trap) +{ + PRINT("kernelrpc_mach_port_type_trap(%s, %s, %#lx)", + name_for_port(ARG1), name_for_port(ARG2), ARG3); + PRE_REG_READ3(kern_return_t, "kernelrpc_mach_port_type_trap", + ipc_space_t, task, mach_port_name_t, name, mach_port_type_t*, ptype); + if (ARG3 != 0) { + PRE_MEM_WRITE("kernelrpc_mach_port_type_trap(ptype)", ARG3, sizeof(mach_port_type_t)); + } +} + +POST(kernelrpc_mach_port_type_trap) +{ + if (RES == 0 && ARG3 != 0) { + POST_MEM_WRITE(ARG3, sizeof(mach_port_type_t)); + PRINT("-> ptype:%#x", *(mach_port_type_t*)ARG3); + } +} + +#endif /* DARWIN_VERS >= DARWIN_10_15 */ + + +/* --------------------------------------------------------------------- + Added for macOS 11.0 (Big Sur) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS >= DARWIN_11_00 + +#define DYLD_VM_END_MWL (-1ull) + +PRE(shared_region_check_np) +{ + // Special value used by dyld to forbid further uses of map_with_linking_np on macOS 13+ + Bool special_call = DARWIN_VERS >= DARWIN_13_00 && ARG1 == DYLD_VM_END_MWL; + + if (special_call) { + PRINT("shared_region_check_np(disable_map_with_linking)"); + } else { + PRINT("shared_region_check_np(%#lx)", ARG1); + } + PRE_REG_READ1(kern_return_t, "shared_region_check_np", uint64_t*, start_address); + + if (!special_call) { + PRE_MEM_WRITE("shared_region_check_np(start_address)", ARG1, sizeof(uint64_t)); +} +} + +POST(shared_region_check_np) +{ + Bool special_call = DARWIN_VERS >= DARWIN_13_00 && ARG1 == DYLD_VM_END_MWL; + + if (special_call) { + return; + } + + if (RES == 0) { + POST_MEM_WRITE(ARG1, sizeof(uint64_t)); + PRINT("shared dyld cache %#llx", *((uint64_t*) ARG1)); + } +} + +PRE(shared_region_map_and_slide_np) +{ + PRINT("shared_region_map_and_slide_np(%ld, %lu, %#lx, %lu, %#lx, %lu)", SARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + PRE_REG_READ6(kern_return_t, "shared_region_map_and_slide_np", + int, fd, uint32_t, count, const struct shared_file_mapping_np*, mappings, + uint32_t, slide, uint64_t*, slide_start, uint32_t, slide_size); +} + +PRE(task_read_for_pid) +{ + PRINT("task_read_for_pid(%s, %ld, %#lx)", name_for_port(ARG1), SARG2, ARG3); + PRE_REG_READ3(kern_return_t, "task_read_for_pid", mach_port_name_t, target_tport, int, pid, mach_port_name_t*, t); + + if (ARG3 != 0) { + PRE_MEM_WRITE("task_read_for_pid(t)", ARG3, sizeof(mach_port_name_t)); + } +} + +POST(task_read_for_pid) +{ + if (RES == 0 && ARG3 != 0) { + POST_MEM_WRITE(ARG3, sizeof(mach_port_name_t)); + PRINT("-> t:%s", name_for_port(*(mach_port_name_t*)ARG3)); + } +} + +PRE(ulock_wait2) +{ + PRINT("ulock_wait2(%ld, %#lx, %ld, %#lx, %ld)", + SARG1, ARG2, SARG3, ARG4, SARG5); + PRE_REG_READ5(int, "ulock_wait2", + uint32_t, operation, void*, addr, uint64_t, value, + uint32_t, timeout, uint64_t, value2); + Int value_size = 4; + if (ARG1 == VKI_UL_COMPARE_AND_WAIT64 + || ARG1 == VKI_UL_COMPARE_AND_WAIT64_SHARED + || ARG1 == VKI_UL_COMPARE_AND_WAIT_SHARED) { + value_size = 8; + } + if (ARG2 != 0) { + PRE_MEM_READ("ulock_wait2(addr)", ARG2, value_size); + *flags |= SfMayBlock; + } else { + SET_STATUS_Failure( VKI_EINVAL ); + } +} + +#if defined(VGA_arm64) +PRE(sys_crossarch_trap) +{ + PRINT("sys_crossarch_trap(%lu)", ARG1); + PRE_REG_READ1(kern_return_t, "sys_crossarch_trap", uint32_t, name); +} + +PRE(objc_bp_assist_cfg_np) +{ + PRINT("objc_bp_assist_cfg_np(%#lx, %#lx)", ARG1, ARG2); +} +#endif + +#endif /* DARWIN_VERS >= DARWIN_11_00 */ + + +/* --------------------------------------------------------------------- + Added for macOS 12.0 (Monterey) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS >= DARWIN_12_00 + +#endif /* DARWIN_VERS >= DARWIN_12_00 */ + + +/* --------------------------------------------------------------------- + Added for macOS 13.0 (Ventura) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS >= DARWIN_13_00 + +struct mwl_region { + int mwlr_fd; + vm_prot_t mwlr_protections; + uint64_t mwlr_file_offset; + mach_vm_address_t mwlr_address; + mach_vm_size_t mwlr_size; +}; + +struct mwl_info_hdr { + uint32_t mwli_version; + uint16_t mwli_page_size; + uint16_t mwli_pointer_format; + uint32_t mwli_binds_offset; + uint32_t mwli_binds_count; + uint32_t mwli_chains_offset; + uint32_t mwli_chains_size; + uint64_t mwli_slide; + uint64_t mwli_image_address; +}; + +#define MWL_MAX_REGION_COUNT 5 /* data, const, data auth, auth const, objc const */ + +PRE(map_with_linking_np) +{ + PRINT("map_with_linking_np(%#lx, %lu, %#lx, %lu)", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "map_with_linking_np", + void*, regions, uint32_t, region_count, + void*, link_info, uint32_t, link_info_size); + if (ARG2 == 0 || ARG2 > MWL_MAX_REGION_COUNT) + if (ARG1) { + PRE_MEM_READ( "map_with_linking_np(regions)", ARG1, sizeof(struct mwl_region) * ARG2 ); + } + if (ARG3) { + PRE_MEM_READ( "map_with_linking_np(link_info)", ARG3, ARG4 ); + } +} + +#endif /* DARWIN_VERS >= DARWIN_13_00 */ + + /* --------------------------------------------------------------------- syscall tables ------------------------------------------------------------------ */ @@ -10629,7 +11713,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { // _____(__NR_reboot), // _____(__NR_revoke), GENX_(__NR_symlink, sys_symlink), // 57 - GENX_(__NR_readlink, sys_readlink), + GENXY(__NR_readlink, sys_readlink), GENX_(__NR_execve, sys_execve), GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), @@ -10652,8 +11736,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENXY(__NR_mincore, sys_mincore), GENXY(__NR_getgroups, sys_getgroups), // _____(__NR_setgroups), // 80 - GENX_(__NR_getpgrp, sys_getpgrp), - GENX_(__NR_setpgid, sys_setpgid), + GENX_(__NR_getpgrp, sys_getpgrp), + GENX_(__NR_setpgid, sys_setpgid), GENXY(__NR_setitimer, sys_setitimer), _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(84)), // old wait // _____(__NR_swapon), @@ -10722,7 +11806,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(148)), // old setquota _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(149)), // old qquota _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(150)), // old getsockname -// _____(__NR_getpgid), + GENX_(__NR_getpgid, sys_getpgid), // _____(__NR_setprivexec), GENXY(__NR_pread, sys_pread64), GENX_(__NR_pwrite, sys_pwrite64), @@ -10753,7 +11837,11 @@ const SyscallTableEntry ML_(syscall_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(175)), // old gc_control // _____(__NR_add_profil), _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(177)), // ??? +#if DARWIN_VERS >= DARWIN_10_11 + MACX_(__NR_kdebug_trace_string, kdebug_trace_string), // 178 +#else _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(178)), // ??? +#endif _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(179)), // ??? MACX_(__NR_kdebug_trace, kdebug_trace), // 180 GENX_(__NR_setgid, sys_setgid), @@ -10800,7 +11888,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { // _____(__NR_kqueue_from_portset_np), // _____(__NR_kqueue_portset_np), #endif -// _____(__NR_mkcomplex), + MACXY(__NR_open_dprotected_np, open_dprotected_np), // 216 // _____(__NR_statv), // _____(__NR_lstatv), // _____(__NR_fstatv), @@ -10813,7 +11901,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENX_(__NR_delete, sys_unlink), // _____(__NR_copyfile), #if DARWIN_VERS >= DARWIN_10_6 - MACX_(__NR_fgetattrlist, fgetattrlist), // 228 + MACXY(__NR_fgetattrlist, fgetattrlist), // 228 // _____(__NR_fsetattrlist), #else _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)), // ?? @@ -10890,7 +11978,9 @@ const SyscallTableEntry ML_(syscall_table)[] = { // _____(__NR_mkfifo_extended), // _____(__NR_mkdir_extended), // _____(__NR_identitysvc), -// _____(__NR_shared_region_check_np), +#if DARWIN_VERS >= DARWIN_11_00 + MACXY(__NR_shared_region_check_np, shared_region_check_np), // 294 +#endif // _____(__NR_shared_region_map_np), #if DARWIN_VERS >= DARWIN_10_6 // _____(__NR_vm_pressure_monitor), @@ -10952,7 +12042,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(326)), // ??? MACX_(__NR_issetugid, issetugid), MACX_(__NR___pthread_kill, __pthread_kill), - MACX_(__NR___pthread_sigmask, __pthread_sigmask), + MACXY(__NR___pthread_sigmask, __pthread_sigmask), MACXY(__NR___sigwait, __sigwait), // 330 MACX_(__NR___disable_threadsignal, __disable_threadsignal), MACX_(__NR___pthread_markcancel, __pthread_markcancel), @@ -11077,12 +12167,14 @@ const SyscallTableEntry ML_(syscall_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(435)), // ??? _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(436)), // ??? _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(437)), // ??? -// _____(__NR_shared_region_map_and_slide_np), // 438 +#if DARWIN_VERS >= DARWIN_11_00 + MACX_(__NR_shared_region_map_and_slide_np, shared_region_map_and_slide_np), // 438 +#endif // _____(__NR_kas_info), // 439 // _____(__NR_memorystatus_control), // 440 MACX_(__NR_guarded_open_np, guarded_open_np), MACX_(__NR_guarded_close_np, guarded_close_np), - MACX_(__NR_guarded_kqueue_np, guarded_kqueue_np), + MACXY(__NR_guarded_kqueue_np, guarded_kqueue_np), MACX_(__NR_change_fdguard_np, change_fdguard_np), MACX_(__NR_connectx, connectx), MACX_(__NR_disconnectx, disconnectx), @@ -11092,16 +12184,17 @@ const SyscallTableEntry ML_(syscall_table)[] = { MACXY(__NR_necp_match_policy, necp_match_policy), // 460 MACXY(__NR_getattrlistbulk, getattrlistbulk), // 461 MACXY(__NR_openat, openat), // 463 - MACX_(__NR_mkdirat, mkdirat), // 475 #if DARWIN_VERS >= DARWIN_10_13 MACXY(__NR_openat_nocancel, openat_nocancel), // 464 #endif MACX_(__NR_faccessat, faccessat), // 466 MACXY(__NR_fstatat64, fstatat64), // 470 + MACX_(__NR_unlinkat, unlinkat), // 472 MACXY(__NR_readlinkat, readlinkat), // 473 + MACX_(__NR_mkdirat, mkdirat), // 475 MACX_(__NR_bsdthread_ctl, bsdthread_ctl), // 478 MACXY(__NR_csrctl, csrctl), // 483 - MACX_(__NR_guarded_open_dprotected_np, guarded_open_dprotected_np), // 484 + MACXY(__NR_guarded_open_dprotected_np, guarded_open_dprotected_np), // 484 MACX_(__NR_guarded_write_np, guarded_write_np), // 485 MACX_(__NR_guarded_pwrite_np, guarded_pwrite_np), // 486 MACX_(__NR_guarded_writev_np, guarded_writev_np), // 487 @@ -11115,7 +12208,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { // _____(__NR_stack_snapshot_with_config), // 491 // _____(__NR_microstackshot), // 492 // _____(__NR_grab_pgo_data), // 493 -// _____(__NR_persona), // 494 + MACXY(__NR_persona, persona), // 494 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(495)), // ??? _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(496)), // ??? _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(497)), // ??? @@ -11161,8 +12254,45 @@ const SyscallTableEntry ML_(syscall_table)[] = { // _____(__NR_ntp_gettime), // 528 // _____(__NR_os_fault_with_payload), // 529 #endif -// _____(__NR_MAXSYSCALL) - MACX_(__NR_DARWIN_FAKE_SIGRETURN, FAKE_SIGRETURN) +#if DARWIN_VERS >= DARWIN_10_14 +// _____(__NR_kqueue_workloop_ctl), // 530 +// _____(__NR___mach_bridge_remote_time), // 531 +#endif +#if DARWIN_VERS >= DARWIN_10_15 +// _____(__NR_coalition_ledger), // 532 +// _____(__NR_log_data), // 533 +// _____(__NR_memorystatus_available_memory), // 534 +#endif +#if DARWIN_VERS >= DARWIN_11_00 +#if defined(VGP_arm64_darwin) + MACX_(__NR_objc_bp_assist_cfg_np, objc_bp_assist_cfg_np), // 535 +#endif +// _____(__NR_shared_region_map_and_slide_2_np), // 536 +// _____(__NR_pivot_root), // 537 +// _____(__NR_task_inspect_for_pid), // 538 + MACXY(__NR_task_read_for_pid, task_read_for_pid), // 539 +// _____(__NR_sys_preadv), // 540 +// _____(__NR_sys_pwritev), // 541 +// _____(__NR_sys_preadv_nocancel), // 542 +// _____(__NR_sys_pwritev_nocancel), // 543 + MACX_(__NR_ulock_wait2, ulock_wait2), // 544 +// _____(__NR_proc_info_extended_id), // 545 +#endif +#if DARWIN_VERS >= DARWIN_12_00 +// _____(__NR_tracker_action), // 546 +// _____(__NR_debug_syscall_reject), // 547 +#endif +#if DARWIN_VERS >= DARWIN_13_00 +// _____(__NR_sys_debug_syscall_reject_config), // 548 +// _____(__NR_graftdmg), // 549 + MACX_(__NR_map_with_linking_np, map_with_linking_np), // 550 +// _____(__NR_freadlink), // 551 +// _____(__NR_sys_record_system_event), // 552 +// _____(__NR_mkfifoat), // 553 +// _____(__NR_mknodat), // 554 +// _____(__NR_ungraftdmg), // 555 +#endif + MACX_(__NR_darwin_fake_sigreturn, fake_sigreturn) }; @@ -11183,12 +12313,12 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(9)), # if DARWIN_VERS >= DARWIN_10_8 - MACXY(__NR_kernelrpc_mach_vm_allocate_trap, kernelrpc_mach_vm_allocate_trap), + MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10), kernelrpc_mach_vm_allocate_trap), # else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10)), # endif - _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11)), + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11), kernelrpc_mach_vm_purgable_control_trap), # if DARWIN_VERS >= DARWIN_10_8 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12), kernelrpc_mach_vm_deallocate_trap), @@ -11214,7 +12344,7 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { # if DARWIN_VERS >= DARWIN_10_8 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16), kernelrpc_mach_port_allocate_trap), MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17), kernelrpc_mach_port_destroy_trap), - MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18), kernelrpc_mach_port_deallocate_trap), + MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18), kernelrpc_mach_port_deallocate_trap), MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19), kernelrpc_mach_port_mod_refs_trap), MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20), kernelrpc_mach_port_move_member_trap), MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21), kernelrpc_mach_port_insert_right_trap), @@ -11253,7 +12383,12 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { MACX_(__NR_semaphore_wait_signal_trap, semaphore_wait_signal), MACX_(__NR_semaphore_timedwait_trap, semaphore_timedwait), MACX_(__NR_semaphore_timedwait_signal_trap, semaphore_timedwait_signal), + +# if DARWIN_VERS >= DARWIN_10_14 + MACX_(__NR_kernelrpc_mach_port_get_attributes_trap, kernelrpc_mach_port_get_attributes_trap), +# else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(40)), // -40 +# endif # if DARWIN_VERS >= DARWIN_10_9 MACX_(__NR_kernelrpc_mach_port_guard_trap, kernelrpc_mach_port_guard_trap), @@ -11273,10 +12408,14 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)), # endif -// _____(__NR_task_name_for_pid), + MACXY(__NR_task_name_for_pid, task_name_for_pid), MACXY(__NR_task_for_pid, task_for_pid), MACXY(__NR_pid_for_task, pid_for_task), +#if DARWIN_VERS >= DARWIN_13_00 + MACXY(__NR_mach_msg2_trap, mach_msg2), +#else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(47)), +#endif #if defined(VGA_x86) // _____(__NR_macx_swapon), // _____(__NR_macx_swapoff), @@ -11320,12 +12459,17 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(70)), #endif _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(71)), - _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(72)), + MACX_(__NR_mach_voucher_extract_attr_recipe_trap, mach_voucher_extract_attr_recipe_trap), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(73)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(74)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(75)), +#if DARWIN_VERS >= DARWIN_10_15 + MACXY(__NR_kernelrpc_mach_port_type_trap, kernelrpc_mach_port_type_trap), + MACXY(__NR_kernelrpc_mach_port_request_notification_trap, kernelrpc_mach_port_request_notification_trap), +#else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(76)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(77)), +#endif _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(78)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(79)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(80)), // -80 @@ -11356,26 +12500,59 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { // calling convention instead of the syscall convention. // Use ML_(mdep_trap_table)[syscallno - ML_(mdep_trap_base)] . -#if defined(VGA_x86) const SyscallTableEntry ML_(mdep_trap_table)[] = { +#if defined(VGA_x86) MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self), -}; #elif defined(VGA_amd64) -const SyscallTableEntry ML_(mdep_trap_table)[] = { MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self), -}; #else #error unknown architecture #endif +}; + +const SyscallTableEntry* ML_(get_darwin_syscall_entry) ( UInt sysno ) +{ + const UInt syscall_table_size = + sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); + + const UInt mach_trap_table_size = + sizeof(ML_(mach_trap_table)) / sizeof(ML_(mach_trap_table)[0]); -const UInt ML_(syscall_table_size) = - sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); + const UInt mdep_trap_table_size = + sizeof(ML_(mdep_trap_table)) / sizeof(ML_(mdep_trap_table)[0]); -const UInt ML_(mach_trap_table_size) = - sizeof(ML_(mach_trap_table)) / sizeof(ML_(mach_trap_table)[0]); + const SyscallTableEntry *table; + Int size; -const UInt ML_(mdep_trap_table_size) = - sizeof(ML_(mdep_trap_table)) / sizeof(ML_(mdep_trap_table)[0]); + switch (VG_DARWIN_SYSNO_CLASS(sysno)) { + case VG_DARWIN_SYSCALL_CLASS_UNIX: + table = ML_(syscall_table); + size = syscall_table_size; + break; + case VG_DARWIN_SYSCALL_CLASS_MACH: + table = ML_(mach_trap_table); + size = mach_trap_table_size; + break; + case VG_DARWIN_SYSCALL_CLASS_MDEP: + table = ML_(mdep_trap_table); + size = mdep_trap_table_size; + break; + default: + vg_assert2(0, "invalid syscall class: %d (syscall: %d / %#x)\n", VG_DARWIN_SYSNO_CLASS(sysno), VG_DARWIN_SYSNO_INDEX(sysno), sysno); + break; + } + + sysno = VG_DARWIN_SYSNO_INDEX(sysno); + if (sysno < size) { + const SyscallTableEntry *sys = &table[sysno]; + if (!sys->before) + return NULL; /* no entry */ + return sys; + } + + /* Can't find a wrapper. */ + return NULL; +} #endif // defined(VGO_darwin) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 0832633213..eb8cc50869 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -8,7 +8,7 @@ Copyright (C) 2000-2008 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -526,6 +526,102 @@ PRE(sys_fork) // SYS_open 5 // generic +// int open(const char *path, int flags, mode_t mode); +PRE(sys_open) +{ + HChar name[30]; // large enough + Bool proc_curproc_file = False; + + /* Check for /proc/curproc/file or /proc//file case + * first so that we can then use the later checks. */ + VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)()); + if (ML_(safe_to_deref)( (void*)(Addr)ARG1, 1 ) + && (VG_(strcmp)((HChar *)(Addr)ARG1, name) == 0 + || VG_(strcmp)((HChar *)(Addr)ARG1, "/proc/curproc/file") == 0)) { + proc_curproc_file = True; + } + + if (ARG2 & VKI_O_CREAT) { + // 3-arg version + PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld, %ld )",ARG1, + (HChar*)(Addr)ARG1, SARG2, SARG3); + PRE_REG_READ3(long, "open", + const char *, filename, int, flags, int, mode); + } else { + // 2-arg version + PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld )",ARG1, + (HChar*)(Addr)ARG1, SARG2); + PRE_REG_READ2(long, "open", + const char *, filename, int, flags); + } + PRE_MEM_RASCIIZ( "open(filename)", ARG1 ); + + // check that we are not trying to open the client exe for writing + if ((ARG2 & VKI_O_WRONLY) || + (ARG2 & VKI_O_RDWR)) { + if (proc_curproc_file) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } else { + vg_assert(VG_(resolved_exename)); + const HChar* path = (const HChar*)ARG1; + if (ML_(safe_to_deref)(path, 1)) { + // we need something like a "ML_(safe_to_deref_path)" that does a binary search for the addressable length, and maybe nul + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } + } + } + + /* Handle the case where the open is of /proc/self/cmdline or + /proc//cmdline, and just give it a copy of the fd for the + fake file we cooked up at startup (in m_main). Also, seek the + cloned fd back to the start. */ + { + HChar* arg1s = (HChar*) (Addr)ARG1; + SysRes sres; + + VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); + if (ML_(safe_to_deref)( arg1s, 1 ) + && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/curproc/cmdline"))) { + sres = VG_(dup)( VG_(cl_cmdline_fd) ); + SET_STATUS_from_SysRes( sres ); + if (!sr_isError(sres)) { + OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); + if (off < 0) + SET_STATUS_Failure( VKI_EMFILE ); + } + return; + } + } + + if (proc_curproc_file) { + // do the syscall with VG_(resolved_exename) + ARG1 = (Word)VG_(resolved_exename); + } + + /* Otherwise handle normally */ + *flags |= SfMayBlock; +} + +POST(sys_open) +{ + vg_assert(SUCCESS); + POST_newFd_RES; + if (!ML_(fd_allowed)(RES, "open", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) + ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1); + } +} + // SYS_close 6 // generic @@ -1510,7 +1606,7 @@ PRE(sys_getsockopt) PRINT("sys_getsockopt ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4,ARG5); PRE_REG_READ5(int, "getsockopt", int, s, int, level, int, optname, - void *, optval, int, *optlen); + void *, optval, vki_socklen_t, *optlen); if (optval_p != (Addr)NULL) { ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, "getsockopt(optval)", @@ -2517,7 +2613,7 @@ PRE(sys_clock_nanosleep) POST(sys_clock_nanosleep) { - if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR) { + if (ARG4 != 0 && RES == VKI_EINTR) { POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) ); } } @@ -2736,7 +2832,7 @@ PRE(sys_lutimes) // int fhopen(const fhandle_t *fhp, int flags); PRE(sys_fhopen) { - PRINT("sys_open ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); + PRINT("sys_fhopen ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); PRE_REG_READ2(int, "fhopen", struct fhandle_t *, fhp, int, flags); PRE_MEM_READ( "fhopen(fhp)", ARG1, sizeof(struct vki_fhandle) ); @@ -4115,11 +4211,8 @@ PRE(sys_sigwait) PRE_REG_READ2(int, "sigwait", const vki_sigset_t *, set, int *, sig); PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t)); - vki_sigset_t* set = (vki_sigset_t*)ARG1; - if (ML_(safe_to_deref)(set, sizeof(vki_sigset_t))) { - *flags |= SfMayBlock; - } PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int)); + *flags |= SfMayBlock; } // sigwait doesn't follow the norm of returning -1 on error @@ -5111,9 +5204,9 @@ PRE(sys_shm_open) PRE_REG_READ3(int, "shm_open", const char *, path, int, flags, vki_mode_t, mode); if (ARG1 == VKI_SHM_ANON) { - PRINT("sys_shm_open(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "u, %hu)", ARG1, ARG2, (vki_mode_t)ARG3); + PRINT("sys_shm_open(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "d, %hu)", ARG1, SARG2, (vki_mode_t)ARG3); } else { - PRINT("sys_shm_open(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu)", ARG1, (HChar *)ARG1, ARG2, (vki_mode_t)ARG3); + PRINT("sys_shm_open(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %hu)", ARG1, (HChar *)ARG1, SARG2, (vki_mode_t)ARG3); PRE_MEM_RASCIIZ( "shm_open(path)", ARG1 ); } *flags |= SfMayBlock; @@ -5176,9 +5269,10 @@ POST(sys_cpuset) // int faccessat(int fd, const char *path, int mode, int flag); PRE(sys_faccessat) { - PRINT("sys_faccessat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); - PRE_REG_READ3(int, "faccessat", - int, fd, const char *, path, int, flag); + PRINT("sys_faccessat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %" FMT_REGWORD "d )", + ARG1, ARG2,(char*)ARG2, SARG3, SARG4); + PRE_REG_READ4(int, "faccessat", + int, fd, const char *, path, int, mode, int, flag); ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "faccessat", tid, status); PRE_MEM_RASCIIZ( "faccessat(path)", ARG2 ); } @@ -5372,9 +5466,39 @@ PRE(sys_freebsd11_mknodat) // int openat(int fd, const char *path, int flags, ...); PRE(sys_openat) { + HChar name[30]; // large enough + Bool proc_curproc_file = False; + + if (ARG3 & VKI_O_CREAT) { + // 4-arg version + PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4); + PRE_REG_READ4(int, "openat", + int, fd, const char *, path, int, flags, vki_mode_t, mode); + } else { + // 3-arg version + PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3); + PRE_REG_READ3(int, "openat", + int, fd, const char *, path, int, flags); + } + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat", tid, status); + PRE_MEM_RASCIIZ("openat(path)", ARG2); + + /* Check for /proc/curproc/file or /proc//file case + * first so that we can then use the later checks. */ + VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)()); + if (ML_(safe_to_deref)( (void*)(Addr)ARG1, 1 ) + && (VG_(strcmp)((HChar *)(Addr)ARG1, name) == 0 + || VG_(strcmp)((HChar *)(Addr)ARG1, "/proc/curproc/file") == 0)) { + proc_curproc_file = True; + } + // check that we are not trying to open the client exe for writing if ((ARG3 & VKI_O_WRONLY) || (ARG3 & VKI_O_RDWR)) { + if (proc_curproc_file) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } vg_assert(VG_(resolved_exename) && VG_(resolved_exename)[0] == '/'); Int fd = ARG1; const HChar* path = (const HChar*)ARG2; @@ -5383,41 +5507,56 @@ PRE(sys_openat) HChar tmp[VKI_PATH_MAX]; if (VG_(realpath)(path, tmp)) { if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { - SET_STATUS_Failure( VKI_ETXTBSY ); + SET_STATUS_Failure( VKI_ETXTBSY ); + return; } } } else { const HChar* dirname; - if (VG_(resolve_filename)(fd, &dirname) == False) { - goto no_client_write; // let the OS do the error handling - } - HChar tmp1[VKI_PATH_MAX]; - VG_(snprintf)(tmp1, VKI_PATH_MAX, "%s/%s", dirname, path); - tmp1[VKI_PATH_MAX - 1] = '\0'; - //VG_(free)((void*)dirname); - HChar tmp2[VKI_PATH_MAX]; - if (VG_(realpath)(tmp1, tmp2)) { - if (!VG_(strcmp)(tmp2, VG_(resolved_exename))) { + if (VG_(resolve_filename)(fd, &dirname) == True) { + HChar tmp1[VKI_PATH_MAX]; + VG_(snprintf)(tmp1, VKI_PATH_MAX, "%s/%s", dirname, path); + tmp1[VKI_PATH_MAX - 1] = '\0'; + //VG_(free)((void*)dirname); + HChar tmp2[VKI_PATH_MAX]; + if (VG_(realpath)(tmp1, tmp2)) { + if (!VG_(strcmp)(tmp2, VG_(resolved_exename))) { SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } } } } } } -no_client_write: - if (ARG3 & VKI_O_CREAT) { - // 4-arg version - PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4); - PRE_REG_READ4(int, "openat", - int, fd, const char *, path, int, flags, vki_mode_t, mode); - } else { - // 3-arg version - PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3); - PRE_REG_READ3(int, "openat", - int, fd, const char *, path, int, flags); + + /* Handle the case where the open is of /proc/curproc/cmdline or + /proc//cmdline, and just give it a copy of the fd for the + fake file we cooked up at startup (in m_main). Also, seek the + cloned fd back to the start. */ + { + HChar* arg2s = (HChar*) (Addr)ARG2; + SysRes sres; + + VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); + if (ML_(safe_to_deref)( arg2s, 1 ) + && (VG_STREQ(arg2s, name) || VG_STREQ(arg2s, "/proc/curproc/cmdline"))) { + + sres = VG_(dup)( VG_(cl_cmdline_fd) ); + SET_STATUS_from_SysRes( sres ); + if (!sr_isError(sres)) { + OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); + if (off < 0) + SET_STATUS_Failure( VKI_EMFILE ); + } + return; + } + } + + if (proc_curproc_file) { + // do the syscall with VG_(resolved_exename) + ARG2 = (Word)VG_(resolved_exename); } - ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat", tid, status); - PRE_MEM_RASCIIZ("openat(path)", ARG2); /* Otherwise handle normally */ *flags |= SfMayBlock; @@ -6026,13 +6165,13 @@ POST(sys_rctl_remove_rule) } // SYS_posix_fallocate 530 -// x86/amd64 +// x86/amd64/arm64 // SYS_posix_fadvise 531 -// x86/amd64 +// x86/amd64/arm64 // SYS_wait6 532 -// amd64 / x86 +// x86/amd64/arm64 // SYS_cap_rights_limit 533 //int cap_rights_limit(int fd, const cap_rights_t *rights); @@ -6281,7 +6420,8 @@ PRE(sys_utimensat) int, flag); ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "utimensat", tid, status); PRE_MEM_RASCIIZ("utimensat(path)", ARG2); - PRE_MEM_READ("utimensat(times)", ARG3, 2*sizeof(struct vki_timespec)); + if (ARG3) + PRE_MEM_READ("utimensat(times)", ARG3, 2*sizeof(struct vki_timespec)); } // SYS_fdatasync 550 @@ -6581,7 +6721,7 @@ PRE(sys_copy_file_range) valgrind itself uses some, so make sure someone didn't put in one of our own... */ if (!ML_(fd_allowed)(ARG1, "copy_file_range(infd)", tid, False) || - !ML_(fd_allowed)(ARG3, "copy_file_range(infd)", tid, False)) + !ML_(fd_allowed)(ARG3, "copy_file_range(outfd)", tid, False)) SET_STATUS_Failure( VKI_EBADF ); /* Now see if the offsets are defined. PRE_MEM_READ will @@ -6852,16 +6992,10 @@ PRE(sys_aio_writev) // by the members of the iocb->aio_iov array // FreeBSD headers #define define this to aio_iovcnt SizeT vec_count = (SizeT)iocb->aio_nbytes; -#if defined(__clang__) -#pragma clang diagnostic push - // yes, I know it is volatile -#pragma clang diagnostic ignored "-Wcast-qual" -#endif - struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - PRE_MEM_READ("aio_writev(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec)); + uintptr_t uint_aio_buf = (uintptr_t)iocb->aio_buf; + struct vki_iovec* p_iovec = (struct vki_iovec*)uint_aio_buf; + + PRE_MEM_READ("aio_writev(iocb->aio_iov)", uint_aio_buf, vec_count*sizeof(struct vki_iovec)); // and this to aio_iov if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) { @@ -6889,15 +7023,7 @@ PRE(sys_aio_readv) SET_STATUS_Failure( VKI_EBADF ); } else { SizeT vec_count = (SizeT)iocb->aio_nbytes; -#if defined(__clang__) -#pragma clang diagnostic push - // yes, I know it is volatile -#pragma clang diagnostic ignored "-Wcast-qual" -#endif - struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif + struct vki_iovec* p_iovec = (struct vki_iovec*)(uintptr_t)iocb->aio_buf; PRE_MEM_READ("aio_readv(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec)); if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) { for (SizeT i = 0U; i < vec_count; ++i) { @@ -7121,7 +7247,7 @@ POST(sys_getrlimitusage) break; case VKI_RLIMIT_STACK: /* - * The main client stack is quite different when running under Valgrind. + * The main client stack is quite different when running under Valgrind. * See aspacemg-linux.c for details, but in short on 64bit systems * the main stack starts with 128k reserved and a 512M limit. * Valgrind just has one value, 16M by default (can be changed with @@ -7223,6 +7349,39 @@ PRE(sys_jail_remove_jd) SET_STATUS_Failure(VKI_EBADF); } +// SYS_pdwait 601 +// pid_t pdwait(int fd, int *status, int options, +// struct __wrusage *wrusage, siginfo_t *infop); +PRE(sys_pdwait) +{ + PRINT("sys_pdwait ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", + SARG1, ARG2, SARG3, ARG4, ARG5); + PRE_REG_READ5(pid_t, "pdwait", int, fd, int *, status, int, options, + struct vki___wrusage *, wrusage, vki_siginfo_t *,infop); + PRE_MEM_WRITE("pdwait(status)", ARG2, sizeof(int)); + if (ARG5) { + PRE_MEM_WRITE("pdwait(wrusage)", ARG4, sizeof(struct vki___wrusage)); + } + if (ARG6) { + PRE_MEM_WRITE("pdwait(infop)", ARG5, sizeof(vki_siginfo_t)); + } + if (!ML_(fd_allowed)(ARG1, "pdwait", tid, False)) { + SET_STATUS_Failure(VKI_EBADF); + } +} + +POST(sys_pdwait) +{ + POST_MEM_WRITE(ARG2, sizeof(int)); + if (ARG5) { + POST_MEM_WRITE(ARG4, sizeof(struct vki___wrusage)); + } + + if (ARG6) { + POST_MEM_WRITE(ARG5, sizeof(vki_siginfo_t)); + } +} + #undef PRE #undef POST @@ -7233,7 +7392,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENXY(__NR_read, sys_read), // 3 GENX_(__NR_write, sys_write), // 4 - GENXY(__NR_open, sys_open), // 5 + BSDXY(__NR_open, sys_open), // 5 GENX_(__NR_close, sys_close), // 6 GENXY(__NR_wait4, sys_wait4), // 7 @@ -7610,7 +7769,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENX_(__NR_mlockall, sys_mlockall), // 324 BSDX_(__NR_munlockall, sys_munlockall), // 325 BSDXY(__NR___getcwd, sys___getcwd), // 326 - BSDX_(__NR_sched_setparam, sys_sched_setparam), // 327 + BSDXY(__NR_sched_setparam, sys_sched_setparam), // 327 BSDXY(__NR_sched_getparam, sys_sched_getparam), // 328 BSDX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 329 BSDX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 330 @@ -7938,10 +8097,16 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENXY(__NR_getgroups, sys_getgroups), // 596 #endif - BSDX_(__NR_jail_attach_jd, sys_jail_attach_jd), // 597 - BSDX_(__NR_jail_remove_jd, sys_jail_remove_jd), // 598 + BSDX_(__NR_jail_attach_jd, sys_jail_attach_jd), // 597 + BSDX_(__NR_jail_remove_jd, sys_jail_remove_jd), // 598 + BSDX_(__NR_kexec_load, sys_kexec_load), // 599 + // we only have partial support for rfork, so mark pdrfork + // as not implemented for the moment + GENX_(__NR_pdrfork, sys_ni_syscall), // 600 + BSDXY(__NR_pdwait, sys_pdwait), // 601 + GENX_(__NR_renameat2, sys_renameat2), // 602 - BSDX_(__NR_fake_sigreturn, sys_fake_sigreturn), // 1000, fake sigreturn + BSDX_(__NR_freebsd_fake_sigreturn, sys_fake_sigreturn), // 1000, fake sigreturn }; diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 37f312fe8f..e3f4bf55fe 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -270,7 +270,20 @@ ML_(notify_core_and_tool_of_mprotect) ( Addr a, SizeT len, Int prot ) "ML_(notify_core_and_tool_of_mprotect)" ); } - +#if defined(VGO_linux) +void +ML_(notify_core_and_tool_of_madv_guard) ( Addr a, SizeT len, Bool install ) +{ + page_align_addr_and_len(&a, &len); + if (install) { + if (VG_(am_notify_madv_guard)( a, len, True )) + VG_(discard_translations)( a, (ULong)len, + "ML_(notify_core_and_tool_of_madv_guard)" ); + } else { + VG_(am_notify_madv_guard)(a, len, False); + } +} +#endif #if HAVE_MREMAP /* Expand (or shrink) an existing mapping, potentially moving it at @@ -3114,6 +3127,22 @@ PRE(sys_madvise) unsigned long, start, vki_size_t, length, int, advice); } +#if defined(VGO_linux) +POST(sys_madvise) +{ + if (ARG3 == VKI_MADV_GUARD_INSTALL) { + Addr a = ARG1; + SizeT len = ARG2; + ML_(notify_core_and_tool_of_madv_guard)(a, len, True); + } + if (ARG3 == VKI_MADV_GUARD_REMOVE) { + Addr a = ARG1; + SizeT len = ARG2; + ML_(notify_core_and_tool_of_madv_guard)(a, len, False); + } +} +#endif + #if HAVE_MREMAP PRE(sys_mremap) { @@ -3381,7 +3410,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, PRE_MEM_READ(str2, arg_2_check, sizeof(Addr)); /* argv[0] should not be NULL and valid. */ - if (ML_(safe_to_deref)((HChar **) (Addr)arg_2_check, sizeof(HChar *))) { + if (ML_(safe_to_deref)((HChar **)arg_2_check, sizeof(HChar *))) { Addr argv0 = *(Addr*)arg_2_check; PRE_MEM_RASCIIZ( str3, argv0 ); /* The rest of argv can be NULL or a valid string pointer. */ @@ -3400,7 +3429,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, str3[VG_(strlen)(str)] = '\0'; if (arg_3 != 0) { /* At least the terminating NULL must be addressable. */ - if (!ML_(safe_to_deref)((HChar **) (Addr)arg_3, sizeof(HChar *))) { + if (!ML_(safe_to_deref)((HChar **)arg_3, sizeof(HChar *))) { SET_STATUS_Failure(VKI_EFAULT); return; } @@ -3429,11 +3458,11 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, // debug-only printing if (0) { - VG_(printf)("pathname = %p(%s)\n", (void*)(Addr)pathname, (HChar*)(Addr)pathname); + VG_(printf)("pathname = %p(%s)\n", (void*)pathname, (HChar*)pathname); if (arg_2) { VG_(printf)("arg_2 = "); Int q; - HChar** vec = (HChar**)(Addr)arg_2; + HChar** vec = (HChar**)arg_2; for (q = 0; vec[q]; q++) VG_(printf)("%p(%s) ", vec[q], vec[q]); VG_(printf)("\n"); @@ -3445,10 +3474,10 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, // Decide whether or not we want to follow along { // Make 'child_argv' be a pointer to the child's arg vector // (skipping the exe name) - const HChar** child_argv = (const HChar**)(Addr)arg_2; + const HChar** child_argv = (const HChar**)arg_2; if (child_argv && child_argv[0] == NULL) child_argv = NULL; - trace_this_child = VG_(should_we_trace_this_child)( (HChar*)(Addr)pathname, + trace_this_child = VG_(should_we_trace_this_child)( (HChar*)pathname, child_argv ); } @@ -3456,7 +3485,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, // ok, etc. We allow setuid executables to run only in the case when // we are not simulating them, that is, they to be run natively. setuid_allowed = trace_this_child ? False : True; - res = VG_(pre_exec_check)((const HChar *)(Addr)pathname, NULL, setuid_allowed); + res = VG_(pre_exec_check)((const HChar *)pathname, NULL, setuid_allowed); if (sr_isError(res)) { SET_STATUS_Failure( sr_Err(res) ); return; @@ -3473,7 +3502,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, } /* After this point, we can't recover if the execve fails. */ - VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)(Addr)pathname); + VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)pathname); // Terminate gdbserver if it is active. @@ -3509,7 +3538,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, } } else { - path = (HChar*)(Addr)pathname; + path = (HChar*)pathname; } // Set up the child's environment. @@ -3526,7 +3555,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, if (arg_3 == 0) { envp = NULL; } else { - envp = VG_(env_clone)( (HChar**)(Addr)arg_3 ); + envp = VG_(env_clone)( (HChar**)arg_3 ); if (envp == NULL) goto hosed; VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL ); } @@ -3545,7 +3574,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, // are omitted. // if (!trace_this_child) { - argv = (HChar**)(Addr)arg_2; + argv = (HChar**)arg_2; } else { vg_assert( VG_(args_for_valgrind) ); vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 ); @@ -3560,7 +3589,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, // name of client exe tot_args++; // args for client exe, skipping [0] - arg2copy = (HChar**)(Addr)arg_2; + arg2copy = (HChar**)arg_2; if (arg2copy && arg2copy[0]) { for (i = 1; arg2copy[i]; i++) tot_args++; @@ -3576,7 +3605,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, continue; argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ); } - argv[j++] = (HChar*)(Addr)pathname; + argv[j++] = (HChar*)pathname; if (arg2copy && arg2copy[0]) for (i = 1; arg2copy[i]; i++) argv[j++] = arg2copy[i]; @@ -3650,7 +3679,7 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, vg_assert(FAILURE); VG_(message)(Vg_UserMsg, "execve(%#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x) failed, errno %lu\n", - pathname, (HChar*)(Addr)pathname, arg_2, arg_3, ERR); + pathname, (HChar*)pathname, arg_2, arg_3, ERR); VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from " "execve() failing, so I'm dying.\n"); VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), " @@ -4763,14 +4792,14 @@ POST(sys_nanosleep) POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); } -#if defined(VGO_linux) || defined(VGO_solaris) +#if defined(VGO_linux) /* Handles the case where the open is of /proc/self/auxv or /proc//auxv, and just gives out a copy of the fd for the fake file we cooked up at startup (in m_main). Also, seeks the cloned fd back to the start. Returns True if auxv open was handled (status is set). */ -Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, - int flags) +static Bool handle_auxv_open(SyscallStatus *status, const HChar *filename, + int flags) { HChar name[30]; // large enough @@ -4779,7 +4808,7 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, /* Opening /proc//auxv or /proc/self/auxv? */ VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)()); - if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/auxv")) + if ((VG_(strcmp)(filename, name)!=0) && (VG_(strcmp)(filename, "/proc/self/auxv")!=0)) return False; /* Allow to open the file only for reading. */ @@ -4788,11 +4817,6 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, return True; } -# if defined(VGO_solaris) - VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_auxv_fd)); - SysRes sres = VG_(open)(name, flags, 0); - SET_STATUS_from_SysRes(sres); -# else SysRes sres = VG_(dup)(VG_(cl_auxv_fd)); SET_STATUS_from_SysRes(sres); if (!sr_isError(sres)) { @@ -4800,15 +4824,12 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, if (off < 0) SET_STATUS_Failure(VKI_EMFILE); } -# endif return True; } -#endif // defined(VGO_linux) || defined(VGO_solaris) -#if defined(VGO_linux) -Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, - int flags) +static Bool handle_self_exe_open(SyscallStatus *status, const HChar *filename, + int flags) { HChar name[30]; // large enough for /proc//exe @@ -4817,7 +4838,7 @@ Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, /* Opening /proc//exe or /proc/self/exe? */ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); - if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe")) + if ((VG_(strcmp)(filename, name)!=0) && (VG_(strcmp)(filename, "/proc/self/exe")!=0)) return False; /* Allow to open the file only for reading. */ @@ -4908,7 +4929,7 @@ PRE(sys_open) VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); if (ML_(safe_to_deref)( arg1s, 1 ) - && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/cmdline"))) { + && (VG_(strcmp)(arg1s, name)==0 || VG_(strcmp)(arg1s, "/proc/self/cmdline")==0)) { sres = VG_(dup)( VG_(cl_cmdline_fd) ); SET_STATUS_from_SysRes( sres ); if (!sr_isError(sres)) { @@ -4922,8 +4943,8 @@ PRE(sys_open) /* Handle also the case of /proc/self/auxv or /proc//auxv or /proc/self/exe or /proc//exe. */ - if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2) - || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2)) + if (handle_auxv_open(status, (const HChar *)(Addr)ARG1, ARG2) + || handle_self_exe_open(status, (const HChar *)(Addr)ARG1, ARG2)) return; if (proc_self_exe) { @@ -5030,8 +5051,13 @@ PRE(sys_poll) *flags |= SfMayBlock; PRINT("sys_poll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )\n", ARG1, ARG2, SARG3); +#if defined(VGO_darwin) + PRE_REG_READ3(long, "poll", + struct vki_pollfd *, ufds, unsigned int, nfds, int, timeout); +#else PRE_REG_READ3(long, "poll", struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout); +#endif for (i = 0; i < ARG2; i++) { PRE_MEM_READ( "poll(ufds.fd)", @@ -5060,20 +5086,16 @@ POST(sys_poll) PRE(sys_readlink) { - FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3); PRE_REG_READ3(long, "readlink", const char *, path, char *, buf, int, bufsiz); PRE_MEM_RASCIIZ( "readlink(path)", ARG1 ); PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 ); -} -POST(sys_readlink) -{ + Bool fuse_may_block = True; #if defined(VGO_linux) || defined(VGO_solaris) { - Word saved = SYSNO; #if defined(VGO_linux) #define PID_EXEPATH "/proc/%d/exe" #define SELF_EXEPATH "/proc/self/exe" @@ -5091,15 +5113,28 @@ POST(sys_readlink) HChar* arg1s = (HChar*) (Addr)ARG1; VG_(sprintf)(name, PID_EXEPATH, VG_(getpid)()); if (ML_(safe_to_deref)(arg1s, 1) - && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, SELF_EXEPATH))) { - VG_(sprintf)(name, SELF_EXEFD, VG_(cl_exec_fd)); - SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, - ARG2, ARG3)); + && (VG_(strcmp)(arg1s, name)==0 || VG_(strcmp)(arg1s, SELF_EXEPATH)==0)) { + HChar* out_name = (HChar*)ARG2; + SizeT res = VG_(strlen)(VG_(resolved_exename)); + res = VG_MIN(res, ARG3); + if (ML_(safe_to_deref)(out_name, res)) { + VG_(strncpy)(out_name, VG_(resolved_exename), res); + SET_STATUS_Success(res); + } else { + SET_STATUS_Failure(VKI_EFAULT); + } + fuse_may_block = False; } } #endif - if (SUCCESS && RES > 0) - POST_MEM_WRITE( ARG2, RES ); + + if (fuse_may_block) + FUSE_COMPATIBLE_MAY_BLOCK(); +} + +POST(sys_readlink) +{ + POST_MEM_WRITE( ARG2, RES ); } PRE(sys_readv) @@ -5565,6 +5600,22 @@ PRE(sys_sethostname) PRE_MEM_READ( "sethostname(name)", ARG1, ARG2 ); } +PRE(sys_renameat2) +{ + FUSE_COMPATIBLE_MAY_BLOCK(); + PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD + "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, + ARG4, (HChar*)(Addr)ARG4, ARG5); + PRE_REG_READ5(long, "renameat2", + int, olddfd, const char *, oldpath, + int, newdfd, const char *, newpath, + unsigned int, flags); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "renameat2(olddirfd)", tid, status); + ML_(fd_at_check_allowed)(SARG3, (const HChar*)ARG4, "renameat2(newdirfd)", tid, status); + PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 ); + PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 ); +} + #undef PRE #undef POST diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 3606bb9ad6..a1097c3167 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -130,7 +130,7 @@ static void run_a_thread_NORETURN ( Word tidW ) Int registered_vgstack_id; #endif - VG_(debugLog)(1, "syswrap-linux", + VG_(debugLog)(1, "syswrap-linux", "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n", tid); @@ -146,14 +146,14 @@ static void run_a_thread_NORETURN ( Word tidW ) is the stack to use by the outer to e.g. do stacktraces. */ INNER_REQUEST - (registered_vgstack_id + (registered_vgstack_id = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, tst->os_state.valgrind_stack_init_SP)); - + /* Run the thread all the way through. */ - src = thread_wrapper(tid); + src = thread_wrapper(tid); - VG_(debugLog)(1, "syswrap-linux", + VG_(debugLog)(1, "syswrap-linux", "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n", tid); @@ -180,7 +180,7 @@ static void run_a_thread_NORETURN ( Word tidW ) "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n" ); VG_(debugLog)( - 1, "syswrap-linux", + 1, "syswrap-linux", "run_a_thread_NORETURN(tid=%u): " "WARNING: exiting thread has err_disablement_level = %u\n", tid, tst->err_disablement_level @@ -190,18 +190,18 @@ static void run_a_thread_NORETURN ( Word tidW ) if (c == 1) { - VG_(debugLog)(1, "syswrap-linux", + VG_(debugLog)(1, "syswrap-linux", "run_a_thread_NORETURN(tid=%u): " "last one standing\n", tid); /* We are the last one standing. Keep hold of the lock and - carry on to show final tool results, then exit the entire system. + carry on to show final tool results, then exit the entire system. Use the continuation pointer set at startup in m_main. */ ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src); } else { - VG_(debugLog)(1, "syswrap-linux", + VG_(debugLog)(1, "syswrap-linux", "run_a_thread_NORETURN(tid=%u): " "not last one standing\n", tid); @@ -371,10 +371,10 @@ Addr ML_(allocstack)(ThreadId tid) if (0) VG_(printf)( "stack for tid %u at %p; init_SP=%p\n", - tid, - (void*)tst->os_state.valgrind_stack_base, + tid, + (void*)tst->os_state.valgrind_stack_base, (void*)tst->os_state.valgrind_stack_init_SP ); - + return tst->os_state.valgrind_stack_init_SP; } @@ -386,7 +386,7 @@ Addr ML_(allocstack)(ThreadId tid) void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) { Addr sp; - VG_(debugLog)(1, "syswrap-linux", + VG_(debugLog)(1, "syswrap-linux", "entering VG_(main_thread_wrapper_NORETURN)\n"); sp = ML_(allocstack)(tid); @@ -397,7 +397,7 @@ void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) // reports 'write error' on the non registered stack. ThreadState* tst = VG_(get_ThreadState)(tid); INNER_REQUEST - ((void) + ((void) VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, tst->os_state.valgrind_stack_init_SP)); } @@ -427,7 +427,7 @@ void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) /* shouldn't be any other threads around yet */ vg_assert( VG_(count_living_threads)() == 1 ); - ML_(call_on_new_stack_0_1)( + ML_(call_on_new_stack_0_1)( (Addr)sp, /* stack */ 0, /* bogus return address */ run_a_thread_NORETURN, /* fn to call */ @@ -441,11 +441,11 @@ void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) /* Clone a new thread. Note that in the clone syscalls, we hard-code tlsaddr argument as NULL : the guest TLS is emulated via guest registers, and Valgrind itself has no thread local storage. */ -static SysRes clone_new_thread ( Word (*fn)(void *), - void* stack, - Word flags, +static SysRes clone_new_thread ( Word (*fn)(void *), + void* stack, + Word flags, ThreadState* ctst, - Int* child_tidptr, + Int* child_tidptr, Int* parent_tidptr) { SysRes res; @@ -479,7 +479,7 @@ static SysRes clone_new_thread ( Word (*fn)(void *), /* High half word64 is syscall return value. Low half is the entire CR, from which we need to extract CR0.SO. */ /* VG_(printf)("word64 = 0x%llx\n", word64); */ - res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32), + res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32), /*errflag*/ (((UInt)word64) >> 28) & 1); #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) ULong word64; @@ -496,7 +496,7 @@ static SysRes clone_new_thread ( Word (*fn)(void *), the entire CR, from which we need to extract CR0.SO. */ /* VG_(printf)("word64 = 0x%llx\n", word64); */ res = VG_(mk_SysRes_ppc64_linux) - (/*val*/(UInt)(word64 & 0xFFFFFFFFULL), + (/*val*/(UInt)(word64 & 0xFFFFFFFFULL), /*errflag*/ (UInt)((word64 >> (32+28)) & 1), flag); #elif defined(VGP_s390x_linux) ULong r2; @@ -535,7 +535,7 @@ static SysRes clone_new_thread ( Word (*fn)(void *), (ML_(start_thread_NORETURN), stack, flags, ctst, child_tidptr, parent_tidptr, NULL); /* High half word64 is syscall return value. Low half is - the entire CR, from which we need to extract CR0.SO. */ + the entire CR, from which we need to extract CR0.SO. */ res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0); #elif defined(VGP_nanomips_linux) UInt ret = 0; @@ -557,16 +557,16 @@ static SysRes clone_new_thread ( Word (*fn)(void *), return res; } -static void setup_child ( /*OUT*/ ThreadArchState *child, +static 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; #if defined(VGP_x86_linux) - extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child, + extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child, /*IN*/ ThreadArchState *parent ); ML_(x86_setup_LDT_GDT)(child, parent); #endif @@ -587,7 +587,7 @@ static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr) if (debug) VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u " "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n", - tlsinfo, tlsinfo->entry_number, + tlsinfo, tlsinfo->entry_number, tlsinfo->base_addr, tlsinfo->limit, ctst->arch.vex.guest_ESP, ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS); @@ -619,9 +619,9 @@ static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr) # error Unknown platform #endif return res; -} +} -/* +/* When a client clones, we need to keep track of the new thread. This means: 1. allocate a ThreadId+ThreadState+stack for the thread @@ -631,10 +631,10 @@ static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr) but using the scheduler entrypoint for EIP, and a separate stack for ESP. */ -static SysRes do_clone ( ThreadId ptid, - UWord flags, Addr sp, - Int* parent_tidptr, - Int* child_tidptr, +static SysRes do_clone ( ThreadId ptid, + UWord flags, Addr sp, + Int* parent_tidptr, + Int* child_tidptr, Addr tlsaddr) { ThreadId ctid = VG_(alloc_ThreadState)(); @@ -690,7 +690,7 @@ static SysRes do_clone ( ThreadId ptid, ctst->os_state.threadgroup = ptst->os_state.threadgroup; ML_(guess_and_register_stack) (sp, ctst); - + /* Assume the clone will succeed, and tell any tool that wants to know that this thread has come into existence. We cannot defer it beyond this point because setup_tls, just below, @@ -755,7 +755,7 @@ static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, vki_sigset_t mask; SysRes res; - if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM + if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM | VKI_CLONE_FILES)) return VG_(mk_SysRes_Error)( VKI_EINVAL ); @@ -774,14 +774,14 @@ static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \ || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ || defined(VGP_nanomips_linux) || defined(VGP_riscv64_linux) - res = VG_(do_syscall5)( __NR_clone, flags, - (UWord)NULL, (UWord)parent_tidptr, + res = VG_(do_syscall5)( __NR_clone, flags, + (UWord)NULL, (UWord)parent_tidptr, (UWord)NULL, (UWord)child_tidptr ); #elif defined(VGP_amd64_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, - (UWord)NULL, (UWord)parent_tidptr, + res = VG_(do_syscall5)( __NR_clone, flags, + (UWord)NULL, (UWord)parent_tidptr, (UWord)child_tidptr, (UWord)NULL ); #elif defined(VGP_s390x_linux) /* Note that s390 has the stack first and then the flags */ @@ -799,8 +799,8 @@ static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, /* restore signal mask */ VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); - } - else + } + else if (!sr_isError(res) && sr_Res(res) > 0) { /* parent */ VG_(do_atfork_parent)(tid); @@ -877,7 +877,7 @@ PRE(sys_clone) PRA3("clone", int *, parent_tidptr); } PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); - if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), + if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) { badarg = True; } @@ -891,7 +891,7 @@ PRE(sys_clone) ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */ if (sizeof(vki_modify_ldt_t) > 1) { PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t)); - if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t), + if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t), VKI_PROT_READ)) { badarg = True; } @@ -902,7 +902,7 @@ PRE(sys_clone) PRA_CHILD_TIDPTR("clone", int *, child_tidptr); } PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int)); - if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int), + if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int), VKI_PROT_WRITE)) { badarg = True; } @@ -921,7 +921,7 @@ PRE(sys_clone) } /* Only look at the flags we really care about */ - switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS + 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 */ @@ -1132,7 +1132,7 @@ PRE(sys_getresuid) { PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); - PRE_REG_READ3(long, "getresuid", + PRE_REG_READ3(long, "getresuid", vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid); PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) ); PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) ); @@ -1153,7 +1153,7 @@ PRE(sys_setresgid16) PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); PRE_REG_READ3(long, "setresgid16", - vki_old_gid_t, rgid, + vki_old_gid_t, rgid, vki_old_gid_t, egid, vki_old_gid_t, sgid); } @@ -1190,7 +1190,7 @@ PRE(sys_getresgid) { PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); - PRE_REG_READ3(long, "getresgid", + PRE_REG_READ3(long, "getresgid", vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid); PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) ); PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) ); @@ -1235,7 +1235,7 @@ PRE(sys_exit_group) syscall. */ for (t = 1; t < VG_N_THREADS; t++) { if ( /* not alive */ - VG_(threads)[t].status == VgTs_Empty + VG_(threads)[t].status == VgTs_Empty || /* not our group */ VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup @@ -1248,12 +1248,12 @@ PRE(sys_exit_group) /* Indicate in all other threads that the process is exiting. Then wait using VG_(reap_threads) for these threads to disappear. - + Can this give a deadlock if another thread is calling exit in parallel and would then wait for this thread to disappear ? The answer is no: Other threads are either blocked in a syscall or have yielded the CPU. - + A thread that has yielded the CPU is trying to get the big lock in VG_(scheduler). This thread will get the CPU thanks to the call to VG_(reap_threads). The scheduler will then check for signals, @@ -1262,7 +1262,7 @@ PRE(sys_exit_group) the thread status is VG_(is_exiting), the scheduler exits the thread. So, a thread that has yielded the CPU does not have a chance to call exit => no deadlock for this thread. - + VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal to all threads blocked in a syscall. The syscall will be interrupted, and the control will go to the @@ -1395,7 +1395,7 @@ PRE(sys_syslog) case 2: case 3: case 4: PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3); break; - default: + default: break; } } @@ -1440,7 +1440,7 @@ PRE(sys_sysctl) args = (struct __vki_sysctl_args *)(Addr)ARG1; PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args); PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) ); - if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args), + if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args), VKI_PROT_READ)) { SET_STATUS_Failure( VKI_EFAULT ); return; @@ -1690,7 +1690,7 @@ static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout, SyscallArgs* arrghs, SyscallStatus* status, UWord* flags, Bool is_time64 ) { - /* + /* arg param used by ops ARG1 - u32 *futex all @@ -1706,11 +1706,11 @@ static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout, case VKI_FUTEX_WAKE_OP: case VKI_FUTEX_CMP_REQUEUE_PI: if (is_time64) { - PRE_REG_READ6(long, "futex_time64", + PRE_REG_READ6(long, "futex_time64", vki_u32 *, futex, int, op, int, val, struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3); } else { - PRE_REG_READ6(long, "futex", + PRE_REG_READ6(long, "futex", vki_u32 *, futex, int, op, int, val, struct timespec *, utime, vki_u32 *, uaddr2, int, val3); } @@ -1718,11 +1718,11 @@ static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout, case VKI_FUTEX_REQUEUE: case VKI_FUTEX_WAIT_REQUEUE_PI: if (is_time64) { - PRE_REG_READ5(long, "futex_time64", + PRE_REG_READ5(long, "futex_time64", vki_u32 *, futex, int, op, int, val, struct timespec64 *, utime, vki_u32 *, uaddr2); } else { - PRE_REG_READ5(long, "futex", + PRE_REG_READ5(long, "futex", vki_u32 *, futex, int, op, int, val, struct timespec *, utime, vki_u32 *, uaddr2); } @@ -1769,18 +1769,18 @@ static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout, case VKI_FUTEX_WAIT: case VKI_FUTEX_LOCK_PI: if (is_time64) { - PRE_REG_READ4(long, "futex_time64", + PRE_REG_READ4(long, "futex_time64", vki_u32 *, futex, int, op, int, val, struct timespec64 *, utime); } else { - PRE_REG_READ4(long, "futex", + PRE_REG_READ4(long, "futex", vki_u32 *, futex, int, op, int, val, struct timespec *, utime); } break; case VKI_FUTEX_WAKE: case VKI_FUTEX_FD: - PRE_REG_READ3(long, "futex", + PRE_REG_READ3(long, "futex", vki_u32 *, futex, int, op, int, val); break; case VKI_FUTEX_TRYLOCK_PI: @@ -1889,7 +1889,7 @@ PRE(sys_set_robust_list) { PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); - PRE_REG_READ2(long, "set_robust_list", + PRE_REG_READ2(long, "set_robust_list", struct vki_robust_list_head *, head, vki_size_t, len); /* Just check the robust_list_head structure is readable - don't @@ -1945,13 +1945,13 @@ static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout, } // XXX: this possibly understates how much memory is read. if (ARG2 != 0) - PRE_MEM_READ( "pselect6(readfds)", + PRE_MEM_READ( "pselect6(readfds)", ARG2, ARG1/8 /* __FD_SETSIZE/8 */ ); if (ARG3 != 0) - PRE_MEM_READ( "pselect6(writefds)", + PRE_MEM_READ( "pselect6(writefds)", ARG3, ARG1/8 /* __FD_SETSIZE/8 */ ); if (ARG4 != 0) - PRE_MEM_READ( "pselect6(exceptfds)", + PRE_MEM_READ( "pselect6(exceptfds)", ARG4, ARG1/8 /* __FD_SETSIZE/8 */ ); if (ARG5 != 0) { if (is_time64) { @@ -2485,7 +2485,7 @@ PRE(sys_tkill) SET_STATUS_Failure( VKI_EINVAL ); return; } - + /* Check to see if this kill gave us a pending signal */ *flags |= SfPollAfter; @@ -2526,7 +2526,7 @@ PRE(sys_tgkill) SET_STATUS_Failure( VKI_EINVAL ); return; } - + /* Check to see if this kill gave us a pending signal */ *flags |= SfPollAfter; @@ -2607,7 +2607,7 @@ POST(sys_io_setup) { SizeT size; struct vki_aio_ring *r; - + size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) + ARG1*sizeof(struct vki_io_event)); r = *(struct vki_aio_ring **)(Addr)ARG2; @@ -2631,7 +2631,7 @@ POST(sys_io_setup) PRE(sys_io_destroy) { SizeT size = 0; - + PRINT("sys_io_destroy ( %llu )", (ULong)ARG1); PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx); @@ -2639,35 +2639,35 @@ PRE(sys_io_destroy) // possible... if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) { struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1; - size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) + + size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) + r->nr*sizeof(struct vki_io_event)); } SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) ); - if (SUCCESS && RES == 0) { + if (SUCCESS && RES == 0) { Bool d = VG_(am_notify_munmap)( ARG1, size ); VG_TRACK( die_mem_munmap, ARG1, size ); if (d) - VG_(discard_translations)( (Addr)ARG1, (ULong)size, + VG_(discard_translations)( (Addr)ARG1, (ULong)size, "PRE(sys_io_destroy)" ); - } -} + } +} static -void common_pre_io_getevents(ThreadId tid, UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, UWord a6, UWord* flags, const HChar* funtion_name) +void common_pre_io_getevents(ThreadId tid, UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, UWord a6, UWord* flags, const HChar* function_name) { HChar buf[25]; *flags |= SfMayBlock; PRINT("sys_%s ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#" - FMT_REGWORD "x )", funtion_name, + FMT_REGWORD "x )", function_name, (ULong)a1,(Long)a2,(Long)a3,a4,a5); if (a3 > 0) { - VG_(snprintf)(buf, 25, "%s(events)", funtion_name); + VG_(snprintf)(buf, 25, "%s(events)", function_name); PRE_MEM_WRITE( buf, a4, sizeof(struct vki_io_event)*a3 ); } if (a5 != 0) { - VG_(snprintf)(buf, 25, "%s(timeout)", funtion_name); + VG_(snprintf)(buf, 25, "%s(timeout)", function_name); PRE_MEM_READ( buf, a5, sizeof(struct vki_timespec)); } @@ -2688,7 +2688,7 @@ PRE(sys_io_getevents) } static -void common_post_sys_io_events(ThreadId tid, UWord a4, SyscallStatus* status, const HChar* funtion_name) +void common_post_sys_io_events(ThreadId tid, UWord a4, SyscallStatus* status, const HChar* function_name) { Int i; vg_assert(SUCCESS); @@ -2736,7 +2736,7 @@ void common_post_sys_io_events(ThreadId tid, UWord a4, SyscallStatus* status, co default: VG_(message)(Vg_DebugMsg, "Warning: unhandled %s opcode: %u\n", - funtion_name, + function_name, cb->aio_lio_opcode); break; } @@ -2904,16 +2904,16 @@ PRE(sys_fanotify_mark) PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#" FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6, (HChar *)(Addr)ARG6); - PRE_REG_READ6(long, "sys_fanotify_mark", + PRE_REG_READ6(long, "sys_fanotify_mark", int, fanotify_fd, unsigned int, flags, __vki_u32, mask0, __vki_u32, mask1, int, dfd, const char *, pathname); if (ARG6) PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6); #elif VG_WORDSIZE == 8 - PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))", + PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))", SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5); - PRE_REG_READ5(long, "sys_fanotify_mark", + PRE_REG_READ5(long, "sys_fanotify_mark", int, fanotify_fd, unsigned int, flags, __vki_u64, mask, int, dfd, const char *, pathname); @@ -3148,7 +3148,7 @@ PRE(sys_mq_getsetattr) if (ARG3 != 0) PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3, sizeof(struct vki_mq_attr) ); - } + } } POST(sys_mq_getsetattr) { @@ -3163,7 +3163,7 @@ POST(sys_mq_getsetattr) PRE(sys_clock_settime) { PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2); - PRE_REG_READ2(long, "clock_settime", + PRE_REG_READ2(long, "clock_settime", vki_clockid_t, clk_id, const struct timespec *, tp); PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) ); } @@ -3179,7 +3179,7 @@ PRE(sys_clock_settime64) PRE(sys_clock_gettime) { PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2); - PRE_REG_READ2(long, "clock_gettime", + PRE_REG_READ2(long, "clock_gettime", vki_clockid_t, clk_id, struct timespec *, tp); PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) ); } @@ -3206,7 +3206,7 @@ PRE(sys_clock_getres) PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2); // Nb: we can't use "RES" as the param name because that's a macro // defined above! - PRE_REG_READ2(long, "clock_getres", + PRE_REG_READ2(long, "clock_getres", vki_clockid_t, clk_id, struct timespec *, res); if (ARG2 != 0) PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) ); @@ -3309,7 +3309,7 @@ PRE(sys_timer_settime) { PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4); - PRE_REG_READ4(long, "timer_settime", + PRE_REG_READ4(long, "timer_settime", vki_timer_t, timerid, int, flags, const struct itimerspec *, value, struct itimerspec *, ovalue); @@ -3329,7 +3329,7 @@ PRE(sys_timer_settime64) { PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4); - PRE_REG_READ4(long, "timer_settime64", + PRE_REG_READ4(long, "timer_settime64", vki_timer_t, timerid, int, flags, const struct vki_itimerspec64 *, value, struct vki_itimerspec64 *, ovalue); @@ -3348,7 +3348,7 @@ POST(sys_timer_settime64) PRE(sys_timer_gettime) { PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2); - PRE_REG_READ2(long, "timer_gettime", + PRE_REG_READ2(long, "timer_gettime", vki_timer_t, timerid, struct itimerspec *, value); PRE_MEM_WRITE( "timer_gettime(value)", ARG2, sizeof(struct vki_itimerspec)); @@ -3361,7 +3361,7 @@ POST(sys_timer_gettime) PRE(sys_timer_gettime64) { PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2); - PRE_REG_READ2(long, "timer_gettime64", + PRE_REG_READ2(long, "timer_gettime64", vki_timer_t, timerid, struct vki_itimerspec64 *, value); PRE_MEM_WRITE( "timer_gettime64(value)", ARG2, sizeof(struct vki_itimerspec64)); @@ -3559,12 +3559,12 @@ POST(sys_timerfd_settime64) PRE(sys_capget) { PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 ); - PRE_REG_READ2(long, "capget", + PRE_REG_READ2(long, "capget", vki_cap_user_header_t, header, vki_cap_user_data_t, data); - PRE_MEM_READ( "capget(header)", ARG1, + PRE_MEM_READ( "capget(header)", ARG1, sizeof(struct __vki_user_cap_header_struct) ); if (ARG2 != (Addr)NULL) - PRE_MEM_WRITE( "capget(data)", ARG2, + PRE_MEM_WRITE( "capget(data)", ARG2, sizeof(struct __vki_user_cap_data_struct) ); } POST(sys_capget) @@ -3576,12 +3576,12 @@ POST(sys_capget) PRE(sys_capset) { PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 ); - PRE_REG_READ2(long, "capset", + PRE_REG_READ2(long, "capset", vki_cap_user_header_t, header, const vki_cap_user_data_t, data); - PRE_MEM_READ( "capset(header)", + PRE_MEM_READ( "capset(header)", ARG1, sizeof(struct __vki_user_cap_header_struct) ); - PRE_MEM_READ( "capset(data)", + PRE_MEM_READ( "capset(data)", ARG2, sizeof(struct __vki_user_cap_data_struct) ); } @@ -3874,7 +3874,7 @@ PRE(sys_fremovexattr) PRE(sys_sched_setparam) { PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 ); - PRE_REG_READ2(long, "sched_setparam", + PRE_REG_READ2(long, "sched_setparam", vki_pid_t, pid, struct sched_param *, p); PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) ); } @@ -3886,7 +3886,7 @@ POST(sys_sched_setparam) PRE(sys_sched_getparam) { PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 ); - PRE_REG_READ2(long, "sched_getparam", + PRE_REG_READ2(long, "sched_getparam", vki_pid_t, pid, struct sched_param *, p); PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) ); } @@ -3940,10 +3940,10 @@ PRE(sys_sched_setscheduler) { PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3); - PRE_REG_READ3(long, "sched_setscheduler", + PRE_REG_READ3(long, "sched_setscheduler", vki_pid_t, pid, int, policy, struct sched_param *, p); if (ARG3 != 0) - PRE_MEM_READ( "sched_setscheduler(p)", + PRE_MEM_READ( "sched_setscheduler(p)", ARG3, sizeof(struct vki_sched_param)); } @@ -4001,7 +4001,7 @@ PRE(sys_sched_setaffinity) { PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3); - PRE_REG_READ3(long, "sched_setaffinity", + PRE_REG_READ3(long, "sched_setaffinity", vki_pid_t, pid, unsigned int, len, unsigned long *, mask); PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2); } @@ -4010,7 +4010,7 @@ PRE(sys_sched_getaffinity) { PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3); - PRE_REG_READ3(long, "sched_getaffinity", + PRE_REG_READ3(long, "sched_getaffinity", vki_pid_t, pid, unsigned int, len, unsigned long *, mask); PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2); } @@ -4125,14 +4125,124 @@ POST(sys_dup3) ML_(record_fd_open_named)(tid, RES); } +static +void common_pre_quotactl_p4_check(ThreadId tid, Int subop, Int a4, SyscallStatus* status, const HChar* function_name) +{ + HChar buf[25]; + VG_(snprintf)(buf, sizeof(buf), "%s(addr)", function_name); + switch (subop) { + case VKI_Q_QUOTAON: + // The addr argument points to the pathname of a file + // containing the quotas for the filesystem. + PRE_MEM_RASCIIZ( buf, a4 ); + break; + case VKI_Q_QUOTAOFF: + // The addr and id arguments are ignored. + break; + case VKI_Q_GETQUOTA: + // Get disk quota limits and current usage for user or group id. The + // addr argument is a pointer to a dqblk structure defined in + // as follows: + if (a4 != 0) + PRE_MEM_WRITE(buf, a4, sizeof(struct vki_dqblk)); + break; + case VKI_Q_GETNEXTQUOTA: + // The addr argument is a pointer to a nextdqblk structure + // whose fields are as for the dqblk, except for the addition + // of a dqb_id field that is used to return the ID for which + // quota information is being returned: + if (a4 != 0) + PRE_MEM_WRITE(buf, a4, sizeof(struct vki_nextdqblk)); + break; + case VKI_Q_SETQUOTA: + // Set quota information for user or group id, using the + // information supplied in the dqblk structure pointed to by + // addr. + if (a4 != 0) + PRE_MEM_READ(buf, a4, sizeof(struct vki_dqblk)); + break; + case VKI_Q_GETINFO: + // The addr argument should be a pointer to a dqinfo structure. + if (a4 != 0) + PRE_MEM_WRITE(buf, a4, sizeof(struct vki_dqinfo)); + break; + case VKI_Q_SETINFO: + // The addr argument should be a pointer to a dqinfo structure + if (a4 != 0) + PRE_MEM_READ(buf, a4, sizeof(struct vki_dqinfo)); + break; + case VKI_Q_GETFMT: + // The addr argument should be a pointer to a 4-byte buffer where the + // format number will be stored. + if (a4 != 0) + PRE_MEM_WRITE(buf, a4, 4); + break; + case VKI_Q_SYNC: + // The addr and id arguments are ignored. + break; + // case VKI_Q_GETSTATS: was only supported up to Linux 2.4.21 - skipping) + default: + return; + } +} + +static +void common_post_quotactl_p4_check(ThreadId tid, Int subop, Int a4, const HChar* function_name) +{ + switch (subop) { + case VKI_Q_GETQUOTA: + // Get disk quota limits and current usage for user or group id. The + // addr argument is a pointer to a dqblk structure defined in + // as follows: + if (a4 != 0) + POST_MEM_WRITE(a4, sizeof(struct vki_dqblk)); + break; + case VKI_Q_GETNEXTQUOTA: + // The addr argument is a pointer to a nextdqblk structure + // whose fields are as for the dqblk, except for the addition + // of a dqb_id field that is used to return the ID for which + // quota information is being returned: + if (a4 != 0) + POST_MEM_WRITE(a4, sizeof(struct vki_nextdqblk)); + break; + case VKI_Q_GETINFO: + // The addr argument should be a pointer to a dqinfo structure. + if (a4 != 0) + POST_MEM_WRITE(a4, sizeof(struct vki_dqinfo)); + break; + case VKI_Q_GETFMT: + // The addr argument should be a pointer to a 4-byte buffer where the + // format number will be stored. + if (a4 != 0) + POST_MEM_WRITE(a4, 4); + break; + // case VKI_Q_GETSTATS: was only supported up to Linux 2.4.21 - skipping) + default: + return; + } +} + + PRE(sys_quotactl) { + // SYSCALL_DEFINE4(quotactl, + // unsigned int, cmd, + // const char __user *, special, + // qid_t, id, + // void __user *, addr) + Int subop = ARG1 >> VKI_SUBCMDSHIFT; PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4); PRE_REG_READ4(long, "quotactl", unsigned int, cmd, const char *, special, vki_qid_t, id, void *, addr); PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 ); + common_pre_quotactl_p4_check(tid, subop, ARG4, status, "quotactl"); +} +POST(sys_quotactl) +{ + Int subop = ARG1 >> VKI_SUBCMDSHIFT; + common_post_quotactl_p4_check(tid, subop, ARG4, "quotactl"); } PRE(sys_quotactl_fd) @@ -4142,13 +4252,20 @@ PRE(sys_quotactl_fd) // unsigned int, cmd, // qid_t, id, // void __user *, addr) - PRINT("sys_quotactl (0x%" FMT_REGWORD "x, 0x%#" FMT_REGWORD "x, 0x%" + Int subop = ARG2 >> VKI_SUBCMDSHIFT; + PRINT("sys_quotactl_fd (0x%" FMT_REGWORD "x, 0x%#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4); PRE_REG_READ4(long, "quotactl_fd", unsigned int, fd, unsigned int, cmd, vki_qid_t, id, void *, addr); if (!ML_(fd_allowed)(ARG1, "quotactl_fd", tid, False)) SET_STATUS_Failure( VKI_EBADF ); + common_pre_quotactl_p4_check(tid, subop, ARG4, status, "quotactl_fd"); +} +POST(sys_quotactl_fd) +{ + Int subop = ARG2 >> VKI_SUBCMDSHIFT; + common_post_quotactl_p4_check(tid, subop, ARG4, "quotactl_fd"); } PRE(sys_waitid) @@ -4268,7 +4385,7 @@ PRE(sys_getcpu) { PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )" , ARG1, ARG2, ARG3); - PRE_REG_READ3(int, "getcpu", + PRE_REG_READ3(int, "getcpu", unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache); if (ARG1 != 0) PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) ); @@ -4482,6 +4599,105 @@ POST(sys_listmount) } } +PRE(sys_file_getattr) +{ + // SYSCALL_DEFINE5(file_getattr, int, dfd, const char __user *, filename, + // struct file_attr __user *, ufattr, size_t, usize, + // unsigned int, at_flags) + // in: dfd, filename, at_flags + // out: ufattr, usize + *flags |= SfMayBlock; + PRINT("sys_file_getattr ( %ld, %#" FMT_REGWORD "x(%s), %#" + FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )" , + SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, ARG5); + PRE_REG_READ5(int, "file_getattr", int, dfd, const char*, filename, + struct vki_file_attr *, ufattr, vki_size_t, usize, int, at_flags); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "file_getattr", tid, status); + PRE_MEM_WRITE("file_getattr(ufattr)", ARG3, ARG4); +} + +POST(sys_file_getattr) +{ + POST_MEM_WRITE(ARG3, ARG4); +} + +PRE(sys_file_setattr) +{ + // SYSCALL_DEFINE5(file_setattr, int, dfd, const char __user *, filename, + // struct file_attr __user *, ufattr, size_t, usize, + // unsigned int, at_flags) + // in: dfd, filename, ufattr, usize, at_flags + *flags |= SfMayBlock; + PRINT("sys_file_setattr ( %ld, %#" FMT_REGWORD "x(%s), %#" + FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )" , + SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, ARG5); + PRE_REG_READ5(int, "file_setattr", int, dfd, const char*, filename, + struct vki_file_attr *, ufattr, vki_size_t, usize, int, at_flags); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "sys_file_setattr", tid, status); + PRE_MEM_READ("file_setattr(ufattr)", ARG3, ARG4); +} + +PRE(sys_lsm_get_self_attr) +{ + // * sys_lsm_get_self_attr - Return current task's security module attributes + // * @attr: which attribute to return + // * @ctx: the user-space destination for the information, or NULL + // * @size: pointer to the size of space available to receive the data + // * @flags: special handling options. LSM_FLAG_SINGLE indicates that only + // * attributes associated with the LSM identified in the passed @ctx be + // * reported. + // SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *, + // ctx, u32 __user *, size, u32, flags) + PRINT("sys_lsm_get_self_attr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "lsm_get_self_attr", unsigned int, attr, struct vki_lsm_ctx *, ctx, __vki_u32 *, size, __vki_u32, flags); + if (ML_(safe_to_deref)((__vki_u32 *)ARG3,sizeof(__vki_u32))) { + PRE_MEM_READ("lsm_get_self_attr(size)", ARG3, sizeof(__vki_u32)); + PRE_MEM_READ("lsm_get_self_attr(ctx)", ARG2, *(__vki_u32 *)ARG3); + } +} + +POST(sys_lsm_get_self_attr) +{ + POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u32)); + POST_MEM_WRITE(ARG2, *(__vki_u32 *)ARG3); +} + +PRE(sys_lsm_set_self_attr) +{ + // * sys_lsm_set_self_attr - Set current task's security module attribute + // * @attr: which attribute to set + // * @ctx: the LSM contexts + // * @size: size of @ctx + // * @flags: reserved for future use + // SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, + // ctx, u32, size, u32, flags) + PRINT("sys_lsm_get_self_attr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "lsm_set_self_attr", unsigned int, attr, struct vki_lsm_ctx *, ctx, __vki_u32 *, size, __vki_u32, flags); + PRE_MEM_READ("lsm_get_self_attr(ctx)", ARG2, ARG3); +} + +PRE(sys_lsm_list_modules) +{ + // * sys_lsm_list_modules - Return a list of the active security modules + // * @ids: the LSM module ids + // * @size: pointer to size of @ids, updated on return + // * @flags: reserved for future use, must be zero + // SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, u32 __user *, size, + // u32, flags) + PRINT("sys_lsm_list_modules ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3); + PRE_REG_READ3(long, "lsm_list_modules", __vki_u64 *, ids, __vki_u32 *, size, __vki_u32, flags); + PRE_MEM_READ("lsm_list_modules(size)", ARG2, sizeof(__vki_u32)); + if (ML_(safe_to_deref)((__vki_u32 *)ARG2,sizeof(__vki_u32))) + PRE_MEM_READ("lsm_list_modules(ids)", ARG1, *(__vki_u32 *)ARG2); +} + +POST(sys_lsm_list_modules) +{ + // No need to POST_MEM_WRITE((Addr)ARG2, sizeof(__vki_u32)); + // per https://bugs.kde.org/show_bug.cgi?id=513257#c4 + POST_MEM_WRITE(ARG1, *(__vki_u32 *)ARG2); +} + PRE(sys_syncfs) { *flags |= SfMayBlock; @@ -4635,7 +4851,7 @@ PRE(sys_sigprocmask) vki_sigset_t bigger_oldset; PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); - PRE_REG_READ3(long, "sigprocmask", + PRE_REG_READ3(long, "sigprocmask", int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset); if (ARG2 != 0) PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t)); @@ -4653,7 +4869,7 @@ PRE(sys_sigprocmask) bigger_set.sig[0] = *(vki_old_sigset_t*)set; SET_STATUS_from_SysRes( - VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, + VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, set ? &bigger_set : NULL, oldset ? &bigger_oldset : NULL) ); @@ -4672,7 +4888,7 @@ POST(sys_sigprocmask) } /* Convert from non-RT to RT sigset_t's */ -static +static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set) { VG_(sigemptyset)(set); @@ -4870,7 +5086,7 @@ PRE(sys_rt_sigprocmask) { PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4); - PRE_REG_READ4(long, "rt_sigprocmask", + PRE_REG_READ4(long, "rt_sigprocmask", int, how, vki_sigset_t *, set, vki_sigset_t *, oldset, vki_size_t, sigsetsize); if (ARG2 != 0) @@ -4901,8 +5117,8 @@ PRE(sys_rt_sigprocmask) } else { - SET_STATUS_from_SysRes( - VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, + SET_STATUS_from_SysRes( + VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, (vki_sigset_t*) (Addr)ARG2, (vki_sigset_t*) (Addr)ARG3 ) ); @@ -4921,7 +5137,7 @@ POST(sys_rt_sigprocmask) PRE(sys_rt_sigpending) { PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 ); - PRE_REG_READ2(long, "rt_sigpending", + PRE_REG_READ2(long, "rt_sigpending", vki_sigset_t *, set, vki_size_t, sigsetsize); PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t)); } @@ -4936,10 +5152,10 @@ PRE(sys_rt_sigtimedwait) PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); - PRE_REG_READ4(long, "rt_sigtimedwait", + PRE_REG_READ4(long, "rt_sigtimedwait", const vki_sigset_t *, set, vki_siginfo_t *, info, const struct timespec *, timeout, vki_size_t, sigsetsize); - if (ARG1 != 0) + if (ARG1 != 0) PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t)); if (ARG2 != 0) PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) ); @@ -4959,11 +5175,11 @@ PRE(sys_rt_sigtimedwait_time64) PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); - PRE_REG_READ4(long, "rt_sigtimedwait_time64", + PRE_REG_READ4(long, "rt_sigtimedwait_time64", const vki_sigset_t *, set, vki_siginfo_t *, info, const struct vki_timespec64 *, timeout, vki_size_t, sigsetsize); - if (ARG1 != 0) + if (ARG1 != 0) PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) ); if (ARG2 != 0) PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2, @@ -4981,7 +5197,7 @@ PRE(sys_rt_sigqueueinfo) { PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)", SARG1, SARG2, ARG3); - PRE_REG_READ3(long, "rt_sigqueueinfo", + PRE_REG_READ3(long, "rt_sigqueueinfo", int, pid, int, sig, vki_siginfo_t *, uinfo); if (ARG2 != 0) PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE ); @@ -5221,10 +5437,10 @@ PRE(sys_ipc) void *, ptr); Addr msgp; Word msgtyp; - + msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp), "msgrcv(msgp)" ); - msgtyp = deref_Addr( tid, + msgtyp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp), "msgrcv(msgp)" ); @@ -5615,12 +5831,12 @@ PRE(sys_socketcall) break; case VKI_SYS_BIND: - /* int bind(int sockfd, struct sockaddr *my_addr, + /* int bind(int sockfd, struct sockaddr *my_addr, int addrlen); */ PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) ); ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 ); break; - + case VKI_SYS_LISTEN: /* int listen(int s, int backlog); */ PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) ); @@ -5639,11 +5855,11 @@ PRE(sys_socketcall) break; case VKI_SYS_SENDTO: - /* int sendto(int s, const void *msg, int len, - unsigned int flags, + /* int sendto(int s, const void *msg, int len, + unsigned int flags, const struct sockaddr *to, int tolen); */ PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) ); - ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2, + ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4, ARG2_5 ); break; @@ -5657,10 +5873,10 @@ PRE(sys_socketcall) /* int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); */ PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) ); - ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2, + ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4, ARG2_5 ); break; - + case VKI_SYS_RECV: /* int recv(int s, void *buf, int len, unsigned int flags); */ /* man 2 recv says: @@ -5673,25 +5889,25 @@ PRE(sys_socketcall) break; case VKI_SYS_CONNECT: - /* int connect(int sockfd, + /* int connect(int sockfd, struct sockaddr *serv_addr, int addrlen ); */ PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) ); ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 ); break; case VKI_SYS_SETSOCKOPT: - /* int setsockopt(int s, int level, int optname, + /* int setsockopt(int s, int level, int optname, const void *optval, int optlen); */ PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) ); - ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, + ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKOPT: - /* int getsockopt(int s, int level, int optname, + /* int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); */ PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) ); - ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, + ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 ); break; @@ -5718,7 +5934,7 @@ PRE(sys_socketcall) ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)(Addr)ARG2_1 ); break; - + case VKI_SYS_RECVMSG: /* int recvmsg(int s, struct msghdr *msg, int flags); */ PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) ); @@ -5767,9 +5983,9 @@ POST(sys_socketcall) switch (ARG1 /* request */) { case VKI_SYS_SOCKETPAIR: - r = ML_(generic_POST_sys_socketpair)( - tid, VG_(mk_SysRes_Success)(RES), - ARG2_0, ARG2_1, ARG2_2, ARG2_3 + r = ML_(generic_POST_sys_socketpair)( + tid, VG_(mk_SysRes_Success)(RES), + ARG2_0, ARG2_1, ARG2_2, ARG2_3 ); SET_STATUS_from_SysRes(r); break; @@ -5780,10 +5996,10 @@ POST(sys_socketcall) break; case VKI_SYS_BIND: - /* int bind(int sockfd, struct sockaddr *my_addr, + /* int bind(int sockfd, struct sockaddr *my_addr, int addrlen); */ break; - + case VKI_SYS_LISTEN: /* int listen(int s, int backlog); */ break; @@ -5792,7 +6008,7 @@ POST(sys_socketcall) case VKI_SYS_ACCEPT4: /* int accept(int s, struct sockaddr *addr, int *addrlen); */ /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */ - r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES), + r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES), ARG2_0, ARG2_1, ARG2_2 ); SET_STATUS_from_SysRes(r); break; @@ -5821,7 +6037,7 @@ POST(sys_socketcall) case VKI_SYS_GETSOCKOPT: ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), - ARG2_0, ARG2_1, + ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 ); break; @@ -5831,7 +6047,7 @@ POST(sys_socketcall) break; case VKI_SYS_GETPEERNAME: - ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES), + ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES), ARG2_0, ARG2_1, ARG2_2 ); break; @@ -5959,7 +6175,7 @@ PRE(sys_send) PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4); PRE_REG_READ4(long, "send", - int, s, const void *, msg, vki_size_t, len, + int, s, const void *, msg, vki_size_t, len, int, flags); ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 ); @@ -5972,13 +6188,13 @@ PRE(sys_sendto) FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, ARG3, ARG4, ARG5, SARG6); PRE_REG_READ6(long, "sendto", - int, s, const void *, msg, vki_size_t, len, - unsigned int, flags, + int, s, const void *, msg, vki_size_t, len, + unsigned int, flags, const struct sockaddr *, to, int, tolen); ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); } -PRE (sys_recv) +PRE (sys_recv) { *flags |= SfMayBlock; PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" @@ -5986,12 +6202,12 @@ PRE (sys_recv) PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len, unsigned int, flags); ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3); -} +} -POST (sys_recv) +POST (sys_recv) { ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3); -} +} PRE(sys_recvfrom) { @@ -6204,7 +6420,7 @@ PRE(sys_openat) VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 + && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) { sres = VG_(dup)( VG_(cl_cmdline_fd) ); SET_STATUS_from_SysRes( sres ); @@ -6220,7 +6436,7 @@ PRE(sys_openat) VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)()); if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 + && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) { sres = VG_(dup)( VG_(cl_auxv_fd) ); SET_STATUS_from_SysRes( sres ); @@ -6415,22 +6631,6 @@ PRE(sys_renameat) PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 ); } -PRE(sys_renameat2) -{ - FUSE_COMPATIBLE_MAY_BLOCK(); - PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD - "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, - ARG4, (HChar*)(Addr)ARG4, ARG5); - PRE_REG_READ5(long, "renameat2", - int, olddfd, const char *, oldpath, - int, newdfd, const char *, newpath, - unsigned int, flags); - ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "renameat2(olddirfd)", tid, status); - ML_(fd_at_check_allowed)(SARG3, (const HChar*)ARG4, "renameat2(newdirfd)", tid, status); - PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 ); - PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 ); -} - PRE(sys_linkat) { *flags |= SfMayBlock; @@ -6468,14 +6668,10 @@ PRE(sys_readlinkat) ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "readlinkat", tid, status); PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 ); -} -POST(sys_readlinkat) -{ + Bool fuse_may_block = True; HChar name[30]; // large enough - Word saved = SYSNO; - // @todo PJF why is this done in POST and not in PRE? /* * Handle the case where readlinkat is looking at /proc/self/exe or * /proc//exe. @@ -6484,13 +6680,25 @@ POST(sys_readlinkat) if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1) && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { - VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd)); - SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name, - ARG3, ARG4)); + HChar* out_name = (HChar*)ARG3; + SizeT res = VG_(strlen)(VG_(resolved_exename)); + res = VG_MIN(res, ARG4); + if (ML_(safe_to_deref)(out_name, res)) { + VG_(strncpy)(out_name, VG_(resolved_exename), res); + SET_STATUS_Success(res); + } else { + SET_STATUS_Failure(VKI_EFAULT); + } + fuse_may_block = False; } - if (SUCCESS && RES > 0) - POST_MEM_WRITE( ARG3, RES ); + if (fuse_may_block) + FUSE_COMPATIBLE_MAY_BLOCK(); +} + +POST(sys_readlinkat) +{ + POST_MEM_WRITE( ARG3, RES ); } PRE(sys_fchmodat) @@ -6978,7 +7186,7 @@ PRE(sys_request_key) FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4); PRE_REG_READ4(long, "request_key", - const char *, type, const char *, description, + const char *, type, const char *, description, const char *, callout_info, vki_key_serial_t, keyring); PRE_MEM_RASCIIZ( "request_key(type)", ARG1); PRE_MEM_RASCIIZ( "request_key(description)", ARG2); @@ -6993,7 +7201,7 @@ PRE(sys_add_key) ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5); PRE_REG_READ5(long, "add_key", const char *, type, const char *, description, - const void *, payload, vki_size_t, plen, + const void *, payload, vki_size_t, plen, vki_key_serial_t, keyring); PRE_MEM_RASCIIZ( "add_key(type)", ARG1); PRE_MEM_RASCIIZ( "add_key(description)", ARG2); @@ -7073,7 +7281,7 @@ PRE(sys_keyctl) FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3, ARG4, (HChar*)(Addr)ARG4, SARG5); PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)", - int, option, vki_key_serial_t, keyring, + int, option, vki_key_serial_t, keyring, const char *, type, const char *, description, vki_key_serial_t, destring); PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3); @@ -7083,7 +7291,7 @@ PRE(sys_keyctl) PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG2, ARG3, ARG4); PRE_REG_READ4(long, "keyctl(KEYCTL_READ)", - int, option, vki_key_serial_t, keyring, + int, option, vki_key_serial_t, keyring, char *, buffer, vki_size_t, buflen); if (ARG3 != (UWord)NULL) PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4); @@ -7092,7 +7300,7 @@ PRE(sys_keyctl) PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5); PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)", - int, option, vki_key_serial_t, key, + int, option, vki_key_serial_t, key, char *, payload, vki_size_t, plen, vki_key_serial_t, keyring); if (ARG3 != (UWord)NULL) @@ -7102,7 +7310,7 @@ PRE(sys_keyctl) PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )", SARG2, ARG3, SARG4); PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)", - int, option, vki_key_serial_t, key, + int, option, vki_key_serial_t, key, unsigned, timeout, vki_key_serial_t, keyring); break; case VKI_KEYCTL_SET_REQKEY_KEYRING: @@ -7564,7 +7772,7 @@ PRE(sys_fcntl64) PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex)); break; } - + # if defined(VGP_x86_linux) if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64) # else @@ -7660,7 +7868,7 @@ PRE(sys_ioctl) /* SCSI no operand */ case VKI_SCSI_IOCTL_DOORLOCK: case VKI_SCSI_IOCTL_DOORUNLOCK: - + /* CDROM stuff. */ case VKI_CDROM_DISC_STATUS: case VKI_CDROMSTOP: @@ -7774,7 +7982,7 @@ PRE(sys_ioctl) case VKI_TCSETSW: case VKI_TCSETSF: PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) ); - break; + break; case VKI_TCGETS: PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) ); break; @@ -8126,7 +8334,7 @@ PRE(sys_ioctl) PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)", (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num, sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num)); - PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3, + PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3, sizeof(struct vki_ifreq)); break; case VKI_SIOCGIFCONF: /* get iface list */ @@ -8167,7 +8375,7 @@ PRE(sys_ioctl) case VKI_SIOCGARP: /* get ARP table entry */ PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq)); break; - + case VKI_SIOCSIFFLAGS: /* set flags */ PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)", (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name ); @@ -8243,7 +8451,7 @@ PRE(sys_ioctl) /* Routing table calls. */ case VKI_SIOCADDRT: /* add routing table entry */ case VKI_SIOCDELRT: /* delete routing table entry */ - PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3, + PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3, sizeof(struct vki_rtentry)); break; @@ -8333,7 +8541,7 @@ PRE(sys_ioctl) case VKI_SOUND_PCM_READ_CHANNELS: case VKI_SOUND_PCM_READ_BITS: case VKI_SOUND_PCM_READ_FILTER: - PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))", + PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))", ARG3, sizeof(int)); break; case VKI_SNDCTL_SEQ_CTRLRATE: @@ -8351,9 +8559,9 @@ PRE(sys_ioctl) case VKI_SNDCTL_TMR_SOURCE: case VKI_SNDCTL_MIDI_PRETIME: case VKI_SNDCTL_MIDI_MPUMODE: - PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))", + PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))", ARG3, sizeof(int)); - PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))", + PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))", ARG3, sizeof(int)); break; case VKI_SNDCTL_DSP_GETOSPACE: @@ -8364,7 +8572,7 @@ PRE(sys_ioctl) case VKI_SNDCTL_DSP_NONBLOCK: break; case VKI_SNDCTL_DSP_SETTRIGGER: - PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))", + PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))", ARG3, sizeof(int)); break; @@ -8426,7 +8634,7 @@ PRE(sys_ioctl) break; case VKI_RTC_RD_TIME: case VKI_RTC_ALM_READ: - PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)", + PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)", ARG3, sizeof(struct vki_rtc_time)); break; case VKI_RTC_ALM_SET: @@ -8556,7 +8764,7 @@ PRE(sys_ioctl) PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))", (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format), sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format)); - PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3, + PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3, sizeof(struct vki_cdrom_subchnl)); break; case VKI_CDROMREADMODE1: /*0x530d*/ @@ -8568,7 +8776,7 @@ PRE(sys_ioctl) PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0); break; case VKI_CDROMREADTOCHDR: - PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3, + PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3, sizeof(struct vki_cdrom_tochdr)); break; case VKI_CDROMREADTOCENTRY: @@ -8578,7 +8786,7 @@ PRE(sys_ioctl) PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))", (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track), sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track)); - PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3, + PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3, sizeof(struct vki_cdrom_tocentry)); break; case VKI_CDROMMULTISESSION: /* 0x5310 */ @@ -8603,7 +8811,7 @@ PRE(sys_ioctl) PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf", (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW); } - break; + break; case VKI_CDROMPLAYMSF: PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf)); break; @@ -8821,19 +9029,19 @@ PRE(sys_ioctl) break; case VKI_KDSKBMODE: break; - + case VKI_KDGKBMETA: PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) ); break; case VKI_KDSKBMETA: break; - + case VKI_KDGKBLED: PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) ); break; case VKI_KDSKBLED: break; - + case VKI_KDGKBENT: PRE_MEM_READ( "ioctl(KDGKBENT).kb_table", (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table, @@ -8856,7 +9064,7 @@ PRE(sys_ioctl) (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value, sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) ); break; - + case VKI_KDGKBSENT: PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func", (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func, @@ -8872,14 +9080,14 @@ PRE(sys_ioctl) PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string", (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string ); break; - + case VKI_KDGKBDIACR: PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) ); break; case VKI_KDSKBDIACR: PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) ); break; - + case VKI_KDGETKEYCODE: PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode", (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode, @@ -8896,7 +9104,7 @@ PRE(sys_ioctl) (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode, sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) ); break; - + case VKI_KDSIGACCEPT: break; @@ -9096,7 +9304,7 @@ PRE(sys_ioctl) for (i=0; i < vkui->nmsgs; i++) { struct vki_i2c_msg *msg = vkui->msgs + i; PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg)); - if (msg->flags & VKI_I2C_M_RD) + if (msg->flags & VKI_I2C_M_RD) PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len); else PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len); @@ -9344,7 +9552,7 @@ PRE(sys_ioctl) dlr->dev_num * sizeof(struct vki_hci_dev_req)); } break; - + case VKI_HCIINQUIRY: if (ARG3) { struct vki_hci_inquiry_req* ir = @@ -9577,7 +9785,7 @@ PRE(sys_ioctl) break; VG_(memset)(&harrghs, 0, sizeof(harrghs)); - harrghs.sysno = args->op; + harrghs.canonical_sysno = args->op; harrghs.arg1 = args->arg[0]; harrghs.arg2 = args->arg[1]; harrghs.arg3 = args->arg[2]; @@ -10826,6 +11034,26 @@ PRE(sys_ioctl) case VKI_EVIOCGRAB: /* This just takes an int argument. */ break; + case VKI_PROCMAP_QUERY: { + /* https://www.kernel.org/doc/html/latest/filesystems/proc.html */ + /* linux source: include/uapi/linux/fs.h:561 */ + struct vki_procmap_query *pq = + (struct vki_procmap_query *)(Addr)ARG3; + if (!ML_(safe_to_deref) (pq, sizeof(struct vki_procmap_query))) + break; + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).size", pq->size); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).query_flags", pq->query_flags); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).query_addr", pq->query_addr); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).vma_name_size", pq->vma_name_size); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).vma_name_addr", pq->vma_name_addr); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).build_id_size", pq->build_id_size); + PRE_FIELD_READ("ioctl(PROCMAP_QUERY).build_id_addr", pq->build_id_addr); + if (pq->vma_name_size > 0) + PRE_MEM_WRITE("ioctl(PROCMAP_QUERY)", (Addr)pq->vma_name_addr, pq->vma_name_size); + if (pq->build_id_size > 0) + PRE_MEM_WRITE("ioctl(PROCMAP_QUERY)", (Addr)pq->build_id_addr, pq->build_id_size); + break; + } default: /* EVIOC* are variable length and return size written on success */ @@ -10856,7 +11084,7 @@ PRE(sys_ioctl) break; } break; - } + } } POST(sys_ioctl) @@ -10894,7 +11122,7 @@ POST(sys_ioctl) at, it's possible to guess that the 7 word structure has this form - 0 1 2 3 4 5 6 + 0 1 2 3 4 5 6 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask Unfortunately that doesn't seem to work for some reason, @@ -10986,7 +11214,7 @@ POST(sys_ioctl) case VKI_TCSETSW: case VKI_TCSETSF: case VKI_IB_USER_MAD_ENABLE_PKEY: - break; + break; case VKI_TCGETS: POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) ); break; @@ -11091,7 +11319,7 @@ POST(sys_ioctl) break; case VKI_SG_GET_SG_TABLESIZE: POST_MEM_WRITE(ARG3, sizeof(int)); - break; + break; case VKI_IIOCGETCPS: POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) ); @@ -11288,7 +11516,7 @@ POST(sys_ioctl) case VKI_SIOCGARP: /* get ARP table entry */ POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq)); break; - + case VKI_SIOCSIFFLAGS: /* set flags */ case VKI_SIOCSIFMAP: /* Set device parameters */ case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */ @@ -11585,7 +11813,7 @@ POST(sys_ioctl) POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW); break; } - + case VKI_CDROMPLAYMSF: break; /* The following two are probably bogus (should check args @@ -11740,46 +11968,46 @@ POST(sys_ioctl) break; case VKI_KDSKBMODE: break; - + case VKI_KDGKBMETA: POST_MEM_WRITE( ARG3, sizeof(int) ); break; case VKI_KDSKBMETA: break; - + case VKI_KDGKBLED: POST_MEM_WRITE( ARG3, sizeof(char) ); break; case VKI_KDSKBLED: break; - + case VKI_KDGKBENT: POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value, sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) ); break; case VKI_KDSKBENT: break; - + case VKI_KDGKBSENT: POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string, sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) ); break; case VKI_KDSKBSENT: break; - + case VKI_KDGKBDIACR: POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) ); break; case VKI_KDSKBDIACR: break; - + case VKI_KDGETKEYCODE: POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode, sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) ); break; case VKI_KDSETKEYCODE: break; - + case VKI_KDSIGACCEPT: break; @@ -11899,7 +12127,7 @@ POST(sys_ioctl) dir2 = _VKI_IOC_DIR(vkui->ioctl_code); size2 = _VKI_IOC_SIZE(vkui->ioctl_code); if (size2 > 0) { - if (dir2 & _VKI_IOC_READ) + if (dir2 & _VKI_IOC_READ) POST_MEM_WRITE((Addr)vkui->data, size2); } } @@ -11921,7 +12149,7 @@ POST(sys_ioctl) UInt i; for (i=0; i < vkui->nmsgs; i++) { struct vki_i2c_msg *msg = vkui->msgs + i; - if (msg->flags & VKI_I2C_M_RD) + if (msg->flags & VKI_I2C_M_RD) POST_MEM_WRITE((Addr)msg->buf, msg->len); } } @@ -12316,7 +12544,7 @@ POST(sys_ioctl) break; VG_(memset)(&harrghs, 0, sizeof(harrghs)); - harrghs.sysno = args->op; + harrghs.canonical_sysno = args->op; harrghs.arg1 = args->arg[0]; harrghs.arg2 = args->arg[1]; harrghs.arg3 = args->arg[2]; @@ -12984,6 +13212,20 @@ POST(sys_ioctl) case VKI_PTP_ENABLE_PPS: case VKI_PTP_PIN_SETFUNC: break; + case VKI_PROCMAP_QUERY: { + /* https://www.kernel.org/doc/html/latest/filesystems/proc.html */ + /* linux source: include/uapi/linux/fs.h:561 */ + struct vki_procmap_query *pq = + (struct vki_procmap_query *)(Addr)ARG3; + if (pq->vma_name_size > 0) + POST_MEM_WRITE(pq->vma_name_addr, pq->vma_name_size); + if (pq->build_id_size > 0) + POST_MEM_WRITE(pq->build_id_addr, pq->build_id_size); + /* assume everything is written/defined with POST_MEM_WRITE */ + /* instead of doing individual POST_FIELD_WRITEs */ + POST_MEM_WRITE((Addr)pq, pq->size); + break; + } default: /* EVIOC* are variable length and return size written on success */ @@ -13025,12 +13267,12 @@ POST(sys_ioctl) socketcall wrapper helpers ------------------------------------------------------------------ */ -void -ML_(linux_PRE_sys_getsockopt) ( ThreadId tid, +void +ML_(linux_PRE_sys_getsockopt) ( ThreadId tid, UWord arg0, UWord arg1, UWord arg2, UWord arg3, UWord arg4 ) { - /* int getsockopt(int s, int level, int optname, + /* int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); */ Addr optval_p = arg3; Addr optlen_p = arg4; @@ -13040,7 +13282,7 @@ ML_(linux_PRE_sys_getsockopt) ( ThreadId tid, "socketcall.getsockopt(optval)", "socketcall.getsockopt(optlen)" ); if (arg1 == VKI_SOL_SCTP && - (arg2 == VKI_SCTP_GET_PEER_ADDRS || + (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; @@ -13051,7 +13293,7 @@ ML_(linux_PRE_sys_getsockopt) ( ThreadId tid, } } -void +void ML_(linux_POST_sys_getsockopt) ( ThreadId tid, SysRes res, UWord arg0, UWord arg1, UWord arg2, @@ -13067,7 +13309,7 @@ ML_(linux_POST_sys_getsockopt) ( ThreadId tid, (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { - struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; + struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; struct vki_sockaddr *a = ga->addrs; int i; for (i = 0; i < ga->addr_num; i++) { @@ -13082,17 +13324,17 @@ ML_(linux_POST_sys_getsockopt) ( ThreadId tid, } a = (struct vki_sockaddr*)((char*)a + sl); } - POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs ); + POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs ); } } } -void -ML_(linux_PRE_sys_setsockopt) ( ThreadId tid, +void +ML_(linux_PRE_sys_setsockopt) ( ThreadId tid, UWord arg0, UWord arg1, UWord arg2, UWord arg3, UWord arg4 ) { - /* int setsockopt(int s, int level, int optname, + /* int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); */ Addr optval_p = arg3; if (optval_p != (Addr)NULL) { @@ -13805,12 +14047,12 @@ PRE(sys_copy_file_range) ARG4, ARG5, ARG6); PRE_REG_READ6(vki_size_t, "copy_file_range", - int, "fd_in", - vki_loff_t *, "off_in", - int, "fd_out", - vki_loff_t *, "off_out", - vki_size_t, "len", - unsigned int, "flags"); + int, fd_in, + vki_loff_t *, off_in, + int, fd_out, + vki_loff_t *, off_out, + vki_size_t, len, + unsigned int, flags); /* File descriptors are "specially" tracked by valgrind. valgrind itself uses some, so make sure someone didn't @@ -13833,8 +14075,8 @@ PRE(sys_pkey_alloc) PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2); PRE_REG_READ2(long, "pkey_alloc", - unsigned long, "flags", - unsigned long, "access_rights"); + unsigned long, flags, + unsigned long, access_rights); /* The kernel says: pkey_alloc() is always safe to call regardless of whether or not the operating system supports protection keys. It can be @@ -13857,7 +14099,7 @@ PRE(sys_pkey_free) PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1); PRE_REG_READ1(long, "pkey_free", - unsigned long, "pkey"); + unsigned long, pkey); /* Since pkey_alloc () can never succeed, see above, freeing any pkey is always an error. */ @@ -14452,7 +14694,7 @@ PRE(sys_fsconfig) if (ARG3) PRE_MEM_RASCIIZ( "fsconfig(key)", ARG3); if (!ML_(fd_allowed)(ARG1, "fsconfig", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + SET_STATUS_Failure( VKI_EINVAL ); // Bug 518951 /* XXX we could also check the value based on the cmd FSCONFIG_... */ } diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index c7dbd6b92f..3342ff3b49 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -74,6 +74,7 @@ FreeBSD: x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c + arm64 x8 x0 x1 x2 x3 x4 x5 x6 x7 x0:x1, nzcv.c On s390x the svc instruction is used for system calls. The system call number is encoded in the instruction (8 bit immediate field). Since Linux @@ -302,18 +303,20 @@ UWord ML_(do_syscall_for_client_WRK)( Word syscallno, Word sigsetSzB ); #elif defined(VGO_freebsd) extern -UWord ML_(do_syscall_for_client_WRK)( Word syscallno, - void* guest_state, - const vki_sigset_t *syscall_mask, - const vki_sigset_t *restore_mask, - Word sigsetSzB ); +UWord ML_(do_syscall_for_client_WRK)(Word syscallno, + void* guest_state, + const vki_sigset_t *syscall_mask, + const vki_sigset_t *restore_mask, + Word sigsetSzB, + UChar *cflag); #elif defined(VGO_darwin) extern UWord ML_(do_syscall_for_client_unix_WRK)( Word syscallno, void* guest_state, const vki_sigset_t *syscall_mask, const vki_sigset_t *restore_mask, - Word sigsetSzB ); /* unused */ + Word sigsetSzB, /* unused */ + UChar* cflag ); extern UWord ML_(do_syscall_for_client_mach_WRK)( Word syscallno, void* guest_state, @@ -356,25 +359,41 @@ void do_syscall_for_client ( Int syscallno, syscall_mask, &saved, sizeof(vki_sigset_t) ); # elif defined(VGO_freebsd) - Word real_syscallno; + UChar cflag; VG_(sigemptyset)(&saved); - if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL0) - real_syscallno = __NR_syscall; - else if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL198) - real_syscallno = __NR___syscall; - else - real_syscallno = syscallno; err = ML_(do_syscall_for_client_WRK)( - real_syscallno, &tst->arch.vex, - syscall_mask, &saved, sizeof(vki_sigset_t) + syscallno, &tst->arch.vex, + syscall_mask, &saved, sizeof(vki_sigset_t), + &cflag ); + /* Save the carry flag. */ +# if defined(VGP_amd64_freebsd) + LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex); +# elif defined(VGP_arm64_freebsd) + LibVEX_GuestARM64_put_nzcv_c(cflag, &tst->arch.vex); +# elif defined(VGP_x86_freebsd) + LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex); +# else +# error "Unknown platform" +# endif # elif defined(VGO_darwin) + UChar cflag; switch (VG_DARWIN_SYSNO_CLASS(syscallno)) { case VG_DARWIN_SYSCALL_CLASS_UNIX: err = ML_(do_syscall_for_client_unix_WRK)( VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex, - syscall_mask, &saved, 0/*unused:sigsetSzB*/ + syscall_mask, &saved, 0/*unused:sigsetSzB*/, &cflag ); + /* Save the carry flag. */ +# if defined(VGP_amd64_darwin) + LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex); +# elif defined(VGP_arm64_darwin) + LibVEX_GuestARM64_put_nzcv_c(cflag, &tst->arch.vex); +# elif defined(VGP_x86_darwin) + LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex); +# else +# error "Unknown platform" +# endif break; case VG_DARWIN_SYSCALL_CLASS_MACH: err = ML_(do_syscall_for_client_mach_WRK)( @@ -440,7 +459,10 @@ void do_syscall_for_client ( Int syscallno, static Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 ) { - return a1->sysno == a2->sysno + return a1->canonical_sysno == a2->canonical_sysno +#if defined(VGO_freebsd) || defined(VGO_darwin) + && a1->original_sysno == a2->original_sysno +#endif && a1->arg1 == a2->arg1 && a1->arg2 == a2->arg2 && a1->arg3 == a2->arg3 @@ -491,7 +513,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, { #if defined(VGP_x86_linux) VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; - canonical->sysno = gst->guest_EAX; + canonical->canonical_sysno = gst->guest_EAX; canonical->arg1 = gst->guest_EBX; canonical->arg2 = gst->guest_ECX; canonical->arg3 = gst->guest_EDX; @@ -503,7 +525,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_amd64_linux) VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; - canonical->sysno = gst->guest_RAX; + canonical->canonical_sysno = gst->guest_RAX; canonical->arg1 = gst->guest_RDI; canonical->arg2 = gst->guest_RSI; canonical->arg3 = gst->guest_RDX; @@ -515,7 +537,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_ppc32_linux) VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; - canonical->sysno = gst->guest_GPR0; + canonical->canonical_sysno = gst->guest_GPR0; canonical->arg1 = gst->guest_GPR3; canonical->arg2 = gst->guest_GPR4; canonical->arg3 = gst->guest_GPR5; @@ -527,7 +549,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; - canonical->sysno = gst->guest_GPR0; + canonical->canonical_sysno = gst->guest_GPR0; canonical->arg1 = gst->guest_GPR3; canonical->arg2 = gst->guest_GPR4; canonical->arg3 = gst->guest_GPR5; @@ -550,20 +572,20 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, // FreeBSD supports different calling conventions switch (gst->guest_EAX) { case __NR_syscall: - canonical->klass = VG_FREEBSD_SYSCALL0; - canonical->sysno = stack[1]; + canonical->canonical_sysno = stack[1]; stack += 1; break; case __NR___syscall: - canonical->klass = VG_FREEBSD_SYSCALL198; - canonical->sysno = stack[1]; + canonical->canonical_sysno = stack[1]; stack += 2; break; default: - canonical->klass = 0; - canonical->sysno = gst->guest_EAX; + canonical->canonical_sysno = gst->guest_EAX; break; } + + canonical->original_sysno = gst->guest_EAX; + // stack[0] is a (fake) return address canonical->arg1 = stack[1]; canonical->arg2 = stack[2]; @@ -578,29 +600,22 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_RSP; - // FreeBSD supports different calling conventions - // @todo PJF this all seems over complicated to me - // SYSCALL_STD is OK but for the other - // two here we overwrite canonical->sysno with - // the final syscall number but then in do_syscall_for_client - // we switch real_syscallno back to __NR_syscall or __NR___syscall switch (gst->guest_RAX) { case __NR_syscall: - canonical->klass = VG_FREEBSD_SYSCALL0; - canonical->sysno = gst->guest_RDI; + canonical->canonical_sysno = gst->guest_RDI; break; case __NR___syscall: - canonical->klass = VG_FREEBSD_SYSCALL198; - canonical->sysno = gst->guest_RDI; + canonical->canonical_sysno = gst->guest_RDI; break; default: - canonical->klass = VG_FREEBSD_SYSCALL_STD; - canonical->sysno = gst->guest_RAX; + canonical->canonical_sysno = gst->guest_RAX; break; } + canonical->original_sysno = gst->guest_RAX; + // stack[0] is a (fake) return address - if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) { + if (gst->guest_RAX == __NR_syscall || gst->guest_RAX == __NR___syscall) { // stack[0] is return address canonical->arg1 = gst->guest_RSI; canonical->arg2 = gst->guest_RDX; @@ -626,19 +641,20 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; switch (gst->guest_X8) { case __NR_syscall: - canonical->klass = VG_FREEBSD_SYSCALL0; - canonical->sysno = gst->guest_X0; + canonical->canonical_sysno = gst->guest_X0; break; case __NR___syscall: - canonical->klass = VG_FREEBSD_SYSCALL198; - canonical->sysno = gst->guest_X0; + canonical->canonical_sysno = gst->guest_X0; break; default: - canonical->klass = 0; - canonical->sysno = gst->guest_X8; + canonical->canonical_sysno = gst->guest_X8; break; } - if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) { + + canonical->original_sysno = gst->guest_X8; + + if (gst->guest_X8 == __NR_syscall || + gst->guest_X8 == __NR___syscall) { canonical->arg1 = gst->guest_X1; canonical->arg2 = gst->guest_X2; canonical->arg3 = gst->guest_X3; @@ -658,7 +674,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_arm_linux) VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; - canonical->sysno = gst->guest_R7; + canonical->canonical_sysno = gst->guest_R7; canonical->arg1 = gst->guest_R0; canonical->arg2 = gst->guest_R1; canonical->arg3 = gst->guest_R2; @@ -670,7 +686,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_arm64_linux) VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; - canonical->sysno = gst->guest_X8; + canonical->canonical_sysno = gst->guest_X8; canonical->arg1 = gst->guest_X0; canonical->arg2 = gst->guest_X1; canonical->arg3 = gst->guest_X2; @@ -682,8 +698,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_mips32_linux) VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; - canonical->sysno = gst->guest_r2; // v0 - if (canonical->sysno == __NR_exit) { + canonical->canonical_sysno = gst->guest_r2; // v0 + if (canonical->canonical_sysno == __NR_exit) { canonical->arg1 = gst->guest_r4; // a0 canonical->arg2 = 0; canonical->arg3 = 0; @@ -691,7 +707,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, canonical->arg5 = 0; canonical->arg6 = 0; canonical->arg8 = 0; - } else if (canonical->sysno != __NR_syscall) { + } else if (canonical->canonical_sysno != __NR_syscall) { canonical->arg1 = gst->guest_r4; // a0 canonical->arg2 = gst->guest_r5; // a1 canonical->arg3 = gst->guest_r6; // a2 @@ -702,7 +718,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, canonical->arg8 = 0; } else { // Fixme hack handle syscall() - canonical->sysno = gst->guest_r4; // a0 + canonical->canonical_sysno = gst->guest_r4; // a0 canonical->arg1 = gst->guest_r5; // a1 canonical->arg2 = gst->guest_r6; // a2 canonical->arg3 = gst->guest_r7; // a3 @@ -715,7 +731,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_mips64_linux) VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; - canonical->sysno = gst->guest_r2; // v0 + canonical->canonical_sysno = gst->guest_r2; // v0 canonical->arg1 = gst->guest_r4; // a0 canonical->arg2 = gst->guest_r5; // a1 canonical->arg3 = gst->guest_r6; // a2 @@ -727,7 +743,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_nanomips_linux) VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; - canonical->sysno = gst->guest_r2; // t4 + canonical->canonical_sysno = gst->guest_r2; // t4 canonical->arg1 = gst->guest_r4; // a0 canonical->arg2 = gst->guest_r5; // a1 canonical->arg3 = gst->guest_r6; // a2 @@ -740,8 +756,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_ESP; // GrP fixme hope syscalls aren't called with really shallow stacks... - canonical->sysno = gst->guest_EAX; - if (canonical->sysno != 0) { + canonical->canonical_sysno = gst->guest_EAX; + if (canonical->canonical_sysno != 0) { // stack[0] is return address canonical->arg1 = stack[1]; canonical->arg2 = stack[2]; @@ -758,8 +774,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, // DDD: the tool can't see that the params have been shifted! Can // lead to incorrect checking, I think, because the PRRAn/PSARn // macros will mention the pre-shifted args. - canonical->sysno = stack[1]; - vg_assert(canonical->sysno != 0); + canonical->canonical_sysno = stack[1]; + vg_assert(canonical->canonical_sysno != 0); canonical->arg1 = stack[2]; canonical->arg2 = stack[3]; canonical->arg3 = stack[4]; @@ -771,9 +787,11 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n", VG_(getpid)(), /*tid,*/ - VG_SYSNUM_STRING(canonical->sysno)); + VG_SYSNUM_STRING(canonical->canonical_sysno)); } + canonical->original_sysno = gst->guest_EAX; + // Here we determine what kind of syscall it was by looking at the // interrupt kind, and then encode the syscall number using the 64-bit // encoding for Valgrind's internal use. @@ -783,29 +801,29 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, switch (trc) { case VEX_TRC_JMP_SYS_INT128: // int $0x80 = Unix, 64-bit result - vg_assert(canonical->sysno >= 0); - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno); + vg_assert(canonical->canonical_sysno >= 0); + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->canonical_sysno); break; case VEX_TRC_JMP_SYS_SYSENTER: // syscall = Unix, 32-bit result // OR Mach, 32-bit result - if (canonical->sysno >= 0) { + if (canonical->canonical_sysno >= 0) { // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->canonical_sysno & 0xffff); } else { - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno); + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->canonical_sysno); } break; case VEX_TRC_JMP_SYS_INT129: // int $0x81 = Mach, 32-bit result - vg_assert(canonical->sysno < 0); - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno); + vg_assert(canonical->canonical_sysno < 0); + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->canonical_sysno); break; case VEX_TRC_JMP_SYS_INT130: // int $0x82 = mdep, 32-bit result - vg_assert(canonical->sysno >= 0); - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->sysno); + vg_assert(canonical->canonical_sysno >= 0); + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->canonical_sysno); break; default: vg_assert(0); @@ -819,8 +837,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, vg_assert(trc == VEX_TRC_JMP_SYS_SYSCALL); // GrP fixme hope syscalls aren't called with really shallow stacks... - canonical->sysno = gst->guest_RAX; - if (canonical->sysno != __NR_syscall) { + canonical->canonical_sysno = gst->guest_RAX; + if (canonical->canonical_sysno != __NR_syscall) { // stack[0] is return address canonical->arg1 = gst->guest_RDI; canonical->arg2 = gst->guest_RSI; @@ -837,8 +855,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, // DDD: the tool can't see that the params have been shifted! Can // lead to incorrect checking, I think, because the PRRAn/PSARn // macros will mention the pre-shifted args. - canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI); - vg_assert(canonical->sysno != __NR_syscall); + canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI); + vg_assert(canonical->canonical_sysno != __NR_syscall); canonical->arg1 = gst->guest_RSI; canonical->arg2 = gst->guest_RDX; canonical->arg3 = gst->guest_R10; // not rcx with syscall insn @@ -850,14 +868,16 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n", VG_(getpid)(), /*tid,*/ - VG_SYSNUM_STRING(canonical->sysno)); + VG_SYSNUM_STRING(canonical->canonical_sysno)); } - // no canonical->sysno adjustment needed + canonical->original_sysno = gst->guest_RAX; + + // no canonical->canonical_sysno adjustment needed #elif defined(VGP_s390x_linux) VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; - canonical->sysno = gst->guest_SYSNO; + canonical->canonical_sysno = gst->guest_SYSNO; canonical->arg1 = gst->guest_r2; canonical->arg2 = gst->guest_r3; canonical->arg3 = gst->guest_r4; @@ -869,7 +889,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_riscv64_linux) VexGuestRISCV64State* gst = (VexGuestRISCV64State*)gst_vanilla; - canonical->sysno = gst->guest_x17; /* a7 */ + canonical->canonical_sysno = gst->guest_x17; /* a7 */ canonical->arg1 = gst->guest_x10; /* a0 */ canonical->arg2 = gst->guest_x11; /* a1 */ canonical->arg3 = gst->guest_x12; /* a2 */ @@ -882,7 +902,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_x86_solaris) VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_ESP; - canonical->sysno = gst->guest_EAX; + canonical->canonical_sysno = gst->guest_EAX; /* stack[0] is a return address. */ canonical->arg1 = stack[1]; canonical->arg2 = stack[2]; @@ -906,8 +926,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, break; case VEX_TRC_JMP_SYS_INT210: /* int $0xD2 = fasttrap */ - canonical->sysno - = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno); + canonical->canonical_sysno + = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->canonical_sysno); break; default: vg_assert(0); @@ -917,7 +937,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_amd64_solaris) VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_RSP; - canonical->sysno = gst->guest_RAX; + canonical->canonical_sysno = gst->guest_RAX; /* stack[0] is a return address. */ canonical->arg1 = gst->guest_RDI; canonical->arg2 = gst->guest_RSI; @@ -934,8 +954,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, break; case VEX_TRC_JMP_SYS_INT210: /* int $0xD2 = fasttrap */ - canonical->sysno - = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno); + canonical->canonical_sysno + = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->canonical_sysno); break; default: vg_assert(0); @@ -953,7 +973,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, { #if defined(VGP_x86_linux) VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; - gst->guest_EAX = canonical->sysno; + gst->guest_EAX = canonical->canonical_sysno; gst->guest_EBX = canonical->arg1; gst->guest_ECX = canonical->arg2; gst->guest_EDX = canonical->arg3; @@ -963,7 +983,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_amd64_linux) VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; - gst->guest_RAX = canonical->sysno; + gst->guest_RAX = canonical->canonical_sysno; gst->guest_RDI = canonical->arg1; gst->guest_RSI = canonical->arg2; gst->guest_RDX = canonical->arg3; @@ -973,7 +993,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_ppc32_linux) VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; - gst->guest_GPR0 = canonical->sysno; + gst->guest_GPR0 = canonical->canonical_sysno; gst->guest_GPR3 = canonical->arg1; gst->guest_GPR4 = canonical->arg2; gst->guest_GPR5 = canonical->arg3; @@ -983,7 +1003,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; - gst->guest_GPR0 = canonical->sysno; + gst->guest_GPR0 = canonical->canonical_sysno; gst->guest_GPR3 = canonical->arg1; gst->guest_GPR4 = canonical->arg2; gst->guest_GPR5 = canonical->arg3; @@ -997,22 +1017,21 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, UWord *stack = (UWord *)gst->guest_ESP; // stack[0] is a (fake) return address - switch (canonical->klass) { - case VG_FREEBSD_SYSCALL0: - gst->guest_EAX = __NR_syscall; - stack[1] = canonical->sysno; + switch (canonical->original_sysno) { + case __NR_syscall: + stack[1] = canonical->canonical_sysno; stack++; break; - case VG_FREEBSD_SYSCALL198: - gst->guest_EAX = __NR___syscall; - stack[1] = canonical->sysno; + case __NR___syscall: + stack[1] = canonical->canonical_sysno; stack += 2; break; default: - gst->guest_EAX = canonical->sysno; break; } + gst->guest_EAX = canonical->original_sysno; + stack[1] = canonical->arg1; stack[2] = canonical->arg2; stack[3] = canonical->arg3; @@ -1026,21 +1045,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_RSP; - // stack[0] is a (fake) return address - switch (canonical->klass) { - case VG_FREEBSD_SYSCALL0: - gst->guest_RAX = __NR_syscall; - break; - case VG_FREEBSD_SYSCALL198: - gst->guest_RAX = __NR___syscall; - break; - default: - gst->guest_RAX = canonical->sysno; - break; - } - - if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) { - gst->guest_RDI = canonical->sysno; + if (canonical->original_sysno == __NR_syscall || + canonical->original_sysno == __NR___syscall) { + gst->guest_RDI = canonical->canonical_sysno; gst->guest_RSI = canonical->arg1; gst->guest_RDX = canonical->arg2; gst->guest_R10 = canonical->arg3; @@ -1060,21 +1067,14 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, stack[2] = canonical->arg8; } + gst->guest_RAX = canonical->original_sysno; + #elif defined(VGP_arm64_freebsd) VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; - switch (canonical->klass) { - case VG_FREEBSD_SYSCALL0: - gst->guest_X8 = __NR_syscall; - break; - case VG_FREEBSD_SYSCALL198: - gst->guest_X8 = __NR___syscall; - break; - default: - gst->guest_X8 = canonical->sysno; - break; - } - if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) { - gst->guest_X0 = canonical->sysno; + + if (canonical->original_sysno == __NR_syscall || + canonical->original_sysno == __NR___syscall) { + gst->guest_X0 = canonical->canonical_sysno; gst->guest_X1 = canonical->arg1; gst->guest_X2 = canonical->arg2; gst->guest_X3 = canonical->arg3; @@ -1092,9 +1092,11 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, gst->guest_X6 = canonical->arg7; } + gst->guest_X8 = canonical->original_sysno; + #elif defined(VGP_arm_linux) VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; - gst->guest_R7 = canonical->sysno; + gst->guest_R7 = canonical->canonical_sysno; gst->guest_R0 = canonical->arg1; gst->guest_R1 = canonical->arg2; gst->guest_R2 = canonical->arg3; @@ -1104,7 +1106,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_arm64_linux) VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; - gst->guest_X8 = canonical->sysno; + gst->guest_X8 = canonical->canonical_sysno; gst->guest_X0 = canonical->arg1; gst->guest_X1 = canonical->arg2; gst->guest_X2 = canonical->arg3; @@ -1116,7 +1118,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_ESP; - gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno); + gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->canonical_sysno); // GrP fixme? gst->guest_TEMP_EFLAG_C = 0; // stack[0] is return address @@ -1133,7 +1135,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; UWord *stack = (UWord *)gst->guest_RSP; - gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno); + gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->canonical_sysno); // GrP fixme? gst->guest_TEMP_EFLAG_C = 0; // stack[0] is return address @@ -1148,7 +1150,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_s390x_linux) VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; - gst->guest_SYSNO = canonical->sysno; + gst->guest_SYSNO = canonical->canonical_sysno; gst->guest_r2 = canonical->arg1; gst->guest_r3 = canonical->arg2; gst->guest_r4 = canonical->arg3; @@ -1159,7 +1161,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_mips32_linux) VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; if (canonical->arg8 != __NR_syscall) { - gst->guest_r2 = canonical->sysno; + gst->guest_r2 = canonical->canonical_sysno; gst->guest_r4 = canonical->arg1; gst->guest_r5 = canonical->arg2; gst->guest_r6 = canonical->arg3; @@ -1170,7 +1172,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, } else { canonical->arg8 = 0; gst->guest_r2 = __NR_syscall; - gst->guest_r4 = canonical->sysno; + gst->guest_r4 = canonical->canonical_sysno; gst->guest_r5 = canonical->arg1; gst->guest_r6 = canonical->arg2; gst->guest_r7 = canonical->arg3; @@ -1182,7 +1184,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_nanomips_linux) VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; - gst->guest_r2 = canonical->sysno; + gst->guest_r2 = canonical->canonical_sysno; gst->guest_r4 = canonical->arg1; gst->guest_r5 = canonical->arg2; gst->guest_r6 = canonical->arg3; @@ -1193,7 +1195,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, gst->guest_r11 = canonical->arg8; #elif defined(VGP_mips64_linux) VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; - gst->guest_r2 = canonical->sysno; + gst->guest_r2 = canonical->canonical_sysno; gst->guest_r4 = canonical->arg1; gst->guest_r5 = canonical->arg2; gst->guest_r6 = canonical->arg3; @@ -1205,7 +1207,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, #elif defined(VGP_riscv64_linux) VexGuestRISCV64State* gst = (VexGuestRISCV64State*)gst_vanilla; - gst->guest_x17 = canonical->sysno; /* a7 */ + gst->guest_x17 = canonical->canonical_sysno; /* a7 */ gst->guest_x10 = canonical->arg1; /* a0 */ gst->guest_x11 = canonical->arg2; /* a1 */ gst->guest_x12 = canonical->arg3; /* a2 */ @@ -1218,9 +1220,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, UWord *stack = (UWord *)gst->guest_ESP; /* Fasttraps or anything else cannot go through this way. */ - vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno) + vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->canonical_sysno) == VG_SOLARIS_SYSCALL_CLASS_CLASSIC); - gst->guest_EAX = canonical->sysno; + gst->guest_EAX = canonical->canonical_sysno; /* stack[0] is a return address. */ stack[1] = canonical->arg1; stack[2] = canonical->arg2; @@ -1236,9 +1238,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, UWord *stack = (UWord *)gst->guest_RSP; /* Fasttraps or anything else cannot go through this way. */ - vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno) + vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->canonical_sysno) == VG_SOLARIS_SYSCALL_CLASS_CLASSIC); - gst->guest_RAX = canonical->sysno; + gst->guest_RAX = canonical->canonical_sysno; /* stack[0] is a return address. */ gst->guest_RDI = canonical->arg1; gst->guest_RSI = canonical->arg2; @@ -1807,7 +1809,7 @@ void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid, hardwired. */ static -void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) +void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout, /*IN*/Bool syscall_syscall ) { VG_(bzero_inline)(layout, sizeof(*layout)); @@ -1856,6 +1858,10 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) layout->uu_arg8 = -1; /* impossible value */ #elif defined(VGP_x86_freebsd) + // libc converts syscall_syscall to canonical form + // (it just needs to pop the ret address, pop the sysno into eax + // do the syscall + // and push back the ret address) layout->o_sysno = OFFSET_x86_EAX; // syscall parameters are on stack in C convention layout->s_arg1 = sizeof(UWord) * 1; @@ -1867,28 +1873,58 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) layout->s_arg7 = sizeof(UWord) * 7; layout->s_arg8 = sizeof(UWord) * 8; -#elif defined(VGP_amd64_freebsd) - layout->o_sysno = OFFSET_amd64_RAX; - layout->o_arg1 = OFFSET_amd64_RDI; - layout->o_arg2 = OFFSET_amd64_RSI; - layout->o_arg3 = OFFSET_amd64_RDX; - layout->o_arg4 = OFFSET_amd64_R10; - layout->o_arg5 = OFFSET_amd64_R8; - layout->o_arg6 = OFFSET_amd64_R9; - layout->s_arg7 = sizeof(UWord) * 1; - layout->s_arg8 = sizeof(UWord) * 2; - layout->arg6_is_reg = True; +#elif defined(VGP_amd64_freebsd) || defined(VGP_amd64_darwin) + if (syscall_syscall) + { + layout->o_sysno = OFFSET_amd64_RDI; + layout->o_arg1 = OFFSET_amd64_RSI; + layout->o_arg2 = OFFSET_amd64_RDX; + layout->o_arg3 = OFFSET_amd64_R10; + layout->o_arg4 = OFFSET_amd64_R8; + layout->o_arg5 = OFFSET_amd64_R9; + layout->s_arg6 = sizeof(UWord) * 1; + layout->s_arg7 = sizeof(UWord) * 2; + layout->s_arg8 = sizeof(UWord) * 3; + layout->arg6_is_reg = False; + } + else + { + layout->o_sysno = OFFSET_amd64_RAX; + layout->o_arg1 = OFFSET_amd64_RDI; + layout->o_arg2 = OFFSET_amd64_RSI; + layout->o_arg3 = OFFSET_amd64_RDX; + layout->o_arg4 = OFFSET_amd64_R10; + layout->o_arg5 = OFFSET_amd64_R8; + layout->o_arg6 = OFFSET_amd64_R9; + layout->s_arg7 = sizeof(UWord) * 1; + layout->s_arg8 = sizeof(UWord) * 2; + layout->arg6_is_reg = True; + } #elif defined(VGP_arm64_freebsd) - layout->o_sysno = OFFSET_arm64_X8; - layout->o_arg1 = OFFSET_arm64_X0; - layout->o_arg2 = OFFSET_arm64_X1; - layout->o_arg3 = OFFSET_arm64_X2; - layout->o_arg4 = OFFSET_arm64_X3; - layout->o_arg5 = OFFSET_arm64_X4; - layout->o_arg6 = OFFSET_arm64_X5; - layout->o_arg7 = OFFSET_arm64_X6; - layout->o_arg8 = OFFSET_arm64_X7; + if (syscall_syscall) + { + layout->o_sysno = OFFSET_arm64_X0; + layout->o_arg1 = OFFSET_arm64_X1; + layout->o_arg2 = OFFSET_arm64_X2; + layout->o_arg3 = OFFSET_arm64_X3; + layout->o_arg4 = OFFSET_arm64_X4; + layout->o_arg5 = OFFSET_arm64_X5; + layout->o_arg6 = OFFSET_arm64_X6; + layout->o_arg7 = OFFSET_arm64_X7; + } + else + { + layout->o_sysno = OFFSET_arm64_X8; + layout->o_arg1 = OFFSET_arm64_X0; + layout->o_arg2 = OFFSET_arm64_X1; + layout->o_arg3 = OFFSET_arm64_X2; + layout->o_arg4 = OFFSET_arm64_X3; + layout->o_arg5 = OFFSET_arm64_X4; + layout->o_arg6 = OFFSET_arm64_X5; + layout->o_arg7 = OFFSET_arm64_X6; + layout->o_arg8 = OFFSET_arm64_X7; + } #elif defined(VGP_arm_linux) layout->o_sysno = OFFSET_arm_R7; @@ -2018,36 +2054,6 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) #endif } -#if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd) -static -void getSyscallArgLayout_0_198 ( /*OUT*/SyscallArgLayout* layout ) -{ -#if defined(VGP_amd64_freebsd) - VG_(bzero_inline)(layout, sizeof(*layout)); - layout->o_sysno = OFFSET_amd64_RDI; - layout->o_arg1 = OFFSET_amd64_RSI; - layout->o_arg2 = OFFSET_amd64_RDX; - layout->o_arg3 = OFFSET_amd64_R10; - layout->o_arg4 = OFFSET_amd64_R8; - layout->o_arg5 = OFFSET_amd64_R9; - layout->s_arg6 = sizeof(UWord) * 1; - layout->s_arg7 = sizeof(UWord) * 2; - layout->s_arg8 = sizeof(UWord) * 3; - layout->arg6_is_reg = False; -#else - layout->o_sysno = OFFSET_arm64_X0; - layout->o_arg1 = OFFSET_arm64_X1; - layout->o_arg2 = OFFSET_arm64_X2; - layout->o_arg3 = OFFSET_arm64_X3; - layout->o_arg4 = OFFSET_arm64_X4; - layout->o_arg5 = OFFSET_arm64_X5; - layout->o_arg6 = OFFSET_arm64_X6; - layout->o_arg7 = OFFSET_arm64_X7; -#endif -} -#endif - - /* --------------------------------------------------------------------- The main driver logic ------------------------------------------------------------------ */ @@ -2063,7 +2069,7 @@ void bad_before ( ThreadId tid, /*OUT*/UWord* flags ) { VG_(dmsg)("WARNING: unhandled %s syscall: %s\n", - VG_PLATFORM, VG_SYSNUM_STRING(args->sysno)); + VG_PLATFORM, VG_SYSNUM_STRING(args->canonical_sysno)); if (VG_(clo_verbosity) > 1) { VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); } @@ -2093,28 +2099,7 @@ static const SyscallTableEntry* get_syscall_entry ( Int syscallno ) sys = ML_(get_freebsd_syscall_entry)( syscallno ); # elif defined(VGO_darwin) - Int idx = VG_DARWIN_SYSNO_INDEX(syscallno); - - switch (VG_DARWIN_SYSNO_CLASS(syscallno)) { - case VG_DARWIN_SYSCALL_CLASS_UNIX: - if (idx >= 0 && idx < ML_(syscall_table_size) && - ML_(syscall_table)[idx].before != NULL) - sys = &ML_(syscall_table)[idx]; - break; - case VG_DARWIN_SYSCALL_CLASS_MACH: - if (idx >= 0 && idx < ML_(mach_trap_table_size) && - ML_(mach_trap_table)[idx].before != NULL) - sys = &ML_(mach_trap_table)[idx]; - break; - case VG_DARWIN_SYSCALL_CLASS_MDEP: - if (idx >= 0 && idx < ML_(mdep_trap_table_size) && - ML_(mdep_trap_table)[idx].before != NULL) - sys = &ML_(mdep_trap_table)[idx]; - break; - default: - vg_assert(0); - break; - } + sys = ML_(get_darwin_syscall_entry)( syscallno ); # elif defined(VGO_solaris) sys = ML_(get_solaris_syscall_entry)(syscallno); @@ -2173,7 +2158,7 @@ Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid ) Word VG_(is_in_syscall_no) (ThreadId tid ) { vg_assert(tid < VG_N_THREADS); - return syscallInfo[tid].orig_args.sysno; + return syscallInfo[tid].orig_args.canonical_sysno; } static void ensure_initialised ( void ) @@ -2195,11 +2180,13 @@ static void ensure_initialised ( void ) void VG_(client_syscall) ( ThreadId tid, UInt trc ) { - Word sysno; + Word canonical_sysno; + Word original_sysno; ThreadState* tst; const SyscallTableEntry* ent; SyscallArgLayout layout; SyscallInfo* sci; + Bool syscall_syscall = False; ensure_initialised(); @@ -2312,14 +2299,21 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Save the syscall number in the thread state in case the syscall is interrupted by a signal. */ - sysno = sci->orig_args.sysno; + canonical_sysno = sci->orig_args.canonical_sysno; +#if defined(VGO_freebsd) || defined(VGP_amd64_darwin) + original_sysno = sci->orig_args.original_sysno; +#else + /* + * When there is no "syscall syycall" the original + * and canonical sysno values are the same + */ + original_sysno = sci->orig_args.canonical_sysno; +#endif + -# if defined(VGO_freebsd) - tst->arch.vex.guest_SC_CLASS = sci->orig_args.klass; -# endif /* It's sometimes useful, as a crude debugging hack, to get a stack trace at each (or selected) syscalls. */ - if (0 && sysno == __NR_ioctl) { + if (0 && canonical_sysno == __NR_ioctl) { VG_(umsg)("\nioctl:\n"); VG_(get_and_pp_StackTrace)(tid, 10); VG_(umsg)("\n"); @@ -2335,7 +2329,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) because it only has a single syscall return convention and so there is no ambiguity involved in converting the post-signal machine state into a SysRes. */ - tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(sysno); + tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(canonical_sysno); # endif /* The default what-to-do-next thing is hand the syscall to the @@ -2349,7 +2343,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Fetch the syscall's handlers. If no handlers exist for this syscall, we are given dummy handlers which force an immediate return with ENOSYS. */ - ent = get_syscall_entry(sysno); + ent = get_syscall_entry(canonical_sysno); /* Fetch the layout information, which tells us where in the guest state the syscall args reside. This is a platform-dependent @@ -2357,21 +2351,18 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) checks (PRE_REG_READ calls) know which bits of the guest state they need to inspect. */ #if defined(VGP_amd64_freebsd) || defined (VGP_arm64_freebsd) - // PJF - somewhat unfortunate uglificaton of the code, but the current code handles two - // types of syscall with different register use. Mixing them up is not good. - // I've avoided modifying the existing function (I could have added - // a FreeBSD amd64-only flag to it for this purpose). - if (sci->orig_args.klass == VG_FREEBSD_SYSCALL0 || sci->orig_args.klass == VG_FREEBSD_SYSCALL198) { - getSyscallArgLayout_0_198( &layout ); - } else { + if (original_sysno == __NR_syscall || + original_sysno == __NR___syscall) { + syscall_syscall = True; + } #endif - - getSyscallArgLayout( &layout ); - -#if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd) +#if defined(VGP_amd64_darwin) + if (original_sysno == __NR_syscall) { + syscall_syscall = True; } + original_sysno = canonical_sysno; #endif - + getSyscallArgLayout( &layout, syscall_syscall ); /* Make sure the tmp signal mask matches the real signal mask; sigsuspend may change this. */ @@ -2387,7 +2378,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) */ PRINT("SYSCALL[%d,%u](%s) ", - VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno)); + VG_(getpid)(), tid, VG_SYSNUM_STRING(canonical_sysno)); /* Do any pre-syscall actions */ if (VG_(needs).syscall_wrapper) { @@ -2400,7 +2391,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) tmpv[5] = sci->orig_args.arg6; tmpv[6] = sci->orig_args.arg7; tmpv[7] = sci->orig_args.arg8; - VG_TDICT_CALL(tool_pre_syscall, tid, sysno, + VG_TDICT_CALL(tool_pre_syscall, tid, canonical_sysno, &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0])); } @@ -2411,7 +2402,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) &sci->args, &sci->status, &sci->flags ); /* If needed, gdbserver will report syscall entry to GDB */ - VG_(gdbserver_report_syscall)(True, sysno, tid); + VG_(gdbserver_report_syscall)(True, canonical_sysno, tid); /* The pre-handler may have modified: sci->args @@ -2424,7 +2415,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Now we proceed according to what the pre-handler decided. */ vg_assert(sci->status.what == SsHandToKernel || sci->status.what == SsComplete); - vg_assert(sci->args.sysno == sci->orig_args.sysno); + vg_assert(sci->args.canonical_sysno == sci->orig_args.canonical_sysno); if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) { /* The pre-handler completed the syscall itself, declaring @@ -2507,7 +2498,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Do the call, which operates directly on the guest state, not on our abstracted copies of the args/result. */ - do_syscall_for_client(sysno, tst, &mask); + do_syscall_for_client(original_sysno, tst, &mask); /* do_syscall_for_client may not return if the syscall was interrupted by a signal. In that case, flow of control is @@ -2535,7 +2526,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Be decorative, if required. */ if (VG_(clo_trace_syscalls)) { PRINT("SYSCALL[%d,%u](%s) ... [async] --> %s", - VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno), + VG_(getpid)(), tid, VG_SYSNUM_STRING(canonical_sysno), VG_(sr_as_string)(sci->status.sres)); } @@ -2548,7 +2539,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) guest state. Indeed doing so could be construed as incorrect. */ SysRes sres - = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2, + = VG_(do_syscall)(canonical_sysno, sci->args.arg1, sci->args.arg2, sci->args.arg3, sci->args.arg4, sci->args.arg5, sci->args.arg6, sci->args.arg7, sci->args.arg8 ); @@ -2571,7 +2562,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex ); /* If needed, gdbserver will report syscall return to GDB */ - VG_(gdbserver_report_syscall)(False, sysno, tid); + VG_(gdbserver_report_syscall)(False, canonical_sysno, tid); /* Situation now: - the guest state is now correctly modified following the syscall @@ -2605,7 +2596,7 @@ void VG_(post_syscall) (ThreadId tid) const SyscallTableEntry* ent; SyscallStatus test_status; ThreadState* tst; - Word sysno; + Word canonical_sysno; /* Preliminaries */ vg_assert(VG_(is_valid_tid)(tid)); @@ -2631,12 +2622,12 @@ void VG_(post_syscall) (ThreadId tid) /* Get the system call number. Because the pre-handler isn't allowed to mess with it, it should be the same for both the original and potentially-modified args. */ - vg_assert(sci->args.sysno == sci->orig_args.sysno); - sysno = sci->args.sysno; + vg_assert(sci->args.canonical_sysno == sci->orig_args.canonical_sysno); + canonical_sysno = sci->args.canonical_sysno; getSyscallStatusFromGuestState( &test_status, &tst->arch.vex ); if (!(sci->flags & SfNoWriteResult)) { - vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status )); + vg_assert(eq_SyscallStatus( canonical_sysno, &sci->status, &test_status )); } /* Failure of the above assertion on Darwin can indicate a problem in the syscall wrappers that pre-fail or pre-succeed the @@ -2654,11 +2645,9 @@ void VG_(post_syscall) (ThreadId tid) - it exists, and - Success or (Failure and PostOnFail is set) */ - ent = get_syscall_entry(sysno); + ent = get_syscall_entry(canonical_sysno); if (ent->after - && ((!sr_isError(sci->status.sres)) - || (sr_isError(sci->status.sres) - && (sci->flags & SfPostOnFail) ))) { + && (!sr_isError(sci->status.sres) || (sci->flags & SfPostOnFail))) { (ent->after)( tid, &sci->args, &sci->status ); } @@ -2682,7 +2671,7 @@ void VG_(post_syscall) (ThreadId tid) tmpv[6] = sci->orig_args.arg7; tmpv[7] = sci->orig_args.arg8; VG_TDICT_CALL(tool_post_syscall, tid, - sysno, + canonical_sysno, &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]), sci->status.sres); } @@ -2976,7 +2965,7 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch ) } #elif defined(VGP_x86_darwin) - arch->vex.guest_EIP = arch->vex.guest_IP_AT_SYSCALL; + arch->vex.guest_EIP -= 2; /* Make sure our caller is actually sane, and we're really backing back over a syscall. @@ -3000,7 +2989,7 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch ) } #elif defined(VGP_amd64_darwin) - arch->vex.guest_RIP = arch->vex.guest_IP_AT_SYSCALL; + arch->vex.guest_RIP -= 2; /* Make sure our caller is actually sane, and we're really backing back over a syscall. @@ -3329,18 +3318,6 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, # error "Unknown OS" # endif -#if defined(VGO_freebsd) || defined(VGO_darwin) - if (outside_range) - { - if (th_regs->vex.guest_SETC) - { - outside_range = False; - in_complete_to_committed = True; - } - } -#endif - - /* Figure out what the state of the syscall was by examining the (real) IP at the time of the signal, and act accordingly. */ if (outside_range) { @@ -3428,40 +3405,24 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, we expect our caller (the signal handler) will have fixed this up. */ /* XXX: needed? */ -#if defined(VGP_x86_freebsd) - /* On FreeBSD, the success/fail status is returned to the caller - and still has to be fixed up here. */ +#if defined(VGP_x86_freebsd) || defined(VGP_x86_solaris) || defined(VGP_x86_darwin) + /* The %eax and %edx values are committed but the carry flag is still + uncommitted. Save it now. */ if (!(sci->flags & SfNoWriteResult)) { - if (sr_isError(sres)) - LibVEX_GuestX86_put_eflag_c(1, &th_regs->vex); - else - LibVEX_GuestX86_put_eflag_c(0, &th_regs->vex); + LibVEX_GuestX86_put_eflag_c(sr_isError(sres), &th_regs->vex); } -#elif defined(VGP_amd64_freebsd) +#elif defined(VGP_amd64_freebsd) || defined(VGP_amd64_solaris) || defined(VGP_amd64_darwin) if (!(sci->flags & SfNoWriteResult)) { - if (sr_isError(sres)) - LibVEX_GuestAMD64_put_rflag_c(1, &th_regs->vex); - else - LibVEX_GuestAMD64_put_rflag_c(0, &th_regs->vex); + LibVEX_GuestAMD64_put_rflag_c(sr_isError(sres), &th_regs->vex); } #elif defined(VGP_arm64_freebsd) if (!(sci->flags & SfNoWriteResult)) { - if (sr_isError(sres)) - LibVEX_GuestARM64_put_nzcv_c(1, &th_regs->vex); - else - LibVEX_GuestARM64_put_nzcv_c(0, &th_regs->vex); + LibVEX_GuestARM64_put_nzcv_c(sr_isError(sres), &th_regs->vex); } #endif if (VG_(clo_trace_signals)) VG_(message)( Vg_DebugMsg, " completed and committed: nothing to do\n"); -# if defined(VGP_x86_solaris) - /* The %eax and %edx values are committed but the carry flag is still - uncommitted. Save it now. */ - LibVEX_GuestX86_put_eflag_c(sr_isError(sres), &th_regs->vex); -# elif defined(VGP_amd64_solaris) - LibVEX_GuestAMD64_put_rflag_c(sr_isError(sres), &th_regs->vex); -# endif getSyscallStatusFromGuestState( &sci->status, &th_regs->vex ); vg_assert(sci->status.what == SsComplete); VG_(post_syscall)(tid); diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 6132c9ff1a..fde0f614e4 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -896,7 +896,7 @@ static SyscallTableEntry syscall_main_table[] = { //.. GENX_(__NR_init_module, sys_init_module), // 128 //.. // (__NR_delete_module, sys_delete_module), // 129 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 - //.. LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY (__NR_quotactl, sys_quotactl), // 131 GENX_ (__NR_getpgid, sys_getpgid), // 132 GENX_ (__NR_fchdir, sys_fchdir), // 133 //.. // (__NR_bdflush, sys_bdflush), // 134 @@ -980,7 +980,7 @@ static SyscallTableEntry syscall_main_table[] = { PLAXY (__NR_fstat64, sys_fstat64), // 215 LINX_ (__NR_pivot_root, sys_pivot_root), // 216 GENXY (__NR_mincore, sys_mincore), // 217 - GENX_ (__NR_madvise, sys_madvise), // 218 + GENXY (__NR_madvise, sys_madvise), // 218 GENXY (__NR_getdents64, sys_getdents64), // 219 LINXY (__NR_fcntl64, sys_fcntl64), // 220 //.. @@ -1003,7 +1003,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_futex, sys_futex), // 238 LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity), // 239 LINXY (__NR_sched_getaffinity, sys_sched_getaffinity), // 240 - LINX_ (__NR_io_setup, sys_io_setup), // 241 + LINXY (__NR_io_setup, sys_io_setup), // 241 LINX_ (__NR_io_destroy, sys_io_destroy), // 242 LINXY (__NR_io_getevents, sys_io_getevents), // 243 LINX_ (__NR_io_submit, sys_io_submit), // 244 @@ -1110,7 +1110,7 @@ static SyscallTableEntry syscall_main_table[] = { //.. LINX_(__NR_sched_setattr, sys_sched_setattr), // 349 LINXY(__NR_sched_getattr, sys_sched_getattr), // 350 - LINX_(__NR_renameat2, sys_renameat2), // 351 + GENX_(__NR_renameat2, sys_renameat2), // 351 //.. LINXY (__NR_getrandom, sys_getrandom), // 353 LINXY (__NR_memfd_create, sys_memfd_create), // 354 @@ -1125,7 +1125,7 @@ static SyscallTableEntry syscall_main_table[] = { //.. LINXY(__NR_statx, sys_statx), // 366 GENX_(__NR_rseq, sys_ni_syscall), // 367 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 368 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 368 LINX_(__NR_semget, sys_semget), // 393 LINXY(__NR_semctl, sys_semctl), // 394 @@ -1178,7 +1178,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 LINX_(__NR_landlock_restrict_self, sys_landlock_restrict_self), // 446 @@ -1188,7 +1188,12 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 LINXY(__NR_statmount, sys_statmount), // 457 LINXY(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_(__NR_mseal, sys_mseal), // 462 + LINXY(__NR_file_getattr, sys_file_getattr), // 468 + LINX_(__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index 238b1cda0d..b08dc3b9bd 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -495,7 +495,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_ (__NR_mremap, sys_mremap), GENX_ (__NR_msync, sys_msync), GENXY (__NR_mincore, sys_mincore), - GENX_ (__NR_madvise, sys_madvise), + GENXY (__NR_madvise, sys_madvise), LINX_ (__NR_shmget, sys_shmget), LINXY (__NR_shmat, sys_shmat), LINXY (__NR_shmctl, sys_shmctl), @@ -644,7 +644,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_delete_module, sys_delete_module), GENX_ (__NR_get_kernel_syms, sys_ni_syscall), GENX_ (__NR_query_module, sys_ni_syscall), - LINX_ (__NR_quotactl, sys_quotactl), + LINXY (__NR_quotactl, sys_quotactl), /* GENX_(__NR_nfsservctl,sys_nfsservctl), */ GENXY (__NR_getpmsg, sys_getpmsg), GENX_ (__NR_putpmsg, sys_putpmsg), @@ -699,7 +699,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_clock_gettime, sys_clock_gettime), LINXY (__NR_clock_getres, sys_clock_getres), LINXY (__NR_clock_nanosleep, sys_clock_nanosleep), - LINX_ (__NR_tgkill, sys_tgkill), + LINXY (__NR_tgkill, sys_tgkill), GENX_ (__NR_utimes, sys_utimes), LINX_ (__NR_mbind, sys_mbind), LINXY (__NR_get_mempolicy, sys_get_mempolicy), @@ -757,7 +757,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_process_vm_writev, sys_process_vm_writev), LINX_ (__NR_sched_setattr, sys_sched_setattr), LINXY (__NR_sched_getattr, sys_sched_getattr), - LINX_ (__NR_renameat2, sys_renameat2), + GENX_ (__NR_renameat2, sys_renameat2), LINXY (__NR_getrandom, sys_getrandom), LINXY (__NR_memfd_create, sys_memfd_create), LINX_ (__NR_execveat, sys_execveat), @@ -771,7 +771,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_syncfs, sys_syncfs), LINXY (__NR_statx, sys_statx), GENX_ (__NR_rseq, sys_ni_syscall), - LINX_ (__NR_io_pgetevents, sys_io_pgetevents), + LINXY (__NR_io_pgetevents, sys_io_pgetevents), LINX_ (__NR_setns, sys_setns), LINXY (__NR_io_uring_setup, sys_io_uring_setup), LINXY (__NR_io_uring_enter, sys_io_uring_enter), @@ -797,9 +797,14 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_userfaultfd, sys_userfaultfd), LINXY (__NR_statmount, sys_statmount), LINXY (__NR_listmount, sys_listmount), + LINXY (__NR_lsm_get_self_attr, sys_lsm_get_self_attr), + LINX_ (__NR_lsm_set_self_attr, sys_lsm_set_self_attr), + LINXY (__NR_lsm_list_modules, sys_lsm_list_modules), LINX_ (__NR_mseal, sys_mseal), LINX_ (__NR_futex_waitv, sys_futex_waitv), - LINX_ (__NR_quotactl_fd, sys_quotactl_fd), + LINXY (__NR_quotactl_fd, sys_quotactl_fd), + LINXY (__NR_file_getattr, sys_file_getattr), + LINX_ (__NR_file_setattr, sys_file_setattr), }; SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c index bb20cd7d3b..3e99320c76 100644 --- a/coregrind/m_syswrap/syswrap-nanomips-linux.c +++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c @@ -592,7 +592,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_ (__NR_close, sys_close), LINX_ (__NR_vhangup, sys_vhangup), LINXY (__NR_pipe2, sys_pipe2), - LINX_ (__NR_quotactl, sys_quotactl), + LINXY (__NR_quotactl, sys_quotactl), GENXY (__NR_getdents64, sys_getdents64), LINXY (__NR__llseek, sys_llseek), GENXY (__NR_read, sys_read), @@ -657,7 +657,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_sched_yield, sys_sched_yield), LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max), LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min), - LINX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval), + LINXY (__NR_sched_rr_get_interval, sys_sched_rr_get_interval), GENX_ (__NR_kill, sys_kill), LINXY (__NR_tkill, sys_tkill), LINXY (__NR_tgkill, sys_tgkill), @@ -760,7 +760,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_ (__NR_mlockall, sys_mlockall), LINX_ (__NR_munlockall, sys_munlockall), GENXY (__NR_mincore, sys_mincore), - GENX_ (__NR_madvise, sys_madvise), + GENXY (__NR_madvise, sys_madvise), LINX_ (__NR_mbind, sys_mbind), LINXY (__NR_get_mempolicy, sys_get_mempolicy), LINX_ (__NR_set_mempolicy, sys_set_mempolicy), @@ -782,7 +782,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_process_vm_readv, sys_process_vm_readv), LINX_ (__NR_process_vm_writev, sys_process_vm_writev), LINX_ (__NR_kcmp, sys_kcmp), - LINX_ (__NR_renameat2, sys_renameat2), + GENX_ (__NR_renameat2, sys_renameat2), LINX_ (__NR_sched_setattr, sys_sched_setattr), LINXY (__NR_sched_getattr, sys_sched_getattr), LINXY (__NR_getrandom, sys_getrandom), @@ -823,8 +823,13 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_fchmodat2, sys_fchmodat2), LINXY (__NR_statmount, sys_statmount), LINXY (__NR_listmount, sys_listmount), + LINXY (__NR_lsm_get_self_attr, sys_lsm_get_self_attr), + LINX_ (__NR_lsm_set_self_attr, sys_lsm_set_self_attr), + LINXY (__NR_lsm_list_modules, sys_lsm_list_modules), LINX_ (__NR_mseal, sys_mseal), LINX_ (__NR_futex_waitv, sys_futex_waitv), + LINXY (__NR_file_getattr, sys_file_getattr), + LINX_ (__NR_file_setattr, sys_file_setattr), }; SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 4d7e43130c..f56a2de7db 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -770,7 +770,7 @@ static SyscallTableEntry syscall_table[] = { //.. //.. // Nb: get_kernel_syms() was removed 2.4-->2.6 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 -//.. LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY(__NR_quotactl, sys_quotactl), // 131 GENX_(__NR_getpgid, sys_getpgid), // 132 GENX_(__NR_fchdir, sys_fchdir), // 133 //.. // (__NR_bdflush, sys_bdflush), // 134 */Linux @@ -861,10 +861,10 @@ static SyscallTableEntry syscall_table[] = { GENXY(__NR_getdents64, sys_getdents64), // 202 LINX_(__NR_pivot_root, sys_pivot_root), // 203 LINXY(__NR_fcntl64, sys_fcntl64), // 204 - GENX_(__NR_madvise, sys_madvise), // 205 + GENXY(__NR_madvise, sys_madvise), // 205 GENXY(__NR_mincore, sys_mincore), // 206 LINX_(__NR_gettid, sys_gettid), // 207 -//.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux + LINXY(__NR_tkill, sys_tkill), // 208 */Linux LINX_(__NR_setxattr, sys_setxattr), // 209 LINX_(__NR_lsetxattr, sys_lsetxattr), // 210 LINX_(__NR_fsetxattr, sys_fsetxattr), // 211 @@ -886,8 +886,8 @@ static SyscallTableEntry syscall_table[] = { // __NR_tuxcall // 225 LINXY(__NR_sendfile64, sys_sendfile64), // 226 -//.. - LINX_(__NR_io_setup, sys_io_setup), // 227 +//.. + LINXY(__NR_io_setup, sys_io_setup), // 227 LINX_(__NR_io_destroy, sys_io_destroy), // 228 LINXY(__NR_io_getevents, sys_io_getevents), // 229 LINX_(__NR_io_submit, sys_io_submit), // 230 @@ -954,6 +954,8 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_pselect6, sys_pselect6), // 280 LINXY(__NR_ppoll, sys_ppoll), // 281 + LINX_(__NR_splice, sys_splice), // 283 + LINXY(__NR_openat, sys_openat), // 286 LINX_(__NR_mkdirat, sys_mkdirat), // 287 LINX_(__NR_mknodat, sys_mknodat), // 288 @@ -992,6 +994,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_pwritev, sys_pwritev), // 321 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322 + LINXY(__NR_prlimit64, sys_prlimit64), // 325 LINXY(__NR_socket, sys_socket), // 326 LINX_(__NR_bind, sys_bind), // 327 LINX_(__NR_connect, sys_connect), // 328 @@ -1010,7 +1013,7 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_recvmmsg, sys_recvmmsg), // 343 LINXY(__NR_accept4, sys_accept4), // 344 - LINX_(__NR_clock_adjtime, sys_clock_adjtime), // 347 + LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 347 LINX_(__NR_syncfs, sys_syncfs), // 348 LINXY(__NR_sendmmsg, sys_sendmmsg), // 349 @@ -1019,7 +1022,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 - LINX_(__NR_renameat2, sys_renameat2), // 357 + GENX_(__NR_renameat2, sys_renameat2), // 357 LINXY(__NR_getrandom, sys_getrandom), // 359 LINXY(__NR_memfd_create, sys_memfd_create), // 360 @@ -1027,9 +1030,11 @@ static SyscallTableEntry syscall_table[] = { LINX_ (__NR_execveat, sys_execveat), // 362 LINXY(__NR_userfaultfd, sys_userfaultfd), // 364 + LINX_(__NR_membarrier, sys_membarrier), // 365 + GENX_(__NR_mlock2, sys_mlock2), // 378 LINX_(__NR_copy_file_range, sys_copy_file_range), // 379 - LINX_(__NR_preadv2, sys_preadv2), // 380 + LINXY(__NR_preadv2, sys_preadv2), // 380 LINX_(__NR_pwritev2, sys_pwritev2), // 381 LINXY(__NR_statx, sys_statx), // 383 @@ -1076,7 +1081,7 @@ static SyscallTableEntry syscall_table[] = { LINXY (__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_ (__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_ (__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY (__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -1087,7 +1092,12 @@ static SyscallTableEntry syscall_table[] = { LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 LINXY (__NR_statmount, sys_statmount), // 457 LINXY (__NR_listmount, sys_listmount), // 458 + LINXY (__NR_lsm_get_self_attr,sys_lsm_get_self_attr), // 459 + LINX_ (__NR_lsm_set_self_attr,sys_lsm_set_self_attr), // 460 + LINXY (__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_ (__NR_mseal, sys_mseal), // 462 + LINXY (__NR_file_getattr, sys_file_getattr), // 468 + LINX_ (__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 7f78e23ecd..c8ba94da8e 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -363,7 +363,7 @@ asm( void VG_(cleanup_thread) ( ThreadArchState* arch ) { -} +} /* --------------------------------------------------------------------- PRE/POST wrappers for ppc64/Linux-specific syscalls @@ -399,7 +399,7 @@ PRE(sys_mmap) unsigned long, prot, unsigned long, flags, unsigned long, fd, unsigned long, offset); - r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, + r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, (Off64T)ARG6 ); SET_STATUS_from_SysRes(r); } @@ -407,7 +407,7 @@ PRE(sys_mmap) //zz PRE(sys_mmap2) //zz { //zz SysRes r; -//zz +//zz //zz // Exactly like old_mmap() except: //zz // - the file offset is specified in 4K units rather than bytes, //zz // so that it can be used for files bigger than 2^32 bytes. @@ -417,12 +417,12 @@ PRE(sys_mmap) //zz unsigned long, start, unsigned long, length, //zz unsigned long, prot, unsigned long, flags, //zz unsigned long, fd, unsigned long, offset); -//zz -//zz r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, +//zz +//zz r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, //zz 4096 * (Off64T)ARG6 ); //zz SET_STATUS_from_SysRes(r); //zz } -//zz +//zz //zz // XXX: lstat64/fstat64/stat64 are generic, but not necessarily //zz // applicable to every architecture -- I think only to 32-bit archs. //zz // We're going to need something like linux/core_os32.h for such @@ -434,12 +434,12 @@ PRE(sys_mmap) //zz PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); //zz PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); //zz } -//zz +//zz //zz POST(sys_stat64) //zz { //zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); //zz } -//zz +//zz //zz PRE(sys_lstat64) //zz { //zz PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2); @@ -447,7 +447,7 @@ PRE(sys_mmap) //zz PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 ); //zz PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); //zz } -//zz +//zz //zz POST(sys_lstat64) //zz { //zz vg_assert(SUCCESS); @@ -455,14 +455,14 @@ PRE(sys_mmap) //zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); //zz } //zz } -//zz +//zz //zz PRE(sys_fstat64) //zz { //zz PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2); //zz PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf); //zz PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); //zz } -//zz +//zz //zz POST(sys_fstat64) //zz { //zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); @@ -588,7 +588,7 @@ POST(sys_ptrace) ------------------------------------------------------------------ */ /* Add an ppc64-linux specific wrapper to a syscall table. */ -#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc64_linux, sysno, name) +#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc64_linux, sysno, name) #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc64_linux, sysno, name) // This table maps from __NR_xxx syscall numbers (from @@ -713,7 +713,7 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_truncate, sys_truncate), // 92 GENX_(__NR_ftruncate, sys_ftruncate), // 93 GENX_(__NR_fchmod, sys_fchmod), // 94 - + GENX_(__NR_fchown, sys_fchown), // 95 GENX_(__NR_getpriority, sys_getpriority), // 96 GENX_(__NR_setpriority, sys_setpriority), // 97 @@ -757,7 +757,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_delete_module, sys_delete_module), // 129 // _____(__NR_get_kernel_syms, sys_get_kernel_syms), // 130 - LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY(__NR_quotactl, sys_quotactl), // 131 GENX_(__NR_getpgid, sys_getpgid), // 132 GENX_(__NR_fchdir, sys_fchdir), // 133 // _____(__NR_bdflush, sys_bdflush), // 134 @@ -846,7 +846,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_pivot_root, sys_pivot_root), // 203 LINXY(__NR_fcntl64, sys_fcntl64), // 204 !!!!?? 32bit only */ - GENX_(__NR_madvise, sys_madvise), // 205 + GENXY(__NR_madvise, sys_madvise), // 205 GENXY(__NR_mincore, sys_mincore), // 206 LINX_(__NR_gettid, sys_gettid), // 207 LINXY(__NR_tkill, sys_tkill), // 208 @@ -871,7 +871,7 @@ static SyscallTableEntry syscall_table[] = { // _____(__NR_tuxcall, sys_tuxcall), // 225 // /* #define __NR_sendfile64 226 32bit only */ - LINX_(__NR_io_setup, sys_io_setup), // 227 + LINXY(__NR_io_setup, sys_io_setup), // 227 LINX_(__NR_io_destroy, sys_io_destroy), // 228 LINXY(__NR_io_getevents, sys_io_getevents), // 229 LINX_(__NR_io_submit, sys_io_submit), // 230 @@ -1012,7 +1012,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 - LINX_(__NR_renameat2, sys_renameat2), // 357 + GENX_(__NR_renameat2, sys_renameat2), // 357 LINXY(__NR_getrandom, sys_getrandom), // 359 LINXY(__NR_memfd_create, sys_memfd_create), // 360 @@ -1025,13 +1025,13 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_mlock2, sys_mlock2), // 378 LINX_(__NR_copy_file_range, sys_copy_file_range), // 379 - LINX_(__NR_preadv2, sys_preadv2), // 380 + LINXY(__NR_preadv2, sys_preadv2), // 380 LINX_(__NR_pwritev2, sys_pwritev2), // 381 LINXY(__NR_statx, sys_statx), // 383 GENX_(__NR_rseq, sys_ni_syscall), // 387 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 388 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 388 LINX_(__NR_semtimedop, sys_semtimedop), // 392 LINXY(__NR_semctl, sys_semctl), // 394 LINXY(__NR_shmctl, sys_shmctl), // 396 @@ -1054,7 +1054,7 @@ static SyscallTableEntry syscall_table[] = { LINXY (__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_ (__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_ (__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY (__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -1065,7 +1065,12 @@ static SyscallTableEntry syscall_table[] = { LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 LINXY (__NR_statmount, sys_statmount), // 457 LINXY (__NR_listmount, sys_listmount), // 458 + LINXY (__NR_lsm_get_self_attr,sys_lsm_get_self_attr), // 459 + LINX_ (__NR_lsm_set_self_attr,sys_lsm_set_self_attr), // 460 + LINXY (__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_ (__NR_mseal, sys_mseal), // 462 + LINXY (__NR_file_getattr, sys_file_getattr), // 468 + LINX_ (__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-riscv64-linux.c b/coregrind/m_syswrap/syswrap-riscv64-linux.c index 78b1b6b42d..d119482453 100644 --- a/coregrind/m_syswrap/syswrap-riscv64-linux.c +++ b/coregrind/m_syswrap/syswrap-riscv64-linux.c @@ -368,7 +368,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_(__NR_close, sys_close), /* 57 */ LINX_(__NR_vhangup, sys_vhangup), /* 58 */ LINXY(__NR_pipe2, sys_pipe2), /* 59 */ - LINX_(__NR_quotactl, sys_quotactl), /* 60 */ + LINXY(__NR_quotactl, sys_quotactl), /* 60 */ GENXY(__NR_getdents64, sys_getdents64), /* 61 */ LINX_(__NR_lseek, sys_lseek), /* 62 */ GENXY(__NR_read, sys_read), /* 63 */ @@ -438,7 +438,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), /* 127 */ GENX_(__NR_kill, sys_kill), /* 129 */ LINXY(__NR_tkill, sys_tkill), /* 130 */ - LINX_(__NR_tgkill, sys_tgkill), /* 131 */ + 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 */ @@ -539,7 +539,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_(__NR_mlockall, sys_mlockall), /* 230 */ LINX_(__NR_munlockall, sys_munlockall), /* 231 */ GENXY(__NR_mincore, sys_mincore), /* 232 */ - GENX_(__NR_madvise, sys_madvise), /* 233 */ + GENXY(__NR_madvise, sys_madvise), /* 233 */ LINX_(__NR_remap_file_pages, sys_remap_file_pages), /* 234 */ LINX_(__NR_mbind, sys_mbind), /* 235 */ LINXY(__NR_get_mempolicy, sys_get_mempolicy), /* 236 */ @@ -567,7 +567,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_finit_module, sys_finit_module), /* 273 */ LINX_(__NR_sched_setattr, sys_sched_setattr), /* 274 */ LINXY(__NR_sched_getattr, sys_sched_getattr), /* 275 */ - LINX_(__NR_renameat2, sys_renameat2), /* 276 */ + GENX_(__NR_renameat2, sys_renameat2), /* 276 */ LINXY(__NR_getrandom, sys_getrandom), /* 278 */ LINXY(__NR_memfd_create, sys_memfd_create), /* 279 */ LINXY(__NR_bpf, sys_bpf), /* 280 */ @@ -579,7 +579,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_preadv2, sys_preadv2), /* 286 */ LINX_(__NR_pwritev2, sys_pwritev2), /* 287 */ LINXY(__NR_statx, sys_statx), /* 291 */ - LINX_(__NR_io_pgetevents, sys_io_pgetevents), /* 292 */ + LINXY(__NR_io_pgetevents, sys_io_pgetevents), /* 292 */ GENX_(__NR_rseq, sys_ni_syscall), /* 293 */ LINXY(__NR_io_uring_setup, sys_io_uring_setup), /* 425 */ LINXY(__NR_io_uring_enter, sys_io_uring_enter), /* 426 */ @@ -598,7 +598,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), /* 439 */ LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), /* 441 */ LINX_(__NR_mount_setattr, sys_mount_setattr), /* 442 */ - LINX_(__NR_quotactl_fd, sys_quotactl_fd), /* 443 */ + LINXY(__NR_quotactl_fd, sys_quotactl_fd), /* 443 */ LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), /* 444 */ LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), /* 445 */ LINX_(__NR_landlock_restrict_self, sys_landlock_restrict_self), /* 446 */ @@ -608,7 +608,12 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), /* 452 */ LINXY(__NR_statmount, sys_statmount), /* 457 */ LINXY(__NR_listmount, sys_listmount), /* 458 */ + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), /* 459 */ + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), /* 460 */ + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), /* 461 */ LINX_(__NR_mseal, sys_mseal), /* 462 */ + LINXY(__NR_file_getattr, sys_file_getattr), /* 468 */ + LINX_(__NR_file_setattr, sys_file_setattr), /* 469 */ }; SyscallTableEntry* ML_(get_linux_syscall_entry)(UInt sysno) diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index c16b69731a..bda61440b7 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -568,7 +568,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_delete_module, sys_delete_module), // 129 GENX_(130, sys_ni_syscall), /* unimplemented (by the kernel) */ // 130 - LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY(__NR_quotactl, sys_quotactl), // 131 GENX_(__NR_getpgid, sys_getpgid), // 132 GENX_(__NR_fchdir, sys_fchdir), // 133 // ?????(__NR_bdflush, ), // 134 @@ -673,7 +673,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_setfsgid, sys_setfsgid), // 216 LINX_(__NR_pivot_root, sys_pivot_root), // 217 GENXY(__NR_mincore, sys_mincore), // 218 - GENX_(__NR_madvise, sys_madvise), // 219 + GENXY(__NR_madvise, sys_madvise), // 219 GENXY(__NR_getdents64, sys_getdents64), // 220 GENX_(221, sys_ni_syscall), /* unimplemented (by the kernel) */ // 221 @@ -827,7 +827,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_sched_setattr, sys_sched_setattr), // 345 LINXY(__NR_sched_getattr, sys_sched_getattr), // 346 - LINX_(__NR_renameat2, sys_renameat2), // 347 + GENX_(__NR_renameat2, sys_renameat2), // 347 // ?????(__NR_seccomp, ), // 348 LINXY(__NR_getrandom, sys_getrandom), // 349 @@ -863,7 +863,7 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_statx, sys_statx), // 379 GENX_(__NR_rseq, sys_ni_syscall), // 381 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 382 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 382 LINX_(__NR_semtimedop, sys_semtimedop), // 392 LINXY(__NR_semctl, sys_semctl), // 394 @@ -887,7 +887,7 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -900,7 +900,12 @@ static SyscallTableEntry syscall_table[] = { LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 LINXY (__NR_statmount, sys_statmount), // 457 LINXY (__NR_listmount, sys_listmount), // 458 + LINXY (__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_ (__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY (__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_ (__NR_mseal, sys_mseal), // 462 + LINXY (__NR_file_getattr, sys_file_getattr), // 468 + LINX_ (__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-solaris.c b/coregrind/m_syswrap/syswrap-solaris.c index 2665633f43..33c0bf4db6 100644 --- a/coregrind/m_syswrap/syswrap-solaris.c +++ b/coregrind/m_syswrap/syswrap-solaris.c @@ -1251,7 +1251,7 @@ PRE(sys_spawn) VKI_POSIX_SPAWN_WAITPID_NP | VKI_POSIX_SPAWN_NOEXECERR_NP); if (rem != 0) { VG_(unimplemented)("Support for spawn() with attributes flag " - "%#x.", sap->sa_psflags); + "%#x.", (unsigned)sap->sa_psflags); } } } @@ -1619,7 +1619,7 @@ PRE(sys_spawn) VG_(free)(argenv); if (SUCCESS) { - PRINT(" spawn: process %d spawned child %ld\n", VG_(getpid)(), RES); + PRINT(" spawn: process %d spawned child %lu\n", VG_(getpid)(), RES); } exit: @@ -1635,6 +1635,37 @@ PRE(sys_spawn) } #endif /* SOLARIS_SPAWN_SYSCALL */ +static Bool handle_auxv_open(SyscallStatus *status, const HChar *filename, + int flags) +{ + HChar name[30]; // large enough + + if (!ML_(safe_to_deref)((const void *) filename, 1)) + return False; + + /* Opening /proc//auxv or /proc/self/auxv? */ + VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)()); + if ((VG_(strcmp)(filename, name)!=0) && (VG_(strcmp)(filename, "/proc/self/auxv")!=0)) + return False; + + /* Allow to open the file only for reading. */ + if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) { + SET_STATUS_Failure(VKI_EACCES); + return True; + } + + VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_auxv_fd)); + SysRes sres = VG_(open)(name, flags, 0); + SET_STATUS_from_SysRes(sres); + if (!sr_isError(sres)) { + OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET); + if (off < 0) + SET_STATUS_Failure(VKI_EMFILE); + } + + return True; +} + /* Handles the case where the open is of /proc/self/psinfo or /proc//psinfo. Fetch fresh contents into psinfo_t, fake fname, psargs, argc and argv. Write the structure to the fake @@ -1651,7 +1682,7 @@ static Bool handle_psinfo_open(SyscallStatus *status, HChar name[VKI_PATH_MAX]; // large enough VG_(sprintf)(name, "/proc/%d/psinfo", VG_(getpid)()); - if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/psinfo")) + if ((VG_(strcmp)(filename, name)!=0) && (VG_(strcmp)(filename, "/proc/self/psinfo")!=0)) return False; /* Use original arguments to open() or openat(). */ @@ -1727,7 +1758,7 @@ static Bool handle_cmdline_open(SyscallStatus *status, const HChar *filename) HChar name[VKI_PATH_MAX]; // large enough VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); - if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/cmdline")) + if ((VG_(strcmp)(filename, name)!=0) && (VG_(strcmp)(filename, "/proc/self/cmdline")!=0)) return False; SysRes sres = VG_(dup)(VG_(cl_cmdline_fd)); @@ -1763,13 +1794,18 @@ PRE(sys_open) PRE_MEM_RASCIIZ("open(filename)", ARG1); - if (ML_(handle_auxv_open)(status, (const HChar*)ARG1, ARG2)) + if (handle_auxv_open(status, (const HChar*)ARG1, ARG2)) return; if (handle_psinfo_open(status, False /*use_openat*/, (const HChar*)ARG1, 0, ARG2, ARG3)) return; +#if defined(SOLARIS_PROC_CMDLINE) + if (handle_cmdline_open(status, (const HChar*)ARG1)) + return; +#endif + *flags |= SfMayBlock; } @@ -2295,7 +2331,6 @@ PRE(sys_readlinkat) /* ssize_t readlinkat(int dfd, const char *path, char *buf, size_t bufsiz); */ HChar name[30]; // large enough - Word saved = SYSNO; /* Interpret the first argument as 32-bit value even on 64-bit architecture. This is different from Linux, for example, where glibc sign-extends it. */ @@ -2317,9 +2352,15 @@ PRE(sys_readlinkat) if (ML_(safe_to_deref)((void*)ARG2, 1) && (!VG_(strcmp)((HChar*)ARG2, name) || !VG_(strcmp)((HChar*)ARG2, "/proc/self/path/a.out"))) { - VG_(sprintf)(name, "/proc/self/path/%d", VG_(cl_exec_fd)); - SET_STATUS_from_SysRes(VG_(do_syscall4)(saved, dfd, (UWord)name, ARG3, - ARG4)); + HChar* out_name = (HChar*)ARG3; + SizeT res = VG_(strlen)(VG_(resolved_exename)); + res = VG_MIN(res, ARG4); + if (ML_(safe_to_deref)(out_name, res)) { + VG_(strncpy)(out_name, VG_(resolved_exename), res); + SET_STATUS_Success(res); + } else { + SET_STATUS_Failure(VKI_EFAULT); + } } } @@ -3264,6 +3305,7 @@ PRE(sys_ioctl) PRE_MEM_WRITE("ioctl(FIOGETOWN)", ARG3, sizeof(vki_pid_t)); break; +#if defined(HAVE_SYS_CRYPTO_IOCTL_H) /* CRYPTO */ case VKI_CRYPTO_GET_PROVIDER_LIST: { @@ -3281,7 +3323,8 @@ PRE(sys_ioctl) when we know pre-handler succeeded. */ } - break; + break; +#endif /* dtrace */ case VKI_DTRACEHIOC_REMOVE: @@ -3313,9 +3356,13 @@ PRE(sys_ioctl) /* Be strict. */ if (!ML_(fd_allowed)(ARG1, "ioctl", tid, False)) { SET_STATUS_Failure(VKI_EBADF); - } else if (ARG2 == VKI_CRYPTO_GET_PROVIDER_LIST) { - /* Save the requested count to unused ARG4 now. */ - ARG4 = ARG3; + } else { +#if defined(HAVE_SYS_CRYPTO_IOCTL_H) + if (ARG2 == VKI_CRYPTO_GET_PROVIDER_LIST) { + /* Save the requested count to unused ARG4 now. */ + ARG4 = ARG3; + } +#endif } } @@ -3513,6 +3560,7 @@ POST(sys_ioctl) POST_MEM_WRITE(ARG3, sizeof(vki_pid_t)); break; +#if defined(HAVE_SYS_CRYPTO_IOCTL_H) /* CRYPTO */ case VKI_CRYPTO_GET_PROVIDER_LIST: { @@ -3527,6 +3575,7 @@ POST(sys_ioctl) sizeof(vki_crypto_provider_entry_t)); } break; +#endif /* dtrace */ case VKI_DTRACEHIOC_REMOVE: @@ -4197,7 +4246,7 @@ PRE(sys_openat) return; } - if (ML_(handle_auxv_open)(status, (const HChar *) ARG2, ARG3)) + if (handle_auxv_open(status, (const HChar *) ARG2, ARG3)) return; if (handle_psinfo_open(status, True /*use_openat*/, (const HChar *) ARG2, @@ -4969,7 +5018,7 @@ PRE(sys_getsetcontext) /* The thread is setting the ustack pointer. It is a good time to get information about its stack. */ - if (tst->os_state.ustack->ss_flags == 0) { + if (tst->os_state.ustack->ss_flags == 0 && tid != 1) { /* If the sanity check of ss_flags passed set the stack. */ set_stack(tid, tst->os_state.ustack); @@ -4982,6 +5031,18 @@ PRE(sys_getsetcontext) SET_STATUS_Success(0); } break; +#ifdef VKI_CLRSSONSTACK + case VKI_CLRSSONSTACK: + /* Libc: int clrssonstack(void); */ + SET_STATUS_Success(0); + break; +#endif +#ifdef VKI_SETUJMPBUF + case VKI_SETUJMPBUF: + /* Libc: int setujmpbuf(void *buf, void *func); */ + SET_STATUS_Success(0); + break; +#endif default: VG_(unimplemented)("Syswrap of the context call with flag %ld.", SARG1); /*NOTREACHED*/ @@ -7741,9 +7802,11 @@ POST(sys_port) case VKI_PORT_GET: POST_MEM_WRITE(ARG3, sizeof(vki_port_event_t)); break; - case VKI_PORT_GETN: - POST_MEM_WRITE(ARG3, RES * sizeof(vki_port_event_t)); + case VKI_PORT_GETN: { + UInt nget = (UInt)(RES & 0xFFFFFFFFu); + POST_MEM_WRITE(ARG3, nget * sizeof(vki_port_event_t)); break; + } case VKI_PORT_ALERT: case VKI_PORT_DISPATCH: break; @@ -10951,7 +11014,7 @@ static SyscallTableEntry syscall_table[] = { SOLXY(__NR_lwp_mutex_wakeup, sys_lwp_mutex_wakeup), /* 168 */ SOLXY(__NR_lwp_cond_wait, sys_lwp_cond_wait), /* 170 */ SOLXY(__NR_lwp_cond_signal, sys_lwp_cond_signal), /* 171 */ - SOLX_(__NR_lwp_cond_broadcast, sys_lwp_cond_broadcast), /* 172 */ + SOLXY(__NR_lwp_cond_broadcast, sys_lwp_cond_broadcast), /* 172 */ SOLXY(__NR_pread, sys_pread), /* 173 */ SOLX_(__NR_pwrite, sys_pwrite), /* 174 */ #if defined(VGP_x86_solaris) diff --git a/coregrind/m_syswrap/syswrap-x86-darwin.c b/coregrind/m_syswrap/syswrap-x86-darwin.c index 7459ef83a2..a0bc1a1e7a 100644 --- a/coregrind/m_syswrap/syswrap-x86-darwin.c +++ b/coregrind/m_syswrap/syswrap-x86-darwin.c @@ -195,7 +195,7 @@ ThreadState *build_thread(const thread_state_t state, // Edit the thread state to send to the real kernel. // The real thread will run start_thread_NORETURN(tst) // on a separate non-client stack. -void hijack_thread_state(thread_state_t mach_generic, +void hijack_thread_state(thread_state_t mach_generic, thread_state_flavor_t flavor, mach_msg_type_number_t count, ThreadState *tst) @@ -271,7 +271,7 @@ asm( -void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, +void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, Addr stacksize, Addr flags, Addr sp) { vki_sigset_t blockall; @@ -358,6 +358,7 @@ asm( " push $0\n" // alignment " push $0\n" // alignment " push %ebp\n" // original sp +" push %esi\n" // kevent_count " push %edi\n" // reuse " push %edx\n" // workitem " push %ecx\n" // stackaddr @@ -376,7 +377,7 @@ asm( thread for every work item. */ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, - Int reuse, Addr sp) + UInt reuse, Int kevent_count, Addr sp) { ThreadState *tst; VexGuestX86State *vex; @@ -396,8 +397,8 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, if (0) VG_(printf)( "wqthread_hijack: self %#lx, kport %#lx, " - "stackaddr %#lx, workitem %#lx, reuse/flags %x, sp %#lx\n", - self, kport, stackaddr, workitem, reuse, sp); + "stackaddr %#lx, workitem %#lx, reuse/flags %x, kevent_count %d, sp %#lx\n", + self, kport, stackaddr, workitem, reuse, kevent_count, sp); /* Start the thread with all signals blocked. VG_(scheduler) will set the mask correctly when we finally get there. */ @@ -429,7 +430,8 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, || DARWIN_VERS == DARWIN_10_10 \ || DARWIN_VERS == DARWIN_10_11 \ || DARWIN_VERS == DARWIN_10_12 \ - || DARWIN_VERS == DARWIN_10_13 + || DARWIN_VERS == DARWIN_10_13 \ + || DARWIN_VERS == DARWIN_10_14 UWord magic_delta = 0xB0; # else # error "magic_delta: to be computed on new OS version" @@ -452,6 +454,10 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, tid, tst, tst->os_state.pthread, self); vex = &tst->arch.vex; + if (tst->os_state.pthread - magic_delta != self) { + VG_(printf)("wqthread_hijack reuse: tst->os_state.pthread %#lx vs self %#lx (diff: %#lx vs %#lx)\n", + tst->os_state.pthread, self, tst->os_state.pthread - self, magic_delta); + } vg_assert(tst->os_state.pthread - magic_delta == self); } else { @@ -471,7 +477,7 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, vex->guest_ECX = stackaddr; vex->guest_EDX = workitem; vex->guest_EDI = reuse; - vex->guest_ESI = 0; + vex->guest_ESI = kevent_count; vex->guest_ESP = sp; stacksize = 512*1024; // wq stacks are always DEFAULT_STACK_SIZE diff --git a/coregrind/m_syswrap/syswrap-x86-freebsd.c b/coregrind/m_syswrap/syswrap-x86-freebsd.c index 1bb3d6fed2..44524e7f05 100644 --- a/coregrind/m_syswrap/syswrap-x86-freebsd.c +++ b/coregrind/m_syswrap/syswrap-x86-freebsd.c @@ -9,7 +9,7 @@ Copyright (C) 2000-2008 Nicholas Nethercote njn@valgrind.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -1258,7 +1258,7 @@ PRE(sys_posix_fallocate) vki_uint32_t, MERGE64_FIRST(len), vki_uint32_t, MERGE64_SECOND(len)); if (!ML_(fd_allowed)(ARG1, "posix_fallocate", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_posix_fadvise 531 @@ -1274,7 +1274,7 @@ PRE(sys_posix_fadvise) vki_uint32_t, MERGE64_SECOND(len), int, advice); if (!ML_(fd_allowed)(ARG1, "posix_fadvise", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + SET_STATUS_FailureErrorCode(VKI_EBADF); } // SYS_wait6 532 @@ -1434,6 +1434,18 @@ PRE(sys_cpuset_setdomain) PRE_MEM_READ( "cpuset_getdomain(mask)", ARG6, ARG5 ); } +// SYS_kexec_load 599 +// int kexec_load(uint64_t entry, unsigned long count, +// struct kexec_segment *segments, unsigned long flags); +PRE(sys_kexec_load) +{ + PRINT("sys_kexec_load ( %llx, %" FMT_REGWORD "u, %" FMT_REGWORD "x, %" FMT_REGWORD "u )", MERGE64(ARG1, ARG2), ARG3, ARG4, ARG5); + PRE_REG_READ5(int, "kexec_load", vki_uint32_t, MERGE64_FIRST(entry), vki_uint32_t, MERMERGE64_SECOND(entry), + unsigned long, count, struct kexec_segment*, segments, unsigned long, flag); + PRE_MEM_READ("kexec_load(segments)", ARG4, ARG3*(sizeof(struct vki_kexec_segment))); + // FIXME PJF should check the buf and bufsz fields +} + PRE(sys_fake_sigreturn) { /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 423feac568..6f727dc58c 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1316,7 +1316,7 @@ static SyscallTableEntry syscall_table[] = { //zz //zz // Nb: get_kernel_syms() was removed 2.4-->2.6 GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 - LINX_(__NR_quotactl, sys_quotactl), // 131 + LINXY(__NR_quotactl, sys_quotactl), // 131 GENX_(__NR_getpgid, sys_getpgid), // 132 GENX_(__NR_fchdir, sys_fchdir), // 133 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux @@ -1422,7 +1422,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_setfsgid32, sys_setfsgid), // 216 LINX_(__NR_pivot_root, sys_pivot_root), // 217 GENXY(__NR_mincore, sys_mincore), // 218 - GENX_(__NR_madvise, sys_madvise), // 219 + GENXY(__NR_madvise, sys_madvise), // 219 GENXY(__NR_getdents64, sys_getdents64), // 220 LINXY(__NR_fcntl64, sys_fcntl64), // 221 @@ -1583,7 +1583,7 @@ static SyscallTableEntry syscall_table[] = { // LIN__(__NR_finit_module, sys_ni_syscall), // 350 LINX_(__NR_sched_setattr, sys_sched_setattr), // 351 LINXY(__NR_sched_getattr, sys_sched_getattr), // 352 - LINX_(__NR_renameat2, sys_renameat2), // 353 + GENX_(__NR_renameat2, sys_renameat2), // 353 // LIN__(__NR_seccomp, sys_ni_syscall), // 354 LINXY(__NR_getrandom, sys_getrandom), // 355 @@ -1621,16 +1621,16 @@ static SyscallTableEntry syscall_table[] = { /* Explicitly not supported on i386 yet. */ GENX_(__NR_arch_prctl, sys_ni_syscall), // 384 - LINX_(__NR_io_pgetevents, sys_io_pgetevents), // 385 + LINXY(__NR_io_pgetevents, sys_io_pgetevents), // 385 GENX_(__NR_rseq, sys_ni_syscall), // 386 LINX_(__NR_semget, sys_semget), // 393 LINXY(__NR_semctl, sys_semctl), // 394 LINX_(__NR_shmget, sys_shmget), // 395 - LINX_(__NR_shmctl, sys_shmctl), // 396 - LINX_(__NR_shmat, sys_shmat), // 397 - LINX_(__NR_shmdt, sys_shmdt), // 398 + LINXY(__NR_shmctl, sys_shmctl), // 396 + LINXY(__NR_shmat, sys_shmat), // 397 + LINXY(__NR_shmdt, sys_shmdt), // 398 LINX_(__NR_msgget, sys_msgget), // 399 LINX_(__NR_msgsnd, sys_msgsnd), // 400 @@ -1677,7 +1677,7 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 - LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 + LINXY(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), // 445 @@ -1690,7 +1690,12 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 LINXY(__NR_statmount, sys_statmount), // 457 LINXY(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_lsm_get_self_attr, sys_lsm_get_self_attr), // 459 + LINX_(__NR_lsm_set_self_attr, sys_lsm_set_self_attr), // 460 + LINXY(__NR_lsm_list_modules, sys_lsm_list_modules), // 461 LINX_(__NR_mseal, sys_mseal), // 462 + LINXY(__NR_file_getattr, sys_file_getattr), // 468 + LINX_(__NR_file_setattr, sys_file_setattr), // 469 }; SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) diff --git a/coregrind/m_syswrap/syswrap-xen.c b/coregrind/m_syswrap/syswrap-xen.c index e9f844e0d5..5abf6a992f 100644 --- a/coregrind/m_syswrap/syswrap-xen.c +++ b/coregrind/m_syswrap/syswrap-xen.c @@ -2519,7 +2519,7 @@ static void bad_before ( ThreadId tid, /*OUT*/UWord* flags ) { VG_(dmsg)("WARNING: unhandled hypercall: %s\n", - VG_SYSNUM_STRING(args->sysno)); + VG_SYSNUM_STRING(args->canonical_sysno)); if (VG_(clo_verbosity) > 1) { VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); } diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S index 0746fd0f18..cc6145a81f 100644 --- a/coregrind/m_trampoline.S +++ b/coregrind/m_trampoline.S @@ -144,8 +144,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------------- amd64-linux ----------------------*/ -#else -#if defined(VGP_amd64_linux) +#elif defined(VGP_amd64_linux) # define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2 # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -356,8 +355,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- ppc32-linux ----------------*/ -#else -#if defined(VGP_ppc32_linux) +#elif defined(VGP_ppc32_linux) # define UD2_16 trap ; trap ; trap; trap # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -479,8 +477,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- ppc64-linux ----------------*/ -#else -#if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) +#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) # define UD2_16 trap ; trap ; trap; trap # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -662,8 +659,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- arm-linux ----------------*/ -#else -#if defined(VGP_arm_linux) +#elif defined(VGP_arm_linux) # define UD2_4 .word 0xFFFFFFFF # define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4 @@ -839,8 +835,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- arm64-linux ----------------*/ -#else -#if defined(VGP_arm64_linux) +#elif defined(VGP_arm64_linux) # define UD2_4 .word 0xFFFFFFFF # define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4 @@ -939,8 +934,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- x86-freebsd ----------------*/ -#else -#if defined(VGP_x86_freebsd) +#elif defined(VGP_x86_freebsd) .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): @@ -960,15 +954,14 @@ VG_(x86_freebsd_SUBST_FOR_sigreturn): pushl %eax pushl %eax /* fake return addr */ /* movl 0x44(%eax), %gs ; restore %gs, not done by sigreturn */ - movl $__NR_fake_sigreturn, %eax + movl $__NR_freebsd_fake_sigreturn, %eax int $0x80 ud2 .global VG_(trampoline_stuff_end) VG_(trampoline_stuff_end): -#else -#if defined(VGP_amd64_freebsd) +#elif defined(VGP_amd64_freebsd) # define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2 # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -987,7 +980,7 @@ VG_(amd64_freebsd_SUBST_FOR_sigreturn): /* This is a very specific sequence which GDB uses to recognize signal handler frames. */ - movq $__NR_fake_sigreturn, %rax + movq $__NR_freebsd_fake_sigreturn, %rax /* running the preprocessor on * src/amd64.amd64/lib/libc/sigreturn.S @@ -1027,8 +1020,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- arm64-freebsd ----------------*/ -#else -#if defined(VGP_arm64_freebsd) +#elif defined(VGP_arm64_freebsd) # define UD2_4 .word 0xFFFFFFFF # define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4 @@ -1046,7 +1038,7 @@ VG_(trampoline_stuff_start): .global VG_(arm64_freebsd_SUBST_FOR_sigreturn) .type VG_(arm64_freebsd_SUBST_FOR_sigreturn),#function VG_(arm64_freebsd_SUBST_FOR_sigreturn): - mov x8, # __NR_fake_sigreturn + mov x8, # __NR_freebsd_fake_sigreturn mov x0, sp svc #0 .long 0xFFFFFFFF /*illegal insn*/ @@ -1069,8 +1061,7 @@ VG_(trampoline_stuff_end): /*---------------- x86-darwin ----------------*/ -#else -#if defined(VGP_x86_darwin) +#elif defined(VGP_x86_darwin) /* a leading page of unexecutable code */ .fill 2048, 2, 0x0b0f /* `ud2` */ @@ -1082,7 +1073,7 @@ VG_(trampoline_stuff_start): VG_(x86_darwin_SUBST_FOR_sigreturn): /* XXX does this need to have any special form? (cf x86-linux version) */ - movl $ __NR_DARWIN_FAKE_SIGRETURN, %eax + movl $ __NR_darwin_fake_sigreturn, %eax int $0x80 ud2 @@ -1229,8 +1220,7 @@ VG_(trampoline_stuff_end): /*---------------- amd64-darwin ----------------*/ -#else -#if defined(VGP_amd64_darwin) +#elif defined(VGP_amd64_darwin) /* a leading page of unexecutable code */ .fill 2048, 2, 0x0b0f /* `ud2` */ @@ -1242,7 +1232,7 @@ VG_(trampoline_stuff_start): VG_(amd64_darwin_SUBST_FOR_sigreturn): /* XXX does this need to have any special form? (cf x86-linux version) */ - movq $ __NR_DARWIN_FAKE_SIGRETURN, %rax + movq $ __NR_darwin_fake_sigreturn, %rax syscall ud2 @@ -1391,6 +1381,21 @@ VG_(amd64_darwin_REDIR_FOR_strchr): 2: popq %rbp ret + +.globl VG_(amd64_darwin_REDIR_FOR_bcmp) +VG_(amd64_darwin_REDIR_FOR_bcmp): + xorl %eax, %eax + xorl %ecx, %ecx +1: + cmpq %rcx, %rdx + je 2f + movzbl (%rdi,%rcx), %r8d + cmpb (%rsi,%rcx), %r8b + leaq 1(%rcx), %rcx + je 1b + movl $1, %eax +2: + ret .globl VG_(trampoline_stuff_end) VG_(trampoline_stuff_end): @@ -1400,8 +1405,7 @@ VG_(trampoline_stuff_end): /*---------------- s390x-linux ----------------*/ -#else -#if defined(VGP_s390x_linux) +#elif defined(VGP_s390x_linux) /* a leading page of unexecutable code */ .fill 2048, 2, 0x0000 @@ -1455,8 +1459,7 @@ VG_(trampoline_stuff_end): .fill 2048, 2, 0x0000 /*---------------------- mips32-linux ----------------------*/ -#else -#if defined(VGP_mips32_linux) +#elif defined(VGP_mips32_linux) # define UD2_16 trap ; trap ; trap; trap # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -1532,8 +1535,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------------- nanomips-linux --------------------*/ -#else -#if defined(VGP_nanomips_linux) +#elif defined(VGP_nanomips_linux) .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): @@ -1581,8 +1583,7 @@ VG_(trampoline_stuff_end): /*---------------------- mips64-linux ----------------------*/ -#else -#if defined(VGP_mips64_linux) +#elif defined(VGP_mips64_linux) # define UD2_16 trap ; trap ; trap; trap # define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 @@ -1650,8 +1651,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- riscv64-linux ----------------*/ -#else -#if defined(VGP_riscv64_linux) +#elif defined(VGP_riscv64_linux) # define UD2_4 .word 0 # define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4 @@ -1742,8 +1742,7 @@ VG_(trampoline_stuff_end): # undef UD2_PAGE /*---------------- x86-solaris ----------------*/ -#else -#if defined(VGP_x86_solaris) +#elif defined(VGP_x86_solaris) .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): @@ -1796,8 +1795,7 @@ VG_(x86_solaris_REDIR_FOR_strlen): VG_(trampoline_stuff_end): /*---------------- amd64-solaris ----------------*/ -#else -#if defined(VGP_amd64_solaris) +#elif defined(VGP_amd64_solaris) .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): @@ -1924,23 +1922,6 @@ VG_(trampoline_stuff_end): #else # error Unknown platform -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif #endif /* Let the linker know we don't need an executable stack */ diff --git a/coregrind/m_ume/elf.c b/coregrind/m_ume/elf.c index 20e0185cb4..3213874b8d 100644 --- a/coregrind/m_ume/elf.c +++ b/coregrind/m_ume/elf.c @@ -658,7 +658,6 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info) if (sr_isError(sres)) #endif sres = VG_(open)(buf, VKI_O_RDONLY, 0); - //sres = VG_(open)("/usr/home/paulf/build/src/obj/usr/home/paulf/build/src/amd64.amd64/libexec/rtld-elf/ld-elf.so.1.full", VKI_O_RDONLY, 0); if (sr_isError(sres)) { VG_(printf)("valgrind: m_ume.c: can't open interpreter\n"); VG_(exit)(1); diff --git a/coregrind/m_ume/macho.c b/coregrind/m_ume/macho.c index ec7257084e..536eef261e 100644 --- a/coregrind/m_ume/macho.c +++ b/coregrind/m_ume/macho.c @@ -42,6 +42,7 @@ #include "pub_core_mallocfree.h" // VG_(malloc), VG_(free) #include "pub_core_syscall.h" // VG_(strerror) #include "pub_core_clientstate.h" +#include "pub_core_options.h" #include "pub_core_ume.h" // self #include "priv_ume.h" @@ -74,6 +75,7 @@ typedef struct load_info_t { vki_uint8_t *linker_entry; // dylinker entry point Addr linker_offset; // dylinker text offset vki_size_t max_addr; // biggest address reached while loading segments + Addr text_slide; // slide of the text segment because of "ASLR" (arm64-only) } load_info_t; static void print(const HChar *str) @@ -180,7 +182,7 @@ load_segment(int fd, vki_off_t offset, vki_off_t size, vki_size_t vmsize; // page-aligned vki_size_t vmend; // page-aligned unsigned int prot; - Addr slided_addr = segcmd->vmaddr + out_info->linker_offset; + Addr slided_addr = segcmd->vmaddr + out_info->linker_offset + out_info->text_slide; // GrP fixme mark __UNIXSTACK as SF_STACK @@ -243,7 +245,7 @@ load_segment(int fd, vki_off_t offset, vki_off_t size, vmsize = VG_PGROUNDUP(segcmd->vmsize); if (filesize > 0) { addr = slided_addr; - VG_(debugLog)(2, "ume", "mmap fixed (file) (%#lx, %lu)\n", addr, filesize); + VG_(debugLog)(2, "ume", "mmap fixed (file) (%#lx, %lu, %x)\n", addr, filesize, prot); res = VG_(am_mmap_named_file_fixed_client)(addr, filesize, prot, fd, offset + segcmd->fileoff, filename); @@ -260,7 +262,7 @@ load_segment(int fd, vki_off_t offset, vki_off_t size, // page-aligned part SizeT length = vmsize - filesize; addr = (Addr)(filesize + slided_addr); - VG_(debugLog)(2, "ume", "mmap fixed (anon) (%#lx, %lu)\n", addr, length); + VG_(debugLog)(2, "ume", "mmap fixed (anon) (%#lx, %lu, %u)\n", addr, length, prot); res = VG_(am_mmap_anon_fixed_client)(addr, length, prot); check_mmap(res, addr, length, "load_segment2"); } @@ -348,10 +350,22 @@ load_genericthread(struct thread_command *threadcmd, int type, GrP fixme 64-bit? */ static vki_size_t default_stack_size(void) { - struct vki_rlimit lim; - int err = VG_(getrlimit)(VKI_RLIMIT_STACK, &lim); - if (err) return 8*1024*1024; // 8 MB - else return lim.rlim_cur; + SizeT m1 = 1024 * 1024; + SizeT m16 = 16 * m1; + SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur; + if (szB < m1) { + szB = m1; + } + if (szB > m16) { + szB = m16; + } + if (VG_(clo_main_stacksize) > 0) { + szB = VG_(clo_main_stacksize); + } + if (szB < m1) { + szB = m1; + } + return szB; } @@ -449,6 +463,7 @@ load_dylinker(struct dylinker_command *dycmd, load_info_t *out_info) linker_info.entry = NULL; linker_info.linker_entry = NULL; linker_info.linker_offset = 0; + linker_info.text_slide = 0; linker_info.max_addr = out_info->max_addr; if (dycmd->name.offset >= dycmd->cmdsize) { @@ -816,7 +831,7 @@ Bool VG_(match_macho)(const void *hdr, SizeT len) // GrP fixme check more carefully for matching fat arch? - return (len >= VKI_PAGE_SIZE && + return (len >= sizeof(*magic) && (*magic == MAGIC || *magic == VG_(ntohl)(FAT_MAGIC))) ? True : False; } @@ -834,6 +849,7 @@ Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info) load_info.linker_entry = NULL; load_info.linker_offset = 0; load_info.max_addr = 0; + load_info.text_slide = 0; err = VG_(fstat)(fd, &sb); if (err) { @@ -856,7 +872,12 @@ Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info) info->text = (Addr) load_info.text; info->dynamic = load_info.linker_entry ? True : False; - info->executable_path = VG_(strdup)("ume.macho.executable_path", name); + if (!info->dynamic && load_info.text_slide) { + print("cannot slide static executables\n"); + return VKI_ENOEXEC; + } + + info->executable_path = VG_(strdup)("ume.macho.load_macho", name); SysRes res = VG_(dup)(fd); if (!sr_isError(res)) diff --git a/coregrind/m_ume/main.c b/coregrind/m_ume/main.c index bca641eb25..21e64592a0 100644 --- a/coregrind/m_ume/main.c +++ b/coregrind/m_ume/main.c @@ -161,7 +161,7 @@ static Bool is_hash_bang_file(const HChar* f) HChar buf[3] = {0,0,0}; Int fd = sr_Res(res); Int n = VG_(read)(fd, buf, 2); - if (n == 2 && VG_STREQ("#!", buf)) + if (n == 2 && (VG_(strcmp)(buf, "#!")==0)) return True; } return False; diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h index 070fa54951..ee6598886f 100644 --- a/coregrind/pub_core_aspacemgr.h +++ b/coregrind/pub_core_aspacemgr.h @@ -119,6 +119,11 @@ extern void VG_(am_show_nsegments) ( Int logLevel, const HChar* who ); extern Bool VG_(am_do_sync_check) ( const HChar* fn, const HChar* file, Int line ); +/* VG_(is_guarded) checks if address is part of a madvise + MADV_GUARD_INSTALL guard page */ +extern Bool VG_(is_guarded) ( Addr addr ); + + //-------------------------------------------------------------- // Functions pertaining to the central query-notify mechanism // used to handle mmap/munmap/mprotect resulting from client @@ -187,6 +192,9 @@ extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot ); range. */ extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot ); +/* Bug 514297: Notifies aspacem about madvise(MADV_GUARD_*) */ +extern Bool VG_(am_notify_madv_guard) ( Addr start, SizeT len, Bool install ); + /* Notifies aspacem that an munmap completed successfully. The segment array is updated accordingly. As with VG_(am_notify_mprotect), we merely record the given info, and don't diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h index ad484c4c27..68ffed841e 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -76,6 +76,10 @@ extern void VG_(di_notify_pdb_debuginfo)( Int fd, Addr avma, extern void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ); #endif +#if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_11_00 +extern ULong VG_(di_notify_dsc)( const HChar* path, Addr header, SizeT len ); +#endif + extern void VG_(addr_load_di)( Addr a ); extern void VG_(di_load_di)( DebugInfo *di ); diff --git a/coregrind/pub_core_initimg.h b/coregrind/pub_core_initimg.h index 40ef71d049..dcb45cf87e 100644 --- a/coregrind/pub_core_initimg.h +++ b/coregrind/pub_core_initimg.h @@ -117,6 +117,9 @@ struct _IIFinaliseImageInfo { Addr initial_client_SP; /* ------ Per-OS fields ------ */ Addr initial_client_IP; +#if defined(VGO_darwin) + Bool dynamic; /* False iff executable is static */ +#endif }; /* ------------------------- Solaris ------------------------- */ diff --git a/coregrind/pub_core_mach.h b/coregrind/pub_core_mach.h index 8ab46417a2..cbce0309ad 100644 --- a/coregrind/pub_core_mach.h +++ b/coregrind/pub_core_mach.h @@ -31,14 +31,53 @@ #ifndef __PUB_CORE_MACH_H #define __PUB_CORE_MACH_H +#define DARWIN_FAKE_MEMORY_PATH "/dev/macos/internals/" + //-------------------------------------------------------------------- -// PURPOSE: This module contains the Mach kernel interface, +// PURPOSE: This module contains the Mach kernel interface, // for operating systems like Darwin / Mac OS X that use it. //-------------------------------------------------------------------- // Call this early in Valgrind's main(). It depends on nothing. extern void VG_(mach_init)(void); +// Record system memory after aspace has been init'd +extern void VG_(mach_record_system_memory)(void); + +// MACH_DSC_END represent a guess to where the dyld shared cache ends +// there is no way to know for sure and even if we could, +// it would be a pain to carry that value around all of V +// so we just use a guess and hope for the best. +// Why is this value needed? +// We only use it in a single context: when reading the dyld shared cache directly from memory +// we use it as a bound when reading symbols with DebugInfo. +// How is this value calculated? +// - amd64: end of user addressable space, which makes sense as the DSC is mapped at the end of the address space +// - x86: end of user addressable space, note that there should not be any x86 valgrind with DSC support so this is just a placeholder +// - arm64: +// - the DSC is mapped at 0x180000000 + some ASLR slider +// - the size depends on the macOS version but is usually less than 0xFFFFFFFF +// - thus it should be around 0x280000000 but I have seen it reach above +// - thus we use 0x300000000 which is also where we tell V that client memory starts +#if defined(VGP_amd64_darwin) +#define MACH_DSC_END 0x7ffffffff000 +#elif defined(VGP_x86_darwin) +#define MACH_DSC_END 0xfffff000 +#elif defined(VGP_arm64_darwin) +#define MACH_DSC_END 0x300000000 +#else +#error "Unsupported platform" +#endif + +#if DARWIN_VERS >= DARWIN_11_00 +// Dyld shared cache (DSC) parsing, which is required as system libraries are not provided on disk +// starting with macOS 11.0 (Big Sur) +extern void VG_(dyld_cache_init)(const HChar*); +extern int VG_(dyld_cache_might_be_in)(const HChar*); +extern int VG_(dyld_cache_load_library)(const HChar*); +extern Addr VG_(dyld_cache_get_slide)(void); +#endif + #endif // __PUB_CORE_MACH_H #endif // defined(VGO_darwin) diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index 945a96c279..9b62caaaa3 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -330,6 +330,12 @@ extern Word VG_(clo_main_stacksize); #define MAX_THREADS_DEFAULT 500 extern UInt VG_(clo_max_threads); +/* The maximum number of madvise guard pages we support. */ +#if defined(VGO_linux) +#define MAX_GUARDS_DEFAULT 500 +extern UInt VG_(clo_max_guard_pages); +#endif + /* If the same IP is found twice in a backtrace in a sequence of max VG_(clo_merge_recursive_frames) frames, then the recursive call is merged in the backtrace. diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h index 2ca144211b..67875ff4c6 100644 --- a/coregrind/pub_core_trampoline.h +++ b/coregrind/pub_core_trampoline.h @@ -143,6 +143,8 @@ extern void* VG_(amd64_darwin_REDIR_FOR_strcat)( void*, void * ); extern char* VG_(amd64_darwin_REDIR_FOR_strcpy)( char *s1, char *s2 ); extern SizeT VG_(amd64_darwin_REDIR_FOR_strlcat)( char *s1, const char *s2, SizeT size ); +extern SizeT VG_(amd64_darwin_REDIR_FOR_bcmp)( const void *s1, const void *s2, + SizeT len ); extern UInt VG_(amd64_darwin_REDIR_FOR_arc4random)( void ); # if DARWIN_VERS == DARWIN_10_9 extern char* VG_(amd64_darwin_REDIR_FOR_strchr)( const char*, int ); diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c index 0b77e0537f..4215382705 100644 --- a/coregrind/vg_preloaded.c +++ b/coregrind/vg_preloaded.c @@ -188,19 +188,75 @@ static void env_unsetenv ( HChar **env, const HChar *varname ) } } *(to++) = *(from++); + /* fix the 4th "char* apple" pointer (aka. executable path pointer) */ *(to++) = *(from++); + +#if DARWIN_VERS < DARWIN_12_00 + /* We only do this on older versions of darwin because dyld changed + and by the point we do this changes, the apple env ptr is already set, + so if we move values around, we'll end up with a pointer pointing inside + (and even potentially after) applep. + + Instead we copy the first value of the applelp over and over again + so that envp and applep are still separated by NULL, + applep is continuous and points to a correct value. + + See the following example, using the following envp and applep: + + ``` + 0xXXXX00: PATH=/bin (envp) + 0xXXXX08: DYLD_INSERT_LIBRARIES=/lib + 0xXXXX10: USER=foo + 0xXXXX18: NULL + 0xXXXX20: executable_path=/bin/ls (applep) + 0xXXXX28: NULL + ``` + + # With this line + + ``` + 0xXXXX00: PATH=/bin (envp) + 0xXXXX08: USER=foo + 0xXXXX10: NULL + 0xXXXX18: executable_path=/bin/ls + 0xXXXX20: NULL (applep) + 0xXXXX28: NULL + ``` + + Notice that the applep is now invalid. + + # Without this line + + ``` + 0xXXXX00: PATH=/bin (envp) + 0xXXXX08: USER=foo + 0xXXXX10: NULL + 0xXXXX18: executable_path=/bin/ls + 0xXXXX20: executable_path=/bin/ls (applep) + 0xXXXX28: NULL + ``` + + Notice that while values in applep are duplicated, this is only the case if browsing frop envp[len+1] + but not from applep which is always valid. Duplicated values are also harmless in this case. + */ *to = NULL; +#endif } +// FIXME PJF to we really need this? +// We already do env cleanup before any exec static void vg_cleanup_env(void) __attribute__((constructor)); static void vg_cleanup_env(void) { HChar **envp = (HChar**)*_NSGetEnviron(); - env_unsetenv(envp, "VALGRIND_LAUNCHER"); +#if DARWIN_VERS < DARWIN_11_00 env_unsetenv(envp, "DYLD_SHARED_REGION"); +#endif // GrP fixme should be more like mash_colon_env() env_unsetenv(envp, "DYLD_INSERT_LIBRARIES"); + // FIXME PJF on macOS >= 10.15 we also insert PTHREAD_PTR_MUNGE_TOKEN + // should we remove it here? } /* --------------------------------------------------------------------- diff --git a/coregrind/vgdb-invoker-freebsd.c b/coregrind/vgdb-invoker-freebsd.c index ec42ab23ad..0db6740238 100644 --- a/coregrind/vgdb-invoker-freebsd.c +++ b/coregrind/vgdb-invoker-freebsd.c @@ -7,7 +7,7 @@ framework. Copyright (C) 2011-2017 Philippe Waroquiers - Copyright (C) 2021-2022 Paul Floyd + Copyright (C) 2021-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -203,10 +203,10 @@ Bool waitstopped (pid_t pid, int signal_expected, const char *msg) msg, signal_expected); p = waitpid(pid, &status, 0); /* PJF options was __WALL */ DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p, - status, status_image (status)); + (unsigned)status, status_image (status)); if (p != pid) { ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n", - msg, pid, p, status, status_image (status)); + msg, pid, p, (unsigned)status, status_image (status)); return False; } @@ -468,7 +468,7 @@ Bool invoker_invoke_gdbserver (pid_t pid) e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */ *(long *)®_save.r_rax = *(int*)®_save.r_rax; DEBUG(1, "Sign extending %8.8lx to %8.8lx\n", - reg_mod.r_rax, reg_save.r_rax); + (unsigned long)reg_mod.r_rax, (unsigned long)reg_save.r_rax); } #elif defined(VGA_arm64) sp = reg_mod.sp; diff --git a/darwin-drd.supp b/darwin-drd.supp new file mode 100644 index 0000000000..55ca1dd247 --- /dev/null +++ b/darwin-drd.supp @@ -0,0 +1,475 @@ +# DRD suppressions for Darwin 10.x / Mac OS X 10.6 Snow Leopard + +# +# dyld +# +{ + dyld_mutex_not_locked + drd:MutexErr + fun:pthread_mutex_unlock + fun:_dyld_register_func_for_*_image +} +{ + dyld_mutex_reinitialization + drd:MutexErr + fun:pthread_mutex_init + fun:_Z24dyldGlobalLockInitializev + fun:_dyld_initializer +} +{ + dyld_stub_binder + drd:ConflictingAccess + ... + fun:_ZN4dyld18fastBindLazySymbolEPP11ImageLoaderm + fun:dyld_stub_binder +} +{ + dyld ImageLoaderMachOCompressed::findExportedSymbol(char const*, ImageLoader const**) const + drd:ConflictingAccess + fun:_ZNK26ImageLoaderMachOCompressed18findExportedSymbolEPKcPPK11ImageLoader +} +{ + dyld dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + drd:ConflictingAccess + ... + fun:_ZN4dyld18fastBindLazySymbolEPP11ImageLoaderm +} +{ + dyld ImageLoaderMachOCompressed::doBindFastLazySymbol(unsigned int, ImageLoader::LinkContext const&) + drd:ConflictingAccess + ... + fun:_ZN26ImageLoaderMachOCompressed20doBindFastLazySymbolEjRKN11ImageLoader11LinkContextE +} + +# +# C library +# +{ + __umodti3 + drd:ConflictingAccess + fun:__umodti3 +} +{ + fork() + drd:ConflictingAccess + ... + fun:_cthread_fork_child + fun:fork +} +{ + flockfile + drd:ConflictingAccess + fun:flockfile +} +{ + funlockfile + drd:ConflictingAccess + fun:funlockfile +} +{ + vfprintf_l + drd:ConflictingAccess + fun:vfprintf_l +} +{ + localeconv_l + drd:ConflictingAccess + fun:localeconv_l +} +{ + __vfprintf + drd:ConflictingAccess + fun:__vfprintf +} +{ + fflush + drd:ConflictingAccess + fun:fflush +} +{ + cerror + drd:ConflictingAccess + ... + fun:cerror +} +{ + do_rand + drd:ConflictingAccess + fun:do_rand +} +{ + mig_dealloc_reply_port + drd:ConflictingAccess + fun:mig_dealloc_reply_port +} + +{ + OSX1013:drd:nanosleep + drd:ConflictingAccess + fun:nanosleep +} + +# +# pthread library +# + +{ + OSX1013:drd:pthread library + drd:ConflictingAccess + obj:/usr/lib/system/libsystem_pthread.dylib +} + +{ + OSX1013:std::timed_mutex::unlock + drd:ConflictingAccess + fun:_ZNSt3__111timed_mutex6unlockEv +} +{ + std::timed_mutex::try_lock_until + drd:ConflictingAccess + fun:_ZNSt3__111timed_mutex14try_lock_untilINS_6chrono12steady_clockENS2_8durationIxNS_5ratio* +} +{ + OSX1013:mach_timebase_info + drd:ConflictingAccess + fun:mach_timebase_info +} +# take care with this, don't want to suppress anything in user +# thread functions +{ + OSX1013:_pthread_body + drd:ConflictingAccess + fun:_pthread_body +} + +# various getaddrinfo suppressions +{ + OSX1013:exit + drd:ConflictingAccess + ... + fun:exit +} + +{ + OSX1013:freeaddrinfo + drd:ConflictingAccess + fun:freeaddrinfo +} + +{ + OSX1013:getaddrinfo + drd:ConflictingAccess + ... + fun:getaddrinfo +} + +{ + OSX1013:drd:si_addrinfo + drd:ConflictingAccess + ... + fun:si_addrinfo +} + +{ + OSX1013:cache_fill + drd:ConflictingAccess + fun:_ZN7cache_t10reallocateEjj + fun:cache_fill +} +{ + OSX1013:os_unfair_lock + drd:ConflictingAccess + ... + fun:*os_unfair_lock* +} +{ + OSX1013:objc_msgSend + drd:ConflictingAccess + fun:objc_msgSend +} +{ + OSX1013:cache_fill + drd:ConflictingAccess + fun:cache_fill +} +{ + OSX1013:_nc_table + drd:ConflictingAccess + fun:_nc_table_* +} + +{ + OSX1013:drd:xpc_dictionary_apply + drd:ConflictingAccess + ... + fun:xpc_dictionary_apply +} + +{ + OSX1013:drd:getaddrinfo + drd:ConflictingAccess + ... + fun:getaddrinfo +} + +{ + OSX1013:drd:xpc_create_from_plist + drd:ConflictingAccess + ... + fun:xpc_create_from_plist +} + +{ + OSX1013:helgrind:nw_path_copy_interface_with_generation_internal + drd:ConflictingAccess + ... + fun:nw_path_copy_interface_with_generation_internal +} + +{ + OSX1013:helgrind:sem_trywait + Helgrind:Race + fun:sem_trywait +} + +{ + OSX1013:drd:object_dispose + drd:ConflictingAccess + ... + fun:object_dispose +} + +{ + OSX1013:drd:dispatch_once_f + drd:ConflictingAccess + ... + fun:dispatch_once_f +} + +{ + OSX1013:drd:objc_destructInstance + drd:ConflictingAccess + ... + fun:objc_destructInstance +} + +{ + OSX1013:drd:xpc_pipe_routine + drd:ConflictingAccess + ... + fun:xpc_pipe_routine +} + +{ + OSX1013:drd:__si_module_static_cache_block_invoke + drd:MutexErr + fun:pthread_mutex_init + fun:__si_module_static_cache_block_invoke +} + +{ + OSX1013:drd:setlocale + drd:ConflictingAccess + ... + fun:setlocale +} + +{ + OSX1013:drd:std::__1::__thread_specific_ptr::set_pointer(std::__1::__thread_struct*) + + drd:ConflictingAccess + fun:_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE11set_pointerEPS1_ +} + +{ + OSX1013:drd:std::__1::__thread_local_data + drd:ConflictingAccess + fun:_ZNSt3__119__thread_local_dataEv +} + +{ + OSX1013:drd:get_counter + drd:ConflictingAccess + fun:_ZL11get_counterv +} + +{ + OSX1013:drd:gomp_barier_wait + drd:ConflictingAccess + fun:gomp_barrier_wait + fun:child +} + +# DRD suppressions for Darwin 18 / macOS 10.14 Mohave + +{ + macOS1014:pthread_mutex_destroy + drd:MutexErr + fun:pthread_mutex_destroy +} + +{ + macOS1014:_xpc_dictionary_look_up_table + drd:ConflictingAccess + ... + fun:_xpc_dictionary_look_up_table +} + +{ + macOS1014:objc_msgSendSuper2 + drd:ConflictingAccess + fun:objc_msgSendSuper2 +} + +{ + mac1014:nw_path_copy_interface_with_generation + drd:ConflictingAccess + ... + fun:nw_path_copy_interface_with_generation +} + +{ + mac1014:__setenv_locked + drd:ConflictingAccess + fun:__setenv_locked +} + +{ + mac1014:dlopen_internal + drd:ConflictingAccess + ... + fun:dlopen_internal +} + +{ + mac1014:getpwuid_r + drd:ConflictingAccess + fun:si_search + fun:getpwuid_r +} + +{ + mac1014:_pthread_tsd_cleanup + drd:ConflictingAccess + ... + fun:_pthread_tsd_cleanup +} + +{ + macOS1014:dyld::findMappedRange(unsigned long) + drd:ConflictingAccess + fun:_ZN4dyld15findMappedRangeEm +} + +{ + macOS1014:dyld::addImage(ImageLoader*) + drd:ConflictingAccess + ... + fun:_ZN4dyldL8addImageEP11ImageLoader +} + +{ + macOS1014:isKnownClass(objc_class*) + drd:ConflictingAccess + fun:_ZL12isKnownClassP10objc_class +} + +{ + macOS1014:ImageLoader::ImageLoader(char const*, unsigned int) + drd:ConflictingAccess + fun:_ZN11ImageLoaderC2EPKcj +} + +{ + macOS1014:_os_once_callout + drd:ConflictingAccess + ... + fun:_os_once_callout +} + +{ + macOS1014:ImageLoaderMachO::ImageLoaderMachO(macho_header const*, char const*, unsigned int, unsigned int*, unsigned int) + drd:ConflictingAccess + fun:_ZN16ImageLoaderMachOC2EPK12macho_headerPKcjPjj +} + +{ + macOS1014:_fsi_get_validation + drd:ConflictingAccess + ... + fun:_fsi_get_validation +} + +{ + macOS1014:__nw_context_copy_implicit_context_block_invoke + drd:ConflictingAccess + ... + fun:__nw_context_copy_implicit_context_block_invoke +} + +{ + macOS1014:_objc_msgSend_uncached + drd:ConflictingAccess + ... + fun:_objc_msgSend_uncached +} + +{ + macOS1014:dyld::load(char const*, dyld::LoadContext const&, unsigned int&) + drd:ConflictingAccess + ... + fun:_ZN4dyld4loadEPKcRKNS_11LoadContextERj +} + +{ + macOS1015:_CFInitialize + drd:ConflictingAccess + ... + fun:__CFInitialize +} + +{ + macOS1015:cache_validate_item + drd:ConflictingAccess + ... + fun:cache_validate_item +} + +{ + macOS1015:ds_user_byuid + drd:ConflictingAccess + ... + fun:ds_user_byuid +} + +{ + macOS1015:_xpc_bundle_resolve + drd:ConflictingAccess + ... + fun:_xpc_bundle_resolve +} + +{ + macOS1015:getMethodNoSuper_nolock(objc_class*, objc_selector*) + drd:ConflictingAccess + fun:_ZL23getMethodNoSuper_nolockP10objc_classP13objc_selector +} + +{ + macOS1015:search_method_list(method_list_t const*, objc_selector*) + drd:ConflictingAccess + fun:_ZL18search_method_listPK13method_list_tP13objc_selector +} + +{ + macOS1015:objc_object::sidetable_clearDeallocating() + drd:ConflictingAccess + fun:_ZN11objc_object27sidetable_clearDeallocatingEv +} + +{ + macOS1100:_os_semaphore_wait.cold.1 + drd:ConflictingAccess + fun:_os_semaphore_wait.cold.1 +} + diff --git a/darwin-helgrind.supp b/darwin-helgrind.supp new file mode 100644 index 0000000000..f6d3f097b0 --- /dev/null +++ b/darwin-helgrind.supp @@ -0,0 +1,309 @@ + +# Helgrind Suppressions for Darwin 17.x / macOS 10.13 High Sierra + +{ + OSX1013:helgrind:pthread library + Helgrind:Race + obj:/usr/lib/system/libsystem_pthread.dylib +} + +# various getaddrinfo suppressions +{ + OSC1013:helgrind:getaddrinfo + Helgrind:Race + ... + fun:getaddrinfo +} + +{ + OSX1013:helgrind:_fwalk + Helgrind:Race + fun:_fwalk +} + +{ + OSX1013:helgrind:exit + Helgrind:Race + fun:exit +} + +{ + OSX1013:helgrind:freeaddrinfo + Helgrind:Race + fun:freeaddrinfo +} + +# some of these have deep callstacks, this might not work +# with low values of --num-callers +{ + OSC1013:helgrind:si_addrinfo + Helgrind:Race + ... + fun:si_addrinfo +} + +{ + OSC1013:helgrind:file_addrinfo + Helgrind:Race + ... + fun:file_addrinfo +} + +{ + OSX1013:helgrind:xpc_dictionary_apply + Helgrind:Race + ... + fun:xpc_dictionary_apply +} + +{ + OSX1013:helgrind:cache_fill + Helgrind:Race + fun:cache_fill +} + +{ + OSX1013:helgrind:objc_destructInstance + Helgrind:Race + ... + fun:objc_destructInstance +} + +{ + OSX1013:helgrind:xpc_create_from_plist + Helgrind:Race + ... + fun:xpc_create_from_plist +} + +{ + OSX1013:helgrind:dispatch_once_f + Helgrind:Race + ... + fun:dispatch_once_f +} + +{ + OSX1013:helgrind:nanosleep + Helgrind:Race + ... + fun:nanosleep +} + + +{ + OSX1013:helgrind:nw_path_copy_interface_with_generation_internal + Helgrind:Race + ... + fun:nw_path_copy_interface_with_generation_internal +} + + +{ + OSX1013:helgrind:rwlock_tt::read() + Helgrind:Race + fun:_ZN9rwlock_ttILb0EE4readEv +} + +{ + OSX1013:helgrind:rwlock_tt::write() + Helgrind:Race + fun:_ZN9rwlock_ttILb0EE5writeEv +} + +{ + OSX1013:helgrind:gomp_barrier_wait + Helgrind:Race + fun:gomp_barrier_wait +} + +{ + OSX1013:helgrind:_os_unfair_lock_lock_slow + Helgrind:Race + fun:_os_unfair_lock_lock_slow +} + +{ + OSX1013:helgrind:mach_timebase_info + Helgrind:Race + fun:mach_timebase_info +} + +{ + OSX1013:helgrind:std::__1::__thread_specific_ptr::set_pointer(std::__1::__thread_struct*) + Helgrind:Race + fun:_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE11set_pointerEPS1_ +} + +{ + OSX1013:helgrind:std::__1::__thread_local_data() + Helgrind:Race + fun:_ZNSt3__119__thread_local_dataEv +} + +# Helgrind Suppressions for Darwin 18.x / macOS 10.14 Mojave + +{ + macOS1014:_xpc_dictionary_look_up_tab + Helgrind:Race + fun:_platform_strcmp + fun:_xpc_dictionary_look_up_table +} + +{ + macOS1014:_pthread_tsd_cleanup + Helgrind:Race + ... + fun:_pthread_tsd_cleanup +} + +{ + macOS1014:nw_path_copy_interface_with_generation + Helgrind:Race + ... + fun:nw_path_copy_interface_with_generation +} + +{ + macOS1014:__setenv_locked + Helgrind:Race + fun:__setenv_locked +} + +{ + macOS1014:_pthread_once_handler + Helgrind:Race + ... + fun:__pthread_once_handler +} + +{ + macOS1014:getpwuid_r + Helgrind:Race + fun:si_search + fun:getpwuid_r +} + +{ + macOS1014:_objc_msgSend_uncached + Helgrind:Race + ... + fun:_objc_msgSend_uncached +} + +{ + macOS1014:list_array_tt::tryFree() + Helgrind:Race + fun:_ZN13list_array_ttIm15protocol_list_tE7tryFreeEv + fun:NXMapRemove +} + +{ + macOS1015:NXMapInsert + Helgrind:Race + fun:NXMapInsert +} + +{ + macOS1015:notify_monitor_file + Helgrind:Race + fun:notify_monitor_file +} + +{ + macOS1015:_xpc_asprintf + Helgrind:Race + ... + fun:_xpc_asprintf +} + +{ + macOS1015:lookUpImpOrForward + Helgrind:Race + ... + fun:lookUpImpOrForward +} + +{ + macOS1015:__csrctl + Helgrind:Race + fun:__csrctl +} + +{ + macOS1015:search_method_list(method_list_t const*, objc_selector*) + Helgrind:Race + fun:_ZL18search_method_listPK13method_list_tP13objc_selector +} + +{ + macOS1015:cerror + Helgrind:Race + fun:cerror +} + +{ + macOS1015:getPreoptimizedClass + Helgrind:Race + fun:getPreoptimizedClass +} + +{ + maxOS1100:dlopen_internal + Helgrind:Race + ... + fun:dlopen_internal +} + +{ + macOS1100::__CFInitialize + Helgrind:Race + ... + fun:__CFInitialize +} + +{ + macOS1300:voucher_activity_trace_v_2 + Helgrind:Race + fun:_platform_memmove$VARIANT$* + fun:voucher_activity_trace_v_2 +} + +{ + macOS1300:Main_Decrypt_Loop + Helgrind:Race + fun:Main_Decrypt_Loop +} + +{ + macOS1300:ccrng_schedule_timer_notify_reseed + Helgrind:Race + fun:ccrng_schedule_timer_notify_reseed +} + +{ + macOS1300:drbg_reseed + Helgrind:Race + fun:drbg_reseed +} + +{ + macOS1300:ccrng_schedule_*read + Helgrind:Race + fun:ccrng_schedule_*read +} + +{ + macOS1300:getenv + Helgrind:Race + fun:__findenv_locked + fun:getenv +} + +{ + macOS1300:exit1 + Helgrind:Race + fun:__sflush + fun:_fwalk + fun:exit +} diff --git a/darwin16.supp b/darwin-legacy.supp similarity index 50% rename from darwin16.supp rename to darwin-legacy.supp index ae31a97a9e..84487bf631 100644 --- a/darwin16.supp +++ b/darwin-legacy.supp @@ -1,49 +1,515 @@ -# Suppressions for Darwin 16.x / macOS 10.12 Sierra +# Suppressions for legacy versions of Darwin +# Darwin 16.x / macOS 10.12 Sierra and earlier -############################################ -## Leaks. For other stuff see below. +# Suppressions for Darwin 11.x / Mac OS X 10.7 Lion + +# Dunno where this is a real bug, or due to borked 10.7-specific syscall +# wrappers. 64-bit mode; not sure if occurs in 32-bit mode. +# Anyway, for the tine being: +# +# Conditional jump or move depends on uninitialised value(s) +# at 0x1973E6: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib) +# by 0x1976AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib) +# by 0x100B3D: unlock_node (in /usr/lib/system/libkeymgr.dylib) { - OSX1012:1-Leak + OSX107:__mtx_droplock + Memcheck:Cond + fun:__mtx_droplock + fun:pthread_mutex_unlock + fun:unlock_node +} + +# Conditional jump or move depends on uninitialised value(s) +# at 0x2EB883: ??? (in /usr/lib/system/libxpc.dylib) +# by 0x237C6: ??? (in /usr/lib/libSystem.B.dylib) +# by 0x8FE1115A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld) +{ + + Memcheck:Cond + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/libSystem.B.dylib + fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE +} + +# ZLib stuff. How come this wasn't necessary in 10.6 ? +{ + OSX107:zlib-C + Memcheck:Cond + obj:/usr/lib/libz.*dylib + obj:/usr/lib/libz.*dylib +} + +{ + OSX107:zlib-8 + Memcheck:Value8 + obj:/usr/lib/libz.*dylib + obj:/usr/lib/libz.*dylib +} + +# Really a bug? I don't know. +# Conditional jump or move depends on uninitialised value(s) +# at 0x3A322FE: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib) +# by 0x3A326AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib) +# by 0x26382: load_images (in /usr/lib/libobjc.A.dylib) +{ + OSX107:blah + Memcheck:Cond + fun:__mtx_droplock + fun:pthread_mutex_unlock +} + +{ + OSX107:blah + Memcheck:Cond + fun:pthread_mutex_lock +} + +{ + OSX107:10-Leak Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc + match-leak-kinds: reachable + fun:?alloc ... - fun:_read_images + fun:libSystem_initializer } +################ +# More OSX 10.7.2 supps from startup of Firefox, for reports +# that look like they are in the OSX system libraries + +# Conditional jump or move depends on uninitialised value(s) +# at 0x65ADC41: TParsingContext::BuildMacEncTable() +# by 0x65AD98B: TParsingContext::GetEncHash(char const*) +# Uninitialised value was created by a heap allocation +# at 0xC743: malloc (vg_replace_malloc.c:266) +# by 0x65ADADA: TParsingContext::BuildMacEncTable() { - OSX1012:2-Leak + OSX107:more1 + Memcheck:Cond + fun:*TParsingContext16BuildMacEncTable* + fun:*TParsingContext10GetEncHash* +} + +# Conditional jump or move depends on uninitialised value(s) +# at 0x49ABC48: CGColorSpaceAdjustColor +# by 0x4A9AEE8: CGGradientCreateWithColorComponents +# Uninitialised value was created by a heap allocation +# at 0xC743: malloc (vg_replace_malloc.c:266) +# by 0x4A9AEC4: CGGradientCreateWithColorComponents +# by 0x4A9AC49: CGGradientCreateWithColors +{ + OSX107:more2 + Memcheck:Cond + fun:CGColorSpaceAdjustColor + fun:CGGradientCreateWithColorComponents +} + + +# Conditional jump or move depends on uninitialised value(s) +# at 0x2119CCA8: BitSetNextSetBit +# by 0x211A4BA5: BuildInterferenceSets +# Uninitialised value was created by a heap allocation +# at 0xC743: malloc (vg_replace_malloc.c:266) +# by 0x2119CB98: BitSetNew +# by 0x2119D06F: BuildGenKill +{ + OSX107:more3 + Memcheck:Cond + fun:BitSetNextSetBit + fun:BuildInterferenceSets +} + +# and similar +{ + OSX107:more4 + Memcheck:Cond + fun:BitSetNextSetBit + fun:RegistersReInterfere +} + + +# Conditional jump or move depends on uninitialised value(s) +# at 0x33E4160: CUIRenderer::CreateImage +# by 0x33C14A4: CUIRenderer::DrawMenuBar +# Uninitialised value was created by a stack allocation +# at 0x33C12FC: CUIRenderer::DrawMenuBar +{ + OSX107:more5 + Memcheck:Cond + fun:*CUIRenderer*CreateImage* + fun:*CUIRenderer*DrawMenu* +} + +# and similar +{ + OSX107:more6 + Memcheck:Cond + fun:floor$fenv_access_off + fun:*CUIRenderer*CreateImage* + fun:*CUIRenderer*DrawMenu* +} + +# This appears a lot, and the origins seem either missing or +# from system libs. +# Use of uninitialised value of size 8 +# at 0x39CC164: aes_encrypt_xmm_no_save +{ + OSX107:more7 + Memcheck:Value8 + fun:aes_encrypt_xmm_no_save +} + + +# Conditional jump or move depends on uninitialised value(s) +# at 0xD6D193: -[NSPersistentUIManager writeWindowSnapshot:length:... +# by 0xD71A03: __-[NSPersistentUIManager _updateSnapshotForWindowN... +{ + OSX107:more8 + Memcheck:Cond + fun:-[NSPersistentUIManager?writeWindowSnapshot* + fun:__-[NSPersistentUIManager?_updateSnapshotForWindowNumber* +} + + +# Suppressions for Darwin 12.x / Mac OS X 10.8 Mountain Lion + +############################ +## Possibly all to do with borked/incomplete 10.8 syscall wrappers +## Consider all of these as a temporary kludge. It would be much +## better to fix the wrappers correctly (iow, actually implement them). + +{ + OSX108:CoreFoundation-1 + Memcheck:Value8 + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation +} + +{ + OSX108:CoreFoundation-2 + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation +} + +{ + OSX108:CoreGraphics-1 + Memcheck:Cond + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics +} + +{ + OSX108:dyld-1 + Memcheck:Value8 + obj:/usr/lib/dyld + obj:/usr/lib/dyld + obj:/usr/lib/dyld +} + +{ + OSX108:dyld-2 + Memcheck:Cond + obj:/usr/lib/dyld + obj:/usr/lib/dyld + obj:/usr/lib/dyld +} + +{ + OSX108:libxpc-1 + Memcheck:Cond + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib +} + +{ + OSX108:libxpc-2 + Memcheck:Value8 + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib +} + +{ + OSX108:libxpc-3 + Memcheck:Cond + fun:malloc + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib + obj:/usr/lib/system/libxpc.dylib +} + +{ + OSX108:libdispatch-1 + Memcheck:Value8 + obj:/usr/lib/system/libdispatch.dylib + obj:/usr/lib/system/libdispatch.dylib + obj:/usr/lib/system/libdispatch.dylib + obj:/usr/lib/system/libdispatch.dylib +} + +{ + OSX108:ColorSync-1 + Memcheck:Cond + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync +} + +{ + OSX108:ColorSync-2 + Memcheck:Value8 + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync + obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync +} + +{ + OSX108:mach_msg/mach_msg_trap + Memcheck:Param + mach_msg("rcv_name") + fun:mach_msg_trap +} + +{ + OSX108:my_io_execute_passive_block/libdispatch + Memcheck:Cond + fun:my_io_execute_passive_block + obj:/usr/lib/system/libdispatch.dylib + obj:/usr/lib/system/libdispatch.dylib +} + +{ + OSX108:CFRunLoopAddSource/AppKit + Memcheck:Cond + fun:CFRunLoopAddSource + obj:*Frameworks/AppKit.framework/Versions/C/AppKit + obj:*Frameworks/AppKit.framework/Versions/C/AppKit +} + +{ + OSX108:CoreFoundation/HIToolbox/HIToolbox + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*HIToolbox.framework/Versions/A/HIToolbox + obj:*HIToolbox.framework/Versions/A/HIToolbox +} + +{ + OSX108:libsystem_kernel/CoreGraphics-1 + Memcheck:Cond + obj:/usr/lib/system/libsystem_kernel.dylib + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics +} + +{ + OSX108:libsystem_kernel/CoreGraphics-2 + Memcheck:Param + msg->desc.port.name + obj:/usr/lib/system/libsystem_kernel.dylib + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics +} + +{ + OSX108:libsystem_kernel/CoreFoundation/CoreFoundation/LaunchServices + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*LaunchServices.framework/Versions/A/LaunchServices +} + +{ + OSX108:CoreFoundation/AE/AE + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*AE.framework/Versions/A/AE + obj:*AE.framework/Versions/A/AE +} + +{ + OSX108:CoreGraphics/CoreGraphics/CoreGraphics + Memcheck:Param + msg->desc.port.name + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics + obj:*CoreGraphics.framework/Versions/A/CoreGraphics +} + +{ + OSX108:CoreFoundation/Foundation/AppKit + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*Foundation.framework/Versions/C/Foundation + obj:*Frameworks/AppKit.framework/Versions/C/AppKit +} + +{ + OSX108:CoreFoundation/CoreFoundation/HIToolbox + Memcheck:Cond + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*CoreFoundation.framework/Versions/A/CoreFoundation + obj:*HIToolbox.framework/Versions/A/HIToolbox +} + +{ + OSX108:HIServices/HIToolbox/HIToolbox + Memcheck:Cond + obj:*HIServices.framework/Versions/A/HIServices + obj:*HIToolbox.framework/Versions/A/HIToolbox + obj:*HIToolbox.framework/Versions/A/HIToolbox +} + +{ + OSX108:AppKit-1 + Memcheck:Cond + obj:*AppKit.framework/Versions/C/AppKit + obj:*AppKit.framework/Versions/C/AppKit + obj:*AppKit.framework/Versions/C/AppKit +} + +{ + OSX108:32bit:_libxpc_initializer + Memcheck:Cond + fun:_libxpc_initializer + fun:libSystem_initializer + fun:*ImageLoaderMachO*doModInitFunctions* +} + +# See https://bugs.kde.org/show_bug.cgi?id=196528 +{ + macos-__pthread_rwlock_init-see-our-bug-196528 + Memcheck:Cond + fun:pthread_rwlock_init +} + +{ + OSX108:leak-1 Memcheck:Leak match-leak-kinds: definite - fun:malloc_zone_?alloc - ... - fun:_read_images + fun:malloc_zone_malloc + fun:_ZN4objc8DenseMapIP11objc_objectmL* + fun:arr_init } { - OSX1012:3-Leak + OSX108:leak-2 Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_?alloc + fun:malloc_zone_malloc + fun:*NX*Map* + fun:*NX*Map* +} + +{ + OSX108:leak-3 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*NX*Map* + fun:*image* +} + +{ + OSX108:leak-4 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*NX*Map* + fun:*remap* +} + +{ + OSX108:leak-5 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*NX*Map* + fun:*future* +} + +{ + OSX108:leak-6 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*strdup* + fun:*NX*Map* +} + +{ + OSX108:leak-7 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*NX*Map* + fun:*attached* +} + +{ + OSX108:leak-8 + Memcheck:Leak + fun:malloc_zone_malloc + fun:*NX*Map* + fun:dlopen +} + +{ + OSX108:leak-9 + Memcheck:Leak + fun:malloc + fun:*PerThread* + fun:dlopen +} + +{ + OSX108:leak-10 + Memcheck:Leak + fun:malloc_zone_calloc + fun:*NX*Hash* +} + +{ + OSX108:leak-11 + Memcheck:Leak + fun:malloc_zone_calloc + fun:*map* + fun:*map* +} + +{ + OSX108:leak-12 + Memcheck:Leak + fun:malloc_zone_calloc + fun:*fetch_pthread_data* +} + +{ + OSX108:leak-13 + Memcheck:Leak + fun:malloc_zone_malloc fun:recursive_mutex_init - ... - fun:_os_object_init - fun:libdispatch_init - fun:libSystem_initializer + fun:_objc_init } { - OSX1012:4-Leak + OSX108:leak-14 Memcheck:Leak + match-leak-kinds: reachable fun:malloc_zone_?alloc ... fun:dyld_register_image_state_change_handler } { - OSX1012:5-Leak + OSX108:leak-15 Memcheck:Leak match-leak-kinds: reachable fun:?alloc @@ -52,36 +518,45 @@ } { - OSX1012:6-Leak + OSX108:leak-16 Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_?alloc ... fun:map_images_nolock - fun:map_2_images + fun:map_images } { - OSX1012:7-Leak + OSX108:leak-17 Memcheck:Leak match-leak-kinds: possible fun:malloc_zone_?alloc ... fun:map_images_nolock - fun:map_2_images + fun:map_images } { - OSX1012:8-Leak + OSX108:leak-18 Memcheck:Leak - match-leak-kinds: definite + match-leak-kinds: indirect + fun:malloc_zone_?alloc + ... + fun:libSystem_initializer +} + +{ + OSX108:leak-19 + Memcheck:Leak + match-leak-kinds: indirect fun:?alloc ... fun:libSystem_initializer } { - OSX1012:9-Leak + OSX108:leak-20 Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_?alloc @@ -90,30 +565,142 @@ } { - OSX1012:10-Leak + OSX108:leak-22 Memcheck:Leak match-leak-kinds: reachable fun:?alloc ... + fun:_libxpc_initializer +} + +{ + OSX108:leak-23 + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:realloc + fun:new_sem_from_pool +} + +# afaict this is legit. Might be caused by setenv("VAR=") +# where the value string is empty (not sure) +{ + macos-Cond-7 + Memcheck:Cond + fun:__setenv +} + +# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's +# unavoidable due to BSD setenv() semantics. +{ + macos-__setenv-leak-see-our-bug-188572 + Memcheck:Leak + fun:malloc_zone_malloc + fun:__setenv +} + +# From Gary Kwong +{ + macos-malloc_set_zone_name-see-our-bug-307557 + Memcheck:Leak + fun:malloc_zone_malloc + ... + fun:malloc_set_zone_name + ... + fun:init__zone0 +} + +{ + OSX109:2-Leak + Memcheck:Leak + match-leak-kinds: definite + fun:?alloc + ... + fun:_ZN4dyld24initializeMainExecutableEv +} + +{ + OSX109:QuartzCore-1 + Memcheck:Cond + obj:*QuartzCore.framework*QuartzCore + obj:*QuartzCore.framework*QuartzCore + obj:*QuartzCore.framework*QuartzCore +} + +{ + OSX109:vImage-1 + Memcheck:Cond + obj:*vImage.framework*vImage* + obj:*vImage.framework*vImage* + obj:*CoreGraphics.framework*CoreGraphics* +} + +{ + OSX1012:1-Leak + Memcheck:Leak + match-leak-kinds: possible + fun:malloc_zone_?alloc + ... + fun:_read_images +} + +{ + OSX1012:2-Leak + Memcheck:Leak + match-leak-kinds: definite + fun:malloc_zone_?alloc + ... + fun:_read_images +} + +{ + OSX1012:3-Leak + Memcheck:Leak + match-leak-kinds: definite + fun:malloc_zone_?alloc + fun:recursive_mutex_init + ... + fun:_os_object_init + fun:libdispatch_init fun:libSystem_initializer } -#{ -# OSX1012:11-Leak -# Memcheck:Leak -# match-leak-kinds: definite -# fun:malloc -# fun:currentlocale -#} -# -#{ -# OSX1012:12-Leak -# Memcheck:Leak -# match-leak-kinds: possible -# fun:malloc -# fun:tzsetwall_basic -# fun:_st_tzset_basic -#} +{ + OSX1012:4-Leak + Memcheck:Leak + fun:malloc_zone_?alloc + ... + fun:dyld_register_image_state_change_handler +} + +{ + OSX1012:6-Leak + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_?alloc + ... + fun:map_images_nolock + fun:map_2_images +} + +{ + OSX1012:7-Leak + Memcheck:Leak + match-leak-kinds: possible + fun:malloc_zone_?alloc + ... + fun:map_images_nolock + fun:map_2_images +} + +{ + OSX1012:8-Leak + Memcheck:Leak + match-leak-kinds: definite + fun:?alloc + ... + fun:libSystem_initializer +} { OSX1012:13-Leak @@ -180,15 +767,6 @@ fun:*NX*Map* } -{ - OSX1012:20-Leak - Memcheck:Leak - match-leak-kinds: indirect - fun:?alloc - ... - fun:libSystem_initializer -} - { OSX1012:21-Leak Memcheck:Leak @@ -198,18 +776,6 @@ fun:_ZN4dyld24initializeMainExecutableEv } - -############################################ -## Non-leak errors - -##{ -## OSX1012:CoreFoundation-1 -## Memcheck:Cond -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - { OSX1012:CoreFoundation-2 Memcheck:Cond @@ -321,22 +887,6 @@ obj:*libdispatch.dylib* } -#{ -# OSX1012:AppKit-3 -# Memcheck:Cond -# obj:*AppKit.framework*AppKit* -# obj:*libdispatch.dylib* -# obj:*libdispatch.dylib* -#} - -##{ -## OSX1012:AppKit-4 -## Memcheck:Cond -## obj:*AppKit.framework*AppKit* -## obj:*AppKit.framework*AppKit* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - { OSX1012:AppKit-5 Memcheck:Cond @@ -377,14 +927,6 @@ obj:*ColorSync.framework*ColorSync* } -#{ -# OSX1012:ColorSync-2 -# Memcheck:Value8 -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -#} - { OSX1012:CoreGraphics-1 Memcheck:Cond @@ -392,14 +934,6 @@ obj:*CoreGraphics.framework*CoreGraphics* } -#{ -# OSX1012:CoreGraphics-2 -# Memcheck:Value8 -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - { OSX1012:CoreGraphics-3 Memcheck:Cond @@ -408,14 +942,6 @@ obj:*CoreGraphics.framework*libRIP* } -#{ -# OSX1012:CoreGraphics-4 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*libRIP* -#} - { OSX1012:CoreGraphics-5 Memcheck:Cond @@ -424,14 +950,6 @@ obj:*libdispatch.dylib* } -#{ -# OSX1012:CoreGraphics-6 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*HIToolbox.framework*HIToolbox* -#} - { OSX1012:HIServices-1 Memcheck:Cond @@ -456,36 +974,6 @@ obj:*libdispatch.dylib* } -{ - OSX1012:QuartzCore-1 - Memcheck:Cond - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore -} - -#{ -# OSX1012:vImage-1 -# Memcheck:Cond -# obj:*vImage.framework*vImage* -# obj:*vImage.framework*vImage* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - -{ - OSX1012:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -{ - OSX1012:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - { OSX1012:32bit:_libxpc_initializer Memcheck:Cond @@ -574,14 +1062,6 @@ obj:*CoreServices.framework*LaunchServices* } -##{ -## OSX1012:libsystem_pthread-1 -## Memcheck:Cond -## obj:*libsystem_pthread*dylib* -## obj:*ImageIO.framework*ImageIO* -## obj:*ImageIO.framework*ImageIO* -##} - { OSX1012:ApplicationServices-1 Memcheck:Cond @@ -606,22 +1086,6 @@ obj:*libdispatch.dylib* } -##{ -## OSX1012:CoreImage-1 -## Memcheck:Cond -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -##} - -##{ -## OSX1012:strncpy-1 -## Memcheck:Cond -## fun:strncpy -## obj:*CoreServicesInternal.framework*CoreServicesInternal -## obj:*CoreServicesInternal.framework*CoreServicesInternal -##} - { OSX1012:pthread_rwlock_init Memcheck:Cond @@ -644,6 +1108,7 @@ obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* } + { OSX1012:AppleIntelHD4000GraphicsGLDriver-1-Addr8 Memcheck:Addr4 @@ -659,6 +1124,7 @@ obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* } + { OSX1012:AppleIntelHD4000GraphicsGLDriver-2-Addr2 Memcheck:Addr2 @@ -674,6 +1140,7 @@ obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* obj:*GLEngine.bundle*GLEngine* } + { OSX1012:AppleIntelHD4000GraphicsGLDriver-3-Addr2 Memcheck:Addr2 @@ -681,6 +1148,7 @@ obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* obj:*GLEngine.bundle*GLEngine* } + { OSX1012:AppleIntelHD4000GraphicsGLDriver-3-Addr1 Memcheck:Addr1 @@ -704,6 +1172,7 @@ obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* obj:*GLEngine.bundle*GLEngine* } + { OSX1012:AppleIntelHD4000GraphicsGLDriver-6-Addr4 Memcheck:Addr4 @@ -745,9 +1214,3 @@ fun:setenv } -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ -macos-__pthread_rwlock_init-see-our-bug-196528 -Memcheck:Cond -fun:pthread_rwlock_init -} diff --git a/darwin17.supp b/darwin.supp similarity index 78% rename from darwin17.supp rename to darwin.supp index 996688654f..6c57ebb9ca 100644 --- a/darwin17.supp +++ b/darwin.supp @@ -54,21 +54,9 @@ { OSX1013:6-Leak Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_2_images -} - -{ - OSX1013:7-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc + match-leak-kinds: all ... fun:map_images_nolock - fun:map_2_images } { @@ -136,7 +124,7 @@ { OSX1013:15-Leak Memcheck:Leak - match-leak-kinds: reachable + match-leak-kinds: definite,reachable fun:malloc fun:__smakebuf ... @@ -198,6 +186,17 @@ fun:_ZN4dyld24initializeMainExecutableEv } +{ + OSX1013:22-Leak + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__smakebuf + fun:__swsetup + fun:__sfvwrite + fun:fwrite +} + ############################################ ## Non-leak errors @@ -511,20 +510,6 @@ obj:*libdyld*dylib* } -{ - OSX1013:dyld-3 - Memcheck:Cond - fun:bcmp - fun:_ZN16ImageLoaderMachO18validateFirstPagesEPK21linkedit_data_commandiPKhmxRKN11ImageLoader11LinkContextE -} - -{ - OSX1013:dyld-4 - Memcheck:Value8 - fun:bcmp - fun:_ZN16ImageLoaderMachO18validateFirstPagesEPK21linkedit_data_commandiPKhmxRKN11ImageLoader11LinkContextE -} - { OSX1013:dyld-5 Memcheck:Cond @@ -574,13 +559,6 @@ obj:*CoreServices.framework*LaunchServices* } -##{ -## OSX1013:libsystem_pthread-1 -## Memcheck:Cond -## obj:*libsystem_pthread*dylib* -## obj:*ImageIO.framework*ImageIO* -## obj:*ImageIO.framework*ImageIO* -##} { OSX1013:ApplicationServices-1 @@ -606,28 +584,10 @@ obj:*libdispatch.dylib* } -##{ -## OSX1013:CoreImage-1 -## Memcheck:Cond -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -##} - -##{ -## OSX1013:strncpy-1 -## Memcheck:Cond -## fun:strncpy -## obj:*CoreServicesInternal.framework*CoreServicesInternal -## obj:*CoreServicesInternal.framework*CoreServicesInternal -##} - { OSX1013:pthread_rwlock_init Memcheck:Cond fun:pthread_rwlock_init - obj:*ImageIO.framework*ImageIO* - obj:*ImageIO.framework*ImageIO* } { @@ -745,13 +705,6 @@ fun:setenv } -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ -macos-__pthread_rwlock_init-see-our-bug-196528 -Memcheck:Cond -fun:pthread_rwlock_init -} - # macOS 10.13 mach-o loader at startup { OSX1013:map_images-1 @@ -761,14 +714,6 @@ fun:pthread_rwlock_init fun:NXCreate*TableFromZone } -{ - OSX1013:map_images-2 - Memcheck:Leak - match-leak-kinds: possible - fun:calloc - fun:map_images_nolock - fun:map_images -} { OSX1013:map_images-3 Memcheck:Leak @@ -776,29 +721,15 @@ fun:pthread_rwlock_init fun:calloc fun:_ZL12realizeClassP10objc_class } -{ - OSX1013:map_images-4 - Memcheck:Leak - match-leak-kinds: indirect - fun:malloc_zone_malloc - ... - fun:map_images_nolock -} + { OSX1013:map_images-5 Memcheck:Leak - match-leak-kinds: indirect + match-leak-kinds: all fun:malloc_zone_calloc fun:*NXHash* } -{ - OSX1013:_pthread_start - Helgrind:Race - fun:_pthread_start - fun:thread_start -} - { OSX1013:vng_aes_encrypt_opt Memcheck:Value8 @@ -811,176 +742,224 @@ fun:pthread_rwlock_init fun:ccaes_vng_ctr_crypt } -{ - OSX1013:helgrind:_pthread_deallocate - Helgrind:Race - fun:_pthread_deallocate -} +# Suppressions for Darwin 18.x / macOS 10.14 Mojave { - OSX1013:helgrind:_pthread_join_cleanup - Helgrind:Race - fun:_pthread_join_cleanup + macOS1014:_dyld_start + Memcheck:Cond + ... + fun:_dyld_start } { - OSX1013:helgrind:_pthread_join - Helgrind:Race - fun:_pthread_join + macOS1014:libSystem_initializer + Memcheck:Addr16 + ... + fun:libSystem_initializer } { - OSX1013:helgrind:_pthread_terminate - Helgrind:Race - fun:_pthread_terminate + macOS1014:_NXHashRehashToCapacity + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_calloc + fun:_NXHashRehashToCapacity } { - OSX1013:helgrind:_pthread_exit - Helgrind:Race - fun:_pthread_exit + macOS1014:remapClass(objc_class*) + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_calloc + fun:_ZL10remapClassP10objc_class } { - OSX1013:helgrind:_pthread_body - Helgrind:Race - fun:_pthread_body + macOS1014:NXHashGet + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:NXHashGet } { - OSX1013:nanosleep - drd:ConflictingAccess - fun:nanosleep -} -{ - OSX1013:_pthread_join - drd:ConflictingAccess - fun:_pthread_join + macOS1014:NXHashInsert + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc* + fun:NXHashInsert } + { - OSX1013:usleep - drd:ConflictingAccess - fun:pthread_testcancel - fun:usleep + macOS1014:isEqualPrototype(void const*, void const*, void const*) + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_malloc + fun:_ZL16isEqualPrototypePKvS0_S0_ } + +# I suppose that this is deliberate +# and that Apple know what they are doing? +# On macOS 12 at least this seems to have changed name to ___chkstk_darwin +# this matches both { - OSX1013:_pthread_join_cleanup - drd:ConflictingAccess - fun:_pthread_join_cleanup + macOS1015:__chkstk_darwin_probe + Memcheck:Addr8 + fun:__*chkstk_darwin* } + { - OSX1013:pthread_mutex_destroy - drd:ConflictingAccess - fun:pthread_mutex_destroy + macOS1015:_mh_execute_header + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:_mh_execute_header } + { - OSX1013:pthread_cond_destroy - drd:ConflictingAccess - fun:pthread_cond_destroy + macOS1015:_objc_atfork_parent + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:class_setWeakIvarLayout + fun:class_setWeakIvarLayout + fun:_objc_atfork_parent } + +# FIXME PJF all these Addr* issues looks like problems with memory mapping + { - OSX1013:pthread_mutex_unlock - drd:ConflictingAccess - fun:pthread_mutex_unlock + macOS1100:_dyld_start + Memcheck:Addr8 + ... + fun:_dyld_start } + { - OSX1013:pthread_mutex_lock - drd:ConflictingAccess - fun:pthread_mutex_lock + macOS1100:_dyld_start + Memcheck:Addr4 + ... + fun:_dyld_start } + { - OSX1013:_pthread_deallocate - drd:ConflictingAccess - fun:_pthread_deallocate + macOS1100:__chkstk_darwin_probe + Memcheck:Addr1 + fun:__*chkstk_darwin* } + { - OSX1013:std::timed_mutex::unlock - drd:ConflictingAccess - fun:_ZNSt3__111timed_mutex6unlockEv + macOS1100:_dyld_start + Memcheck:Addr1 + ... + fun:_dyld_start } + { - std::timed_mutex::try_lock_until - drd:ConflictingAccess - fun:_ZNSt3__111timed_mutex14try_lock_untilINS_6chrono12steady_clockENS2_8durationIxNS_5ratio* + macOS1200:#dyld4::ProcessConfig::ProcessConfig(dyld4::KernelArgs const*, dyld4::SyscallDelegate&) + Memcheck:Addr1 + ... + fun:_ZN5dyld413ProcessConfigC2EPKNS_10KernelArgsERNS_15SyscallDelegateE } + { - OSX1013:_pthread_cond_updateval - drd:ConflictingAccess - fun:_pthread_cond_updateval + macOS1200:#dyld4::ProcessConfig::ProcessConfig(dyld4::KernelArgs const*, dyld4::SyscallDelegate&) + Memcheck:Addr8 + ... + fun:_ZN5dyld413ProcessConfigC2EPKNS_10KernelArgsERNS_15SyscallDelegateE } + { - OSX1013:pthread_cond_signal - drd:ConflictingAccess - fun:pthread_cond_signal + macOS1200:#dyld4::ProcessConfig::ProcessConfig(dyld4::KernelArgs const*, dyld4::SyscallDelegate&) + Memcheck:Addr4 + ... + fun:_ZN5dyld413ProcessConfigC2EPKNS_10KernelArgsERNS_15SyscallDelegateE } + { - OSX1013:_pthread_mutex_droplock - drd:ConflictingAccess - fun:_pthread_mutex_droplock + macOS1300:xpc_copy_entitlements_for_self + Memcheck:Cond + ... + fun:xpc_copy_entitlements_for_self } + { - OSX1013:_pthread_cond_wait - drd:ConflictingAccess - fun:_pthread_cond_wait + macOS1300:libSystem_initializer + Memcheck:Cond + ... + fun:libSystem_initializer } + { - OSX1013:mach_timebase_info - drd:ConflictingAccess - fun:mach_timebase_info + macOS13:DyldSharedCache::* + Memcheck:Addr4 + fun:_ZNK15DyldSharedCache* } + { - OSX1013:pthread_testcancel - drd:ConflictingAccess - fun:pthread_testcancel + macOS1300:dyld* Value8 + Memcheck:Value8 + fun:_ZN*5dyld* } -# take care with this, don't want to suppress anything in user -# thread functions + { - OSX1013:_pthread_body - drd:ConflictingAccess - fun:_pthread_body + macOS1300:dyld* + Memcheck:Cond + fun:_ZN*5dyld* } + { - OSX1013:exit - drd:ConflictingAccess + macOS1300:dyld* + Memcheck:Addr1 ... - fun:exit + fun:_ZN5dyld* } + { - OSX1013:freeaddrinfo - drd:ConflictingAccess - fun:freeaddrinfo + macOS1300:dyld* + Memcheck:Addr4 + ... + fun:_ZN5dyld* } + { - OSX1013:getaddrinfo - drd:ConflictingAccess + macOS1300:dyld* + Memcheck:Addr8 ... - fun:getaddrinfo + fun:_ZN5dyld* } + { - OSX1013:cache_fill - drd:ConflictingAccess - fun:_ZN7cache_t10reallocateEjj - fun:cache_fill + macOS1300:dyld3::* + Memcheck:Addr16 + ... + fun:_ZN5dyld3* } + { - OSX1013:os_unfair_lock - drd:ConflictingAccess + macOS1300:DyldSharedCache::* + Memcheck:Addr8 ... - fun:*os_unfair_lock* + fun:_ZNK15DyldSharedCache* } + { - OSX1013:objc_msgSend - drd:ConflictingAccess - fun:objc_msgSend + macOS1300:DyldSharedCache::* + Memcheck:Addr16 + ... + fun:_ZNK15DyldSharedCache* } + { - OSX1013:cache_fill - drd:ConflictingAccess - fun:cache_fill + macOS1300:libSystem_atfork_child + Memcheck:Cond + ... + fun:libSystem_atfork_child } + { - OSX1013:_nc_table - drd:ConflictingAccess - fun:_nc_table_* + macOS1300:libSystem_atfork_child + Memcheck:Value8 + ... + fun:libSystem_atfork_child } diff --git a/darwin10-drd.supp b/darwin10-drd.supp deleted file mode 100644 index 6bb8103dfb..0000000000 --- a/darwin10-drd.supp +++ /dev/null @@ -1,162 +0,0 @@ -# DRD suppressions for Darwin 10.x / Mac OS X 10.6 Snow Leopard - -# -# dyld -# -{ - dyld_mutex_not_locked - drd:MutexErr - fun:pthread_mutex_unlock - fun:_dyld_register_func_for_*_image -} -{ - dyld_mutex_reinitialization - drd:MutexErr - fun:pthread_mutex_init - fun:_Z24dyldGlobalLockInitializev - fun:_dyld_initializer -} -{ - dyld_stub_binder - drd:ConflictingAccess - ... - fun:_ZN4dyld18fastBindLazySymbolEPP11ImageLoaderm - fun:dyld_stub_binder -} -{ - dyld ImageLoaderMachOCompressed::findExportedSymbol(char const*, ImageLoader const**) const - drd:ConflictingAccess - fun:_ZNK26ImageLoaderMachOCompressed18findExportedSymbolEPKcPPK11ImageLoader -} -{ - dyld dyld::fastBindLazySymbol(ImageLoader**, unsigned long) - drd:ConflictingAccess - ... - fun:_ZN4dyld18fastBindLazySymbolEPP11ImageLoaderm -} -{ - dyld ImageLoaderMachOCompressed::doBindFastLazySymbol(unsigned int, ImageLoader::LinkContext const&) - drd:ConflictingAccess - ... - fun:_ZN26ImageLoaderMachOCompressed20doBindFastLazySymbolEjRKN11ImageLoader11LinkContextE -} - -# -# C library -# -{ - __umodti3 - drd:ConflictingAccess - fun:__umodti3 -} -{ - fork() - drd:ConflictingAccess - ... - fun:_cthread_fork_child - fun:fork -} -{ - flockfile - drd:ConflictingAccess - fun:flockfile -} -{ - funlockfile - drd:ConflictingAccess - fun:funlockfile -} -{ - vfprintf_l - drd:ConflictingAccess - fun:vfprintf_l -} -{ - localeconv_l - drd:ConflictingAccess - fun:localeconv_l -} -{ - __vfprintf - drd:ConflictingAccess - fun:__vfprintf -} -{ - fflush - drd:ConflictingAccess - fun:fflush -} -{ - cerror - drd:ConflictingAccess - ... - fun:cerror -} -{ - do_rand - drd:ConflictingAccess - fun:do_rand -} -{ - mig_dealloc_reply_port - drd:ConflictingAccess - fun:mig_dealloc_reply_port -} - -# -# pthread library -# -{ - thread_start - drd:ConflictingAccess - obj:* - fun:thread_start -} -{ - pthread_create() - drd:ConflictingAccess - ... - fun:pthread_create -} -{ - drd-darwin-pthread-join-1 - drd:ConflictingAccess - ... - fun:pthread_join$UNIX2003 -} -{ - drd-darwin-pthread-join-2 - drd:ConflictingAccess - ... - fun:pthread_join - fun:pthread_join -} -{ - _pthread_exit() - drd:ConflictingAccess - ... - fun:_pthread_exit -} -{ - pthread_detach() - drd:ConflictingAccess - ... - fun:pthread_detach - fun:pthread_detach -} -{ - pthread_kill() - drd:ConflictingAccess - ... - fun:pthread_kill -} -{ - spin_unlock() - drd:ConflictingAccess - fun:spin_unlock -} -{ - _pthread_testcancel() - drd:ConflictingAccess - fun:_pthread_testcancel -} diff --git a/darwin10.supp b/darwin10.supp deleted file mode 100644 index 505305d8c5..0000000000 --- a/darwin10.supp +++ /dev/null @@ -1,67 +0,0 @@ - -# Suppressions for Darwin 10.x / Mac OS X 10.6 Snow Leopard - -##----------------------------------------------------------------------## -# Memcheck -##----------------------------------------------------------------------## - -# afaict this is legit. Might be caused by setenv("VAR=") -# where the value string is empty (not sure) -{ - macos-Cond-7 - Memcheck:Cond - fun:__setenv -} - -# From Jesse Ruderman. -{ - Mac OS X 10.6.4. rdar://8145289. "new[]" paired with "delete" in the DesktopServicesPriv framework. - Memcheck:Free - fun:_ZdlPv - fun:_ZN5TChar18RemovePtrReferenceEv - } - -# From Jesse Ruderman. -{ - Mac OS X 10.6.4. rdar://8145318. Uninitialized memory from HIMenuBarView::MeasureAppMenus is used in HIMenuBarView::SetAdjustTextTitleBoundsAtIndex. - Memcheck:Cond - fun:_ZN13HIMenuBarView31SetAdjustTextTitleBoundsAtIndexEih - fun:_ZN13HIMenuBarView15MeasureAppMenusEv -} - -{ - TFontFeatures::TFontFeatures(CGFont*) (in CoreText.framework) - Memcheck:Cond - fun:_ZN13TFontFeaturesC2EP6CGFont - fun:_ZNK9TBaseFont12CopyFeaturesEv -} - -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - fun:malloc_zone_malloc - fun:__setenv -} - -{ - libSystem-keymgr-leak-at-exit - Memcheck:Leak - fun:malloc - fun:get_or_create_key_element - fun:_keymgr_get_and_lock_processwide_ptr_2 - fun:__keymgr_initializer - fun:libSystem_initializer -} - -{ - darwin-still-reachable-1 - Memcheck:Leak - ... - fun:dwarf2_unwind_dyld_add_image_hook - fun:_ZN4dyld19registerAddCallbackEPFvPK11mach_headerlE - fun:_dyld_register_func_for_add_image - fun:__keymgr_initializer - fun:libSystem_initializer -} diff --git a/darwin11.supp b/darwin11.supp deleted file mode 100644 index 7f87399763..0000000000 --- a/darwin11.supp +++ /dev/null @@ -1,245 +0,0 @@ - -# Suppressions for Darwin 11.x / Mac OS X 10.7 Lion - -##----------------------------------------------------------------------## -# Memcheck -##----------------------------------------------------------------------## - -# Dunno where this is a real bug, or due to borked 10.7-specific syscall -# wrappers. 64-bit mode; not sure if occurs in 32-bit mode. -# Anyway, for the tine being: -# -# Conditional jump or move depends on uninitialised value(s) -# at 0x1973E6: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib) -# by 0x1976AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib) -# by 0x100B3D: unlock_node (in /usr/lib/system/libkeymgr.dylib) -{ - OSX107:__mtx_droplock - Memcheck:Cond - fun:__mtx_droplock - fun:pthread_mutex_unlock - fun:unlock_node -} - -# Conditional jump or move depends on uninitialised value(s) -# at 0x2EB883: ??? (in /usr/lib/system/libxpc.dylib) -# by 0x237C6: ??? (in /usr/lib/libSystem.B.dylib) -# by 0x8FE1115A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld) -{ - - Memcheck:Cond - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/libSystem.B.dylib - fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE -} - -# ZLib stuff. How come this wasn't necessary in 10.6 ? -{ - OSX107:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} -{ - OSX107:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -# Really a bug? I don't know. -# Conditional jump or move depends on uninitialised value(s) -# at 0x3A322FE: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib) -# by 0x3A326AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib) -# by 0x26382: load_images (in /usr/lib/libobjc.A.dylib) -{ - OSX107:blah - Memcheck:Cond - fun:__mtx_droplock - fun:pthread_mutex_unlock -} - -{ - OSX107:blah - Memcheck:Cond - fun:pthread_mutex_lock -} - -{ - OSX107:10-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_initializer -} - -################ -# More OSX 10.7.2 supps from startup of Firefox, for reports -# that look like they are in the OSX system libraries - -# Conditional jump or move depends on uninitialised value(s) -# at 0x65ADC41: TParsingContext::BuildMacEncTable() -# by 0x65AD98B: TParsingContext::GetEncHash(char const*) -# Uninitialised value was created by a heap allocation -# at 0xC743: malloc (vg_replace_malloc.c:266) -# by 0x65ADADA: TParsingContext::BuildMacEncTable() -{ - OSX107:more1 - Memcheck:Cond - fun:*TParsingContext16BuildMacEncTable* - fun:*TParsingContext10GetEncHash* -} - -# Conditional jump or move depends on uninitialised value(s) -# at 0x49ABC48: CGColorSpaceAdjustColor -# by 0x4A9AEE8: CGGradientCreateWithColorComponents -# Uninitialised value was created by a heap allocation -# at 0xC743: malloc (vg_replace_malloc.c:266) -# by 0x4A9AEC4: CGGradientCreateWithColorComponents -# by 0x4A9AC49: CGGradientCreateWithColors -{ - OSX107:more2 - Memcheck:Cond - fun:CGColorSpaceAdjustColor - fun:CGGradientCreateWithColorComponents -} - - -# Conditional jump or move depends on uninitialised value(s) -# at 0x2119CCA8: BitSetNextSetBit -# by 0x211A4BA5: BuildInterferenceSets -# Uninitialised value was created by a heap allocation -# at 0xC743: malloc (vg_replace_malloc.c:266) -# by 0x2119CB98: BitSetNew -# by 0x2119D06F: BuildGenKill -{ - OSX107:more3 - Memcheck:Cond - fun:BitSetNextSetBit - fun:BuildInterferenceSets -} - -# and similar -{ - OSX107:more4 - Memcheck:Cond - fun:BitSetNextSetBit - fun:RegistersReInterfere -} - - -# Conditional jump or move depends on uninitialised value(s) -# at 0x33E4160: CUIRenderer::CreateImage -# by 0x33C14A4: CUIRenderer::DrawMenuBar -# Uninitialised value was created by a stack allocation -# at 0x33C12FC: CUIRenderer::DrawMenuBar -{ - OSX107:more5 - Memcheck:Cond - fun:*CUIRenderer*CreateImage* - fun:*CUIRenderer*DrawMenu* -} - -# and similar -{ - OSX107:more6 - Memcheck:Cond - fun:floor$fenv_access_off - fun:*CUIRenderer*CreateImage* - fun:*CUIRenderer*DrawMenu* -} - -# This appears a lot, and the origins seem either missing or -# from system libs. -# Use of uninitialised value of size 8 -# at 0x39CC164: aes_encrypt_xmm_no_save -{ - OSX107:more7 - Memcheck:Value8 - fun:aes_encrypt_xmm_no_save -} - - -# Conditional jump or move depends on uninitialised value(s) -# at 0xD6D193: -[NSPersistentUIManager writeWindowSnapshot:length:... -# by 0xD71A03: __-[NSPersistentUIManager _updateSnapshotForWindowN... -{ - OSX107:more8 - Memcheck:Cond - fun:-[NSPersistentUIManager?writeWindowSnapshot* - fun:__-[NSPersistentUIManager?_updateSnapshotForWindowNumber* -} - - -########################################################################## -### The ones below are from darwin10.supp (for Snow Leopard). I don't -### know whether they are still necessary. - -# afaict this is legit. Might be caused by setenv("VAR=") -# where the value string is empty (not sure) -{ - macos-Cond-7 - Memcheck:Cond - fun:__setenv -} - -# From Jesse Ruderman. -#{ -# Mac OS X 10.6.4. rdar://8145289. "new[]" paired with "delete" in the DesktopServicesPriv framework. -# Memcheck:Free -# fun:_ZdlPv -# fun:_ZN5TChar18RemovePtrReferenceEv -# } - -# From Jesse Ruderman. -#{ -# Mac OS X 10.6.4. rdar://8145318. Uninitialized memory from HIMenuBarView::MeasureAppMenus is used in HIMenuBarView::SetAdjustTextTitleBoundsAtIndex. -# Memcheck:Cond -# fun:_ZN13HIMenuBarView31SetAdjustTextTitleBoundsAtIndexEih -# fun:_ZN13HIMenuBarView15MeasureAppMenusEv -#} - -#{ -# TFontFeatures::TFontFeatures(CGFont*) (in CoreText.framework) -# Memcheck:Cond -# fun:_ZN13TFontFeaturesC2EP6CGFont -# fun:_ZNK9TBaseFont12CopyFeaturesEv -#} - -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - fun:malloc_zone_malloc - fun:__setenv -} - -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ - macos-__pthread_rwlock_init-see-our-bug-196528 - Memcheck:Cond - fun:pthread_rwlock_init -} - -#{ -# libSystem-keymgr-leak-at-exit -# Memcheck:Leak -# fun:malloc -# fun:get_or_create_key_element -# fun:_keymgr_get_and_lock_processwide_ptr_2 -# fun:__keymgr_initializer -# fun:libSystem_initializer -#} - -# From Gary Kwong -{ - macos-malloc_set_zone_name-see-our-bug-307557 - Memcheck:Leak - fun:malloc_zone_malloc - ... - fun:malloc_set_zone_name - ... - fun:init__zone0 -} diff --git a/darwin12.supp b/darwin12.supp deleted file mode 100644 index c3f47c15b9..0000000000 --- a/darwin12.supp +++ /dev/null @@ -1,448 +0,0 @@ - -# Suppressions for Darwin 12.x / Mac OS X 10.8 Mountain Lion - -# ZLib stuff. How come this wasn't necessary in 10.6 ? -{ - OSX108:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} -{ - OSX108:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -############################ -## Possibly all to do with borked/incomplete 10.8 syscall wrappers -## Consider all of these as a temporary kludge. It would be much -## better to fix the wrappers correctly (iow, actually implement them). - -{ - OSX108:CoreFoundation-1 - Memcheck:Value8 - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation -} - -{ - OSX108:CoreFoundation-2 - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation -} - -{ - OSX108:CoreGraphics-1 - Memcheck:Cond - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics -} - -# Use of uninitialised value of size 8 -# at 0x39CC164: aes_encrypt_xmm_no_save -{ - OSX108:aes_encrypt_xmm_no_save - Memcheck:Value8 - fun:aes_encrypt_xmm_no_save -} - -{ - OSX108:dyld-1 - Memcheck:Value8 - obj:/usr/lib/dyld - obj:/usr/lib/dyld - obj:/usr/lib/dyld -} - -{ - OSX108:dyld-2 - Memcheck:Cond - obj:/usr/lib/dyld - obj:/usr/lib/dyld - obj:/usr/lib/dyld -} - -{ - OSX108:libxpc-1 - Memcheck:Cond - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib -} - -{ - OSX108:libxpc-2 - Memcheck:Value8 - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib -} - -{ - OSX108:libxpc-3 - Memcheck:Cond - fun:malloc - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib - obj:/usr/lib/system/libxpc.dylib -} - -{ - OSX108:libdispatch-1 - Memcheck:Value8 - obj:/usr/lib/system/libdispatch.dylib - obj:/usr/lib/system/libdispatch.dylib - obj:/usr/lib/system/libdispatch.dylib - obj:/usr/lib/system/libdispatch.dylib -} - -{ - OSX108:ColorSync-1 - Memcheck:Cond - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync -} - -{ - OSX108:ColorSync-2 - Memcheck:Value8 - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync - obj:*Frameworks/ColorSync.framework/Versions/A/ColorSync -} - -{ - OSX108:mach_msg/mach_msg_trap - Memcheck:Param - mach_msg("rcv_name") - fun:mach_msg_trap -} - -{ - OSX108:my_io_execute_passive_block/libdispatch - Memcheck:Cond - fun:my_io_execute_passive_block - obj:/usr/lib/system/libdispatch.dylib - obj:/usr/lib/system/libdispatch.dylib -} - -{ - OSX108:CFRunLoopAddSource/AppKit - Memcheck:Cond - fun:CFRunLoopAddSource - obj:*Frameworks/AppKit.framework/Versions/C/AppKit - obj:*Frameworks/AppKit.framework/Versions/C/AppKit -} - -{ - OSX108:CoreFoundation/HIToolbox/HIToolbox - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*HIToolbox.framework/Versions/A/HIToolbox - obj:*HIToolbox.framework/Versions/A/HIToolbox -} - -{ - OSX108:libsystem_kernel/CoreGraphics-1 - Memcheck:Cond - obj:/usr/lib/system/libsystem_kernel.dylib - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics -} - -{ - OSX108:libsystem_kernel/CoreGraphics-2 - Memcheck:Param - msg->desc.port.name - obj:/usr/lib/system/libsystem_kernel.dylib - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics -} - -{ - OSX108:libsystem_kernel/CoreFoundation/CoreFoundation/LaunchServices - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*LaunchServices.framework/Versions/A/LaunchServices -} - -{ - OSX108:CoreFoundation/AE/AE - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*AE.framework/Versions/A/AE - obj:*AE.framework/Versions/A/AE -} - -{ - OSX108:CoreGraphics/CoreGraphics/CoreGraphics - Memcheck:Param - msg->desc.port.name - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics - obj:*CoreGraphics.framework/Versions/A/CoreGraphics -} - -{ - OSX108:CoreFoundation/Foundation/AppKit - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*Foundation.framework/Versions/C/Foundation - obj:*Frameworks/AppKit.framework/Versions/C/AppKit -} - -{ - OSX108:CoreFoundation/CoreFoundation/HIToolbox - Memcheck:Cond - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*CoreFoundation.framework/Versions/A/CoreFoundation - obj:*HIToolbox.framework/Versions/A/HIToolbox -} - -{ - OSX108:HIServices/HIToolbox/HIToolbox - Memcheck:Cond - obj:*HIServices.framework/Versions/A/HIServices - obj:*HIToolbox.framework/Versions/A/HIToolbox - obj:*HIToolbox.framework/Versions/A/HIToolbox -} - -{ - OSX108:AppKit-1 - Memcheck:Cond - obj:*AppKit.framework/Versions/C/AppKit - obj:*AppKit.framework/Versions/C/AppKit - obj:*AppKit.framework/Versions/C/AppKit -} - -{ - OSX108:32bit:_libxpc_initializer - Memcheck:Cond - fun:_libxpc_initializer - fun:libSystem_initializer - fun:*ImageLoaderMachO*doModInitFunctions* -} - -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ - macos-__pthread_rwlock_init-see-our-bug-196528 - Memcheck:Cond - fun:pthread_rwlock_init -} - -######################################################### -## Leaks (apparently) in even hello-world style programs - -{ - OSX108:leak-1 - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_malloc - fun:_ZN4objc8DenseMapIP11objc_objectmL* - fun:arr_init -} - -{ - OSX108:leak-2 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:*NX*Map* -} - -{ - OSX108:leak-3 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:*image* -} - -{ - OSX108:leak-4 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:*remap* -} - -{ - OSX108:leak-5 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:*future* -} - -{ - OSX108:leak-6 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*strdup* - fun:*NX*Map* -} - -{ - OSX108:leak-7 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:*attached* -} - -{ - OSX108:leak-8 - Memcheck:Leak - fun:malloc_zone_malloc - fun:*NX*Map* - fun:dlopen -} - -{ - OSX108:leak-9 - Memcheck:Leak - fun:malloc - fun:*PerThread* - fun:dlopen -} - -{ - OSX108:leak-10 - Memcheck:Leak - fun:malloc_zone_calloc - fun:*NX*Hash* -} - -{ - OSX108:leak-11 - Memcheck:Leak - fun:malloc_zone_calloc - fun:*map* - fun:*map* -} - -{ - OSX108:leak-12 - Memcheck:Leak - fun:malloc_zone_calloc - fun:*fetch_pthread_data* -} - -{ - OSX108:leak-13 - Memcheck:Leak - fun:malloc_zone_malloc - fun:recursive_mutex_init - fun:_objc_init -} - -{ - OSX108:leak-14 - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX108:leak-15 - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX108:leak-16 - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX108:leak-17 - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX108:leak-18 - Memcheck:Leak - match-leak-kinds: indirect - fun:malloc_zone_?alloc - ... - fun:libSystem_initializer -} - -{ - OSX108:leak-19 - Memcheck:Leak - match-leak-kinds: indirect - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX108:leak-20 - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:libSystem_initializer -} - -{ - OSX108:leak-21 - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX108:leak-22 - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:_libxpc_initializer -} - -{ - OSX108:leak-23 - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:realloc - fun:new_sem_from_pool -} - -##----------------------------------------------------------------------## -# Memcheck -##----------------------------------------------------------------------## - diff --git a/darwin13.supp b/darwin13.supp deleted file mode 100644 index 41478738f7..0000000000 --- a/darwin13.supp +++ /dev/null @@ -1,278 +0,0 @@ - -# Suppressions for Darwin 13.x / Mac OS X 10.9 Mavericks - -############################################ -## Leaks. For other stuff see below. - -{ - OSX109:1-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:_read_images -} - -{ - OSX109:2-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:?alloc - ... - fun:_ZN4dyld24initializeMainExecutableEv -} - -{ - OSX109:3-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_?alloc - fun:recursive_mutex_init - fun:_objc_init - fun:_os_object_init - fun:libSystem_initializer -} - -{ - OSX109:4-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX109:5-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX109:6-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX109:7-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX109:8-Leak - Memcheck:Leak - match-leak-kinds: indirect - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX109:9-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:libSystem_initializer -} - -{ - OSX109:10-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX109:11-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:currentlocale -} - -{ - OSX109:12-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - fun:tzsetwall_basic - fun:_st_tzset_basic -} - -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:_owned_ptr_alloc - fun:setenv -} - -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ - macos-__pthread_rwlock_init-see-our-bug-196528 - Memcheck:Cond - fun:pthread_rwlock_init -} - -############################################ -## Non-leak errors - -{ - OSX109:AppKit-1 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX109:AppKit-2 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* -} - -{ - OSX109:AppKit-3 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX109:ColorSync-1 - Memcheck:Cond - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* -} - -{ - OSX109:ColorSync-2 - Memcheck:Value8 - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* -} - -{ - OSX109:CoreGraphics-1 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* -} - -{ - OSX109:CoreGraphics-2 - Memcheck:Value8 - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* -} - -{ - OSX109:CoreGraphics-3 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*libRIP* - obj:*CoreGraphics.framework*libRIP* -} - -{ - OSX109:CoreGraphics-4 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*libRIP* -} - -{ - OSX109:CoreGraphics-5 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX109:dyld-2 - Memcheck:Cond - obj:/usr/lib/dyld - obj:/usr/lib/dyld - obj:/usr/lib/dyld -} - -{ - OSX109:HIServices-1 - Memcheck:Cond - obj:*HIServices.framework*HIServices* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX109:LaunchServices-1 - Memcheck:Cond - obj:*LaunchServices.framework*LaunchServices* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX109:QuartzCore-1 - Memcheck:Cond - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore -} - -{ - OSX109:vImage-1 - Memcheck:Cond - obj:*vImage.framework*vImage* - obj:*vImage.framework*vImage* - obj:*CoreGraphics.framework*CoreGraphics* -} - -{ - OSX109:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} -{ - OSX109:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -{ - OSX109:32bit:_libxpc_initializer - Memcheck:Cond - fun:_libxpc_initializer - fun:libSystem_initializer - fun:*ImageLoaderMachO*doModInitFunctions* -} diff --git a/darwin14.supp b/darwin14.supp deleted file mode 100644 index 8ba4e9d71e..0000000000 --- a/darwin14.supp +++ /dev/null @@ -1,674 +0,0 @@ - -# Suppressions for Darwin 14.x / Mac OS X 10.10 Yosemite - -############################################ -## Leaks. For other stuff see below. - -{ - OSX1010:1-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:_read_images -} - -#{ -# OSX1010:2-Leak -# Memcheck:Leak -# match-leak-kinds: definite -# fun:?alloc -# ... -# fun:_ZN4dyld24initializeMainExecutableEv -#} - -{ - OSX1010:3-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_?alloc - fun:recursive_mutex_init - ... - fun:_os_object_init - fun:libdispatch_init - fun:libSystem_initializer -} - -#{ -# OSX1010:4-Leak -# Memcheck:Leak -# match-leak-kinds: reachable -# fun:malloc_zone_?alloc -# ... -# fun:dyld_register_image_state_change_handler -# ... -#} - -{ - OSX1010:5-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX1010:6-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX1010:7-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_images -} - -{ - OSX1010:8-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX1010:9-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:libSystem_initializer -} - -{ - OSX1010:10-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_initializer -} - -#{ -# OSX1010:11-Leak -# Memcheck:Leak -# match-leak-kinds: definite -# fun:malloc -# fun:currentlocale -#} -# -#{ -# OSX1010:12-Leak -# Memcheck:Leak -# match-leak-kinds: possible -# fun:malloc -# fun:tzsetwall_basic -# fun:_st_tzset_basic -#} - -{ - OSX1010:13-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_memalign - ... - fun:_ZN4dyld24initializeMainExecutableEv -} - -{ - OSX1010:14-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_atfork_child -} - -{ - OSX1010:15-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:__smakebuf - ... - fun:printf -} - -############################################ -## Non-leak errors - -##{ -## OSX1010:CoreFoundation-1 -## Memcheck:Cond -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - -{ - OSX1010:CoreFoundation-2 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1010:CoreFoundation-3 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1010:CoreFoundation-4 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1010:CoreFoundation-5 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIServices.framework*HIServices* -} - -{ - OSX1010:CoreFoundation-6 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1010:CoreFoundation-7 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1010:CoreFoundation-8 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*IOKit.framework*IOKit* -} - -{ - OSX1010:CoreFoundation-9 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*Foundation.framework*Foundation* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1010:CoreFoundation-10 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1010:CoreFoundation-11 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*AE.framework*AE* - obj:*AE.framework*AE* -} - -{ - OSX1010:CoreFoundation-12 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1010:CoreFoundation-13 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*AE.framework*AE* -} - -{ - OSX1010:AppKit-1 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1010:AppKit-2 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* -} - -#{ -# OSX1010:AppKit-3 -# Memcheck:Cond -# obj:*AppKit.framework*AppKit* -# obj:*libdispatch.dylib* -# obj:*libdispatch.dylib* -#} - -##{ -## OSX1010:AppKit-4 -## Memcheck:Cond -## obj:*AppKit.framework*AppKit* -## obj:*AppKit.framework*AppKit* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - -{ - OSX1010:AppKit-5 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1010:AppKit-6 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1010:AppKit-7 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1010:AppKit-8 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1010:ColorSync-1 - Memcheck:Cond - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* -} - -#{ -# OSX1010:ColorSync-2 -# Memcheck:Value8 -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -#} - -{ - OSX1010:CoreGraphics-1 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* -} - -#{ -# OSX1010:CoreGraphics-2 -# Memcheck:Value8 -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - -{ - OSX1010:CoreGraphics-3 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*libRIP* - obj:*CoreGraphics.framework*libRIP* -} - -#{ -# OSX1010:CoreGraphics-4 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*libRIP* -#} - -{ - OSX1010:CoreGraphics-5 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -#{ -# OSX1010:CoreGraphics-6 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*HIToolbox.framework*HIToolbox* -#} - -{ - OSX1010:HIServices-1 - Memcheck:Cond - obj:*HIServices.framework*HIServices* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1010:LaunchServices-1 - Memcheck:Cond - obj:*LaunchServices.framework*LaunchServices* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1010:LaunchServices-2 - Memcheck:Cond - obj:*LaunchServices.framework*LaunchServices* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1010:QuartzCore-1 - Memcheck:Cond - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore -} - -#{ -# OSX1010:vImage-1 -# Memcheck:Cond -# obj:*vImage.framework*vImage* -# obj:*vImage.framework*vImage* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - -{ - OSX1010:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -{ - OSX1010:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -#{ -# OSX1010:32bit:_libxpc_initializer -# Memcheck:Cond -# fun:_libxpc_initializer -# fun:libSystem_initializer -# fun:*ImageLoaderMachO*doModInitFunctions* -#} - -{ - OSX1010:dyld-1 - Memcheck:Cond - fun:*ImageLoader*weakBind* - fun:*ImageLoader*link* - fun:*dyld*link* -} - -{ - OSX1010:dyld-2 - Memcheck:Cond - fun:exit - obj:*libdyld*dylib* -} - -{ - OSX1010:libsystem_kernel-1 - Memcheck:Cond - obj:*libsystem_kernel*dylib* - obj:*libsystem_kernel*dylib* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1010:CoreServicesInternal-1 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* -} - -{ - OSX1010:CoreServicesInternal-2 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* -} - -{ - OSX1010:CoreServicesInternal-3 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1010:CoreServices-1 - Memcheck:Cond - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* -} - -##{ -## OSX1010:libsystem_pthread-1 -## Memcheck:Cond -## obj:*libsystem_pthread*dylib* -## obj:*ImageIO.framework*ImageIO* -## obj:*ImageIO.framework*ImageIO* -##} - -{ - OSX1010:ApplicationServices-1 - Memcheck:Cond - obj:*ApplicationServices.framework*ATS* - obj:*libsystem_pthread*dylib* - obj:*libsystem_platform*dylib* -} - -{ - OSX1010:HIToolbox-1 - Memcheck:Cond - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1010:RawCamera-1 - Memcheck:Cond - obj:*RawCamera.bundle*RawCamera* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -##{ -## OSX1010:CoreImage-1 -## Memcheck:Cond -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -##} - -##{ -## OSX1010:strncpy-1 -## Memcheck:Cond -## fun:strncpy -## obj:*CoreServicesInternal.framework*CoreServicesInternal -## obj:*CoreServicesInternal.framework*CoreServicesInternal -##} - -{ - OSX1010:pthread_rwlock_init - Memcheck:Cond - fun:pthread_rwlock_init - obj:*ImageIO.framework*ImageIO* - obj:*ImageIO.framework*ImageIO* -} - -{ - OSX1010:CFBasicHash - Memcheck:Value8 - fun:*CFBasicHash* - fun:*CF* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-1-Addr8 - Memcheck:Addr8 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-1-Addr8 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-2-Addr8 - Memcheck:Addr8 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-2-Addr2 - Memcheck:Addr2 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-3-Addr8 - Memcheck:Addr8 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-3-Addr2 - Memcheck:Addr2 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-3-Addr1 - Memcheck:Addr1 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-4 - Memcheck:Addr8 - fun:*platform_bzero* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-6-Addr8 - Memcheck:Addr8 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-6-Addr4 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1010:AppleIntelHD4000GraphicsGLDriver-7 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1010:OSAtomicAdd32 - Memcheck:Addr4 - fun:*OSAtomicAdd32* - obj:*IOAccelerator.framework*IOAccelerator* - obj:*GPUSupport.framework*GPUSupportMercury* -} - -{ - OSX1010:IOAccelerator-1 - Memcheck:Addr4 - obj:*IOAccelerator.framework*IOAccelerator* - obj:*GPUSupport.framework*GPUSupportMercury* -} - -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:_owned_ptr_alloc - fun:setenv -} - -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ -macos-__pthread_rwlock_init-see-our-bug-196528 -Memcheck:Cond -fun:pthread_rwlock_init -} diff --git a/darwin15.supp b/darwin15.supp deleted file mode 100644 index 159e7f66c9..0000000000 --- a/darwin15.supp +++ /dev/null @@ -1,730 +0,0 @@ - -# Suppressions for Darwin 15.x / Mac OS X 10.11 El Capitan - -############################################ -## Leaks. For other stuff see below. - -{ - OSX1011:1-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:_read_images -} - -{ - OSX1011:2-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_?alloc - ... - fun:_read_images -} - -{ - OSX1011:3-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_?alloc - fun:recursive_mutex_init - ... - fun:_os_object_init - fun:libdispatch_init - fun:libSystem_initializer -} - -{ - OSX1011:4-Leak - Memcheck:Leak - fun:malloc_zone_?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX1011:5-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:dyld_register_image_state_change_handler -} - -{ - OSX1011:6-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_2_images -} - -{ - OSX1011:7-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:map_images_nolock - fun:map_2_images -} - -{ - OSX1011:8-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX1011:9-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:libSystem_initializer -} - -{ - OSX1011:10-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_initializer -} - -#{ -# OSX1011:11-Leak -# Memcheck:Leak -# match-leak-kinds: definite -# fun:malloc -# fun:currentlocale -#} -# -#{ -# OSX1011:12-Leak -# Memcheck:Leak -# match-leak-kinds: possible -# fun:malloc -# fun:tzsetwall_basic -# fun:_st_tzset_basic -#} - -{ - OSX1011:13-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_memalign - ... - fun:_ZN4dyld24initializeMainExecutableEv -} - -{ - OSX1011:14-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:libSystem_atfork_child -} - -{ - OSX1011:15-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:__smakebuf - ... - fun:printf -} - -{ - OSX1011:16-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:?alloc - ... - fun:_read_images -} - -{ - OSX1011:17-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:?alloc - ... - fun:_read_images -} - -{ - OSX1011:18-Leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc_zone_?alloc - ... - fun:_read_images -} - -{ - OSX1011:19-Leak - Memcheck:Leak - match-leak-kinds: possible - fun:malloc_zone_?alloc - ... - fun:*NX*Map* - fun:*NX*Map* -} - -{ - OSX1011:20-Leak - Memcheck:Leak - match-leak-kinds: indirect - fun:?alloc - ... - fun:libSystem_initializer -} - -{ - OSX1011:21-Leak - Memcheck:Leak - match-leak-kinds: definite - fun:malloc_zone_memalign - ... - fun:_ZN4dyld24initializeMainExecutableEv -} - - -############################################ -## Non-leak errors - -##{ -## OSX1011:CoreFoundation-1 -## Memcheck:Cond -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - -{ - OSX1011:CoreFoundation-2 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1011:CoreFoundation-3 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1011:CoreFoundation-4 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1011:CoreFoundation-5 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIServices.framework*HIServices* -} - -{ - OSX1011:CoreFoundation-6 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1011:CoreFoundation-7 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1011:CoreFoundation-8 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*IOKit.framework*IOKit* -} - -{ - OSX1011:CoreFoundation-9 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*Foundation.framework*Foundation* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1011:CoreFoundation-10 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1011:CoreFoundation-11 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*AE.framework*AE* - obj:*AE.framework*AE* -} - -{ - OSX1011:CoreFoundation-12 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1011:CoreFoundation-13 - Memcheck:Cond - obj:*CoreFoundation.framework*CoreFoundation* - obj:*CoreFoundation.framework*CoreFoundation* - obj:*AE.framework*AE* -} - -{ - OSX1011:AppKit-1 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1011:AppKit-2 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* -} - -#{ -# OSX1011:AppKit-3 -# Memcheck:Cond -# obj:*AppKit.framework*AppKit* -# obj:*libdispatch.dylib* -# obj:*libdispatch.dylib* -#} - -##{ -## OSX1011:AppKit-4 -## Memcheck:Cond -## obj:*AppKit.framework*AppKit* -## obj:*AppKit.framework*AppKit* -## obj:*CoreFoundation.framework*CoreFoundation* -##} - -{ - OSX1011:AppKit-5 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1011:AppKit-6 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1011:AppKit-7 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1011:AppKit-8 - Memcheck:Cond - obj:*AppKit.framework*AppKit* - obj:*Foundation.framework*Foundation* - obj:*Foundation.framework*Foundation* -} - -{ - OSX1011:ColorSync-1 - Memcheck:Cond - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* - obj:*ColorSync.framework*ColorSync* -} - -#{ -# OSX1011:ColorSync-2 -# Memcheck:Value8 -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -# obj:*ColorSync.framework*ColorSync* -#} - -{ - OSX1011:CoreGraphics-1 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*CoreGraphics* -} - -#{ -# OSX1011:CoreGraphics-2 -# Memcheck:Value8 -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - -{ - OSX1011:CoreGraphics-3 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*CoreGraphics.framework*libRIP* - obj:*CoreGraphics.framework*libRIP* -} - -#{ -# OSX1011:CoreGraphics-4 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*libRIP* -#} - -{ - OSX1011:CoreGraphics-5 - Memcheck:Cond - obj:*CoreGraphics.framework*CoreGraphics* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -#{ -# OSX1011:CoreGraphics-6 -# Memcheck:Cond -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*CoreGraphics.framework*CoreGraphics* -# obj:*HIToolbox.framework*HIToolbox* -#} - -{ - OSX1011:HIServices-1 - Memcheck:Cond - obj:*HIServices.framework*HIServices* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1011:LaunchServices-1 - Memcheck:Cond - obj:*LaunchServices.framework*LaunchServices* - obj:*AppKit.framework*AppKit* - obj:*AppKit.framework*AppKit* -} - -{ - OSX1011:LaunchServices-2 - Memcheck:Cond - obj:*LaunchServices.framework*LaunchServices* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -{ - OSX1011:QuartzCore-1 - Memcheck:Cond - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore - obj:*QuartzCore.framework*QuartzCore -} - -#{ -# OSX1011:vImage-1 -# Memcheck:Cond -# obj:*vImage.framework*vImage* -# obj:*vImage.framework*vImage* -# obj:*CoreGraphics.framework*CoreGraphics* -#} - -{ - OSX1011:zlib-C - Memcheck:Cond - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -{ - OSX1011:zlib-8 - Memcheck:Value8 - obj:/usr/lib/libz.*dylib - obj:/usr/lib/libz.*dylib -} - -{ - OSX1011:32bit:_libxpc_initializer - Memcheck:Cond - obj:/usr/lib/system/libsystem_c.dylib - obj:/usr/lib/system/libsystem_c.dylib - fun:_libxpc_initializer - obj:/usr/lib/libSystem.B.dylib - fun:*ImageLoaderMachO*doModInitFunctions* -} - -{ - OSX1011:dyld-1 - Memcheck:Cond - fun:*ImageLoader*weakBind* - fun:*ImageLoader*link* - fun:*dyld*link* -} - -{ - OSX1011:dyld-2 - Memcheck:Cond - fun:exit - obj:*libdyld*dylib* -} - -{ - OSX1011:libsystem_kernel-1 - Memcheck:Cond - obj:*libsystem_kernel*dylib* - obj:*libsystem_kernel*dylib* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1011:CoreServicesInternal-1 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* -} - -{ - OSX1011:CoreServicesInternal-2 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* -} - -{ - OSX1011:CoreServicesInternal-3 - Memcheck:Cond - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreServicesInternal.framework*CoreServicesInternal* - obj:*CoreFoundation.framework*CoreFoundation* -} - -{ - OSX1011:CoreServices-1 - Memcheck:Cond - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* - obj:*CoreServices.framework*LaunchServices* -} - -##{ -## OSX1011:libsystem_pthread-1 -## Memcheck:Cond -## obj:*libsystem_pthread*dylib* -## obj:*ImageIO.framework*ImageIO* -## obj:*ImageIO.framework*ImageIO* -##} - -{ - OSX1011:ApplicationServices-1 - Memcheck:Cond - obj:*ApplicationServices.framework*ATS* - obj:*libsystem_pthread*dylib* - obj:*libsystem_platform*dylib* -} - -{ - OSX1011:HIToolbox-1 - Memcheck:Cond - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* - obj:*HIToolbox.framework*HIToolbox* -} - -{ - OSX1011:RawCamera-1 - Memcheck:Cond - obj:*RawCamera.bundle*RawCamera* - obj:*libdispatch.dylib* - obj:*libdispatch.dylib* -} - -##{ -## OSX1011:CoreImage-1 -## Memcheck:Cond -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -## obj:*CoreImage.framework*CoreImage* -##} - -##{ -## OSX1011:strncpy-1 -## Memcheck:Cond -## fun:strncpy -## obj:*CoreServicesInternal.framework*CoreServicesInternal -## obj:*CoreServicesInternal.framework*CoreServicesInternal -##} - -{ - OSX1011:pthread_rwlock_init - Memcheck:Cond - fun:pthread_rwlock_init - obj:*ImageIO.framework*ImageIO* - obj:*ImageIO.framework*ImageIO* -} - -{ - OSX1011:CFBasicHash - Memcheck:Value8 - fun:*CFBasicHash* - fun:*CF* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-1-Addr8 - Memcheck:Addr8 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-1-Addr8 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-2-Addr8 - Memcheck:Addr8 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-2-Addr2 - Memcheck:Addr2 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-3-Addr8 - Memcheck:Addr8 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-3-Addr2 - Memcheck:Addr2 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-3-Addr1 - Memcheck:Addr1 - fun:*platform_memmove* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-4 - Memcheck:Addr8 - fun:*platform_bzero* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-6-Addr8 - Memcheck:Addr8 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-6-Addr4 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1011:AppleIntelHD4000GraphicsGLDriver-7 - Memcheck:Addr4 - obj:*AppleIntelHD4000GraphicsGLDriver.bundle*AppleIntelHD4000GraphicsGLDriver* - obj:*GLEngine.bundle*GLEngine* -} - -{ - OSX1011:OSAtomicAdd32 - Memcheck:Addr4 - fun:*OSAtomicAdd32* - obj:*IOAccelerator.framework*IOAccelerator* - obj:*GPUSupport.framework*GPUSupportMercury* -} - -{ - OSX1011:IOAccelerator-1 - Memcheck:Addr4 - obj:*IOAccelerator.framework*IOAccelerator* - obj:*GPUSupport.framework*GPUSupportMercury* -} - -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:_owned_ptr_alloc - fun:setenv -} - -# See https://bugs.kde.org/show_bug.cgi?id=196528 -{ -macos-__pthread_rwlock_init-see-our-bug-196528 -Memcheck:Cond -fun:pthread_rwlock_init -} diff --git a/darwin9-drd.supp b/darwin9-drd.supp deleted file mode 100644 index ea301431b0..0000000000 --- a/darwin9-drd.supp +++ /dev/null @@ -1,469 +0,0 @@ - -# DRD suppressions for Darwin 9.x / Mac OS X 10.5 Leopard - -# -# Suppression patterns for dyld, the dynamic loader. -# - -{ - drd-darwin-dyld-register-func-for-add-image - drd:MutexErr - fun:pthread_mutex_unlock - fun:_dyld_register_func_for_add_image - fun:__keymgr_initializer - fun:libSystem_initializer -} -{ - drd-darwin-dyld-register-func-for-remove-image - drd:MutexErr - fun:pthread_mutex_unlock - fun:_dyld_register_func_for_remove_image - fun:__keymgr_initializer - fun:libSystem_initializer -} -{ - drd-darwin-dyld-GlobalLockInitialize - drd:MutexErr - fun:pthread_mutex_init - fun:_Z24dyldGlobalLockInitializev - fun:_dyld_initializer -} -{ - drd-darwin-dyld-bindLazySymbol - drd:ConflictingAccess - ... - fun:_ZN4dyld14bindLazySymbolEPK11mach_headerPm - fun:stub_binding_helper_interface2 -} -{ - drd-darwin-dyld-addImage - drd:ConflictingAccess - fun:_ZN4dyld8addImageEP11ImageLoader -} -{ - dyld-ImageLoader::link - drd:ConflictingAccess - ... - fun:_ZN4dyld18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE - fun:_ZN11ImageLoader4linkERKNS_11LinkContextEbbRKNS_10RPathChainE - fun:_ZN4dyld4linkEP11ImageLoaderbRKNS0_10RPathChainE -} -{ - drd-darwin-dyld-ImageLoaderMachO::resolveUndefined - drd:ConflictingAccess - ... - fun:_ZN16ImageLoaderMachO16resolveUndefinedERKN11ImageLoader11LinkContextEPK11macho_nlistbPPKS0_ -} -{ - drd-darwin-dyld-ImageLoaderMachO::findExportedSymbol - drd:ConflictingAccess - fun:_ZNK16ImageLoaderMachO18findExportedSymbolEPKcPKvbPPK11ImageLoader - fun:_ZNK11ImageLoader41findExportedSymbolInDependentImagesExceptEPKcPPKS_RS4_S4_S4_ - fun:_ZNK11ImageLoader42findExportedSymbolInImageOrDependentImagesEPKcRKNS_11LinkContextEPPKS_ - fun:dlsym -} - - -# -# Suppression patterns for libc, Darwin's C library. -# - -{ - drd-darwin-libc-cerror - drd:ConflictingAccess - ... - fun:cerror -} -{ - drd-darwin-libc-rand - drd:ConflictingAccess - fun:do_rand -} -{ - drd-darwin-libc-vfprintf-1 - drd:ConflictingAccess - fun:vfprintf_l -} -{ - drd-darwin-libc-vfprintf-2 - drd:ConflictingAccess - fun:__vfprintf -} -{ - drd-darwin-libc-localeconv - drd:ConflictingAccess - fun:localeconv_l -} -{ - drd-darwin-libc-fwrite - drd:ConflictingAccess - ... - fun:fwrite$UNIX2003 -} -{ - drd-darwin-cxa-guard-acquire - drd:ConflictingAccess - obj:* - fun:__cxa_current_exception_type - fun:__cxa_guard_acquire -} -{ - drd-darwin-cxa-guard-release - drd:ConflictingAccess - fun:__cxa_guard_release -} -{ - drd-darwin-cxa-finalize - drd:MutexErr - fun:pthread_mutex_destroy - fun:__tcf_115 - fun:__cxa_finalize - fun:exit -} -{ - drd-darwin-atexit-register - drd:ConflictingAccess - fun:atexit_register -} -{ - drd-darwin-opendir - drd:ConflictingAccess - fun:telldir$UNIX2003 - fun:__opendir2$UNIX2003 - fun:opendir$UNIX2003 -} -{ - drd-darwin-readdir - drd:ConflictingAccess - fun:readdir -} -{ - drd-darwin-closedir - drd:ConflictingAccess - fun:closedir$UNIX2003 -} -{ - drd:darwin-ptrace - drd:ConflictingAccess - fun:ptrace -} - - -# -# Suppression patterns for libpthread, Darwin's POSIX threads implementation. -# - -{ - drd-darwin-pthread-create-1 - drd:ConflictingAccess - obj:* - fun:thread_start -} -{ - drd-darwin-pthread-create-2 - drd:ConflictingAccess - ... - fun:pthread_create* -} -{ - drd-darwin-pthread-join-1 - drd:ConflictingAccess - ... - fun:pthread_join$UNIX2003 -} -{ - drd-darwin-pthread-exit - drd:ConflictingAccess - ... - fun:_pthread_exit -} -{ - drd-darwin-pthread-find-thread - drd:ConflictingAccess - fun:_pthread_find_thread -} -{ - drd-darwin-pthread-spin-unlock - drd:ConflictingAccess - fun:spin_unlock -} -{ - drd-darwin-pthread-testcancel - drd:ConflictingAccess - fun:_pthread_testcancel -} -{ - drd-darwin-pthread-detach - drd:ConflictingAccess - ... - fun:pthread_detach -} -{ - drd-darwin-pthread-detach - drd:CondRaceErr - ... - fun:pthread_detach -} -{ - drd-darwin-pthread-kill - drd:ConflictingAccess - ... - fun:pthread_kill -} -{ - drd-darwin-pthread-free-pthread-onstack - drd:ConflictingAccess - fun:mig_dealloc_reply_port - fun:_pthread_free_pthread_onstack -} -{ - drd-darwin-pthread-mach-thread-np - drd:ConflictingAccess - ... - fun:pthread_mach_thread_np -} -{ - drd-darwin-pthread-key-create - drd:ConflictingAccess - fun:pthread_key_create -} - - -# -# Suppression patterns for libobjc. -# - -# It looks like the implementation of objc_msgSend uses another means than the -# POSIX threads library for locking. More information about messaging and -# objc_msgSend can be found here: -# http://devworld.apple.com/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html -# - -{ - drd-darwin-objc-msgSend - drd:ConflictingAccess - ... - fun:objc_msgSend -} -{ - drd-darwin-objc-msgSend - drd:ConflictingAccess - ... - fun:objc_sync_enter -} - - -# -# Suppression patterns for CoreFoundation.framework. -# - -# Suppressions for NSObject methods. For more information about the NSObject -# class, see also -# http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html -{ - drd-darwin-NSObject-release - drd:ConflictingAccess - ... - fun:-[NSObject release] -} -{ - drd-darwin-NSObject-autorelease-1 - drd:ConflictingAccess - ... - fun:-[NSObject(NSObject) autorelease] -} -{ - drd-darwin-NSObject-autorelease-2 - drd:ConflictingAccess - fun:__NSAutoreleaseObject -} -{ - drd-darwin-NSObject-NSDeallocateObject - drd:ConflictingAccess - fun:_internal_object_dispose - fun:NSDeallocateObject -} -{ - drd-darwin-NSObject-retain - drd:ConflictingAccess - ... - fun:-[NSObject retain] -} -{ - drd-darwin-NSObject-retainCount - drd:ConflictingAccess - ... - fun:-[NSObject retainCount] -} -{ - drd-darwin-NSObject-NSDelayedPerforming-1 - drd:ConflictingAccess - ... - fun:+[NSObject(NSDelayedPerforming) cancelPreviousPerformRequestsWithTarget:selector:object:] -} -{ - drd-darwin-NSObject-NSDelayedPerforming-2 - drd:ConflictingAccess - ... - fun:-[NSObject(NSDelayedPerforming) performSelector:withObject:afterDelay:] -} -{ - drd-darwin-NSObject-NSDelayedPerforming-3 - drd:ConflictingAccess - ... - fun:-[NSObject(NSDelayedPerforming) performSelector:withObject:afterDelay:inModes:] -} -{ - drd-darwin-NSObject-NSDelayedPerforming-4 - drd:ConflictingAccess - ... - fun:-[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] -} -{ - drd-darwin-NSObject-NSDelayedPerforming-5 - drd:ConflictingAccess - ... - fun:-[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] -} - -# Suppressions for methods of the NSThread class. -{ - drd-NSThread-nq - drd:ConflictingAccess - ... - fun:-[NSThread _nq:] -} - -# Suppressions for methods of the NSLock class. See also -# http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSLock_Class/Reference/Reference.html -{ - drd-darwin-NSLock-lock - drd:ConflictingAccess - fun:-[NSLock lock] -} -{ - drd-darwin-NSLock-unlock - drd:ConflictingAccess - fun:-[NSLock unlock] -} -# Suppressions for NSCondition methods. -{ - drd-darwin-NSConditionLock-lock - drd:ConflictingAccess - fun:-[NSCondition lock] -} -# Suppressions for NSConditionLock methods. -{ - drd-darwin-NSConditionLock-lockWhenCondition:beforeDate: - drd:ConflictingAccess - fun:-[NSConditionLock lockWhenCondition:beforeDate:] -} - - -# NSExtraRefCount returns the specified object's reference count, and -# NSDecrementExtraRefCountWasZero decrements the specified object's reference -# count. -# See also http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html -{ - drd-darwin-NSExtraRefCount - drd:ConflictingAccess - ... - fun:NSExtraRefCount -} -{ - drd-darwin-NSDecrementExtraRefCountWasZero - drd:ConflictingAccess - ... - fun:NSDecrementExtraRefCountWasZero -} -# For more information about key-value observing, see also the NSKeyValueObserving Protocol Reference: -# http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html -{ - drd-darwin-NSKVONotify - drd:ConflictingAccess - ... - fun:NSKVONotify -} -{ - drd-darwin-NSKVONotifyingEnableForInfoAndKey - drd:ConflictingAccess - ... - fun:_NSKVONotifyingEnableForInfoAndKey -} -# From the NSRunLoop class reference: -# Warning: The NSRunLoop class is generally not considered to be thread-safe -# and its methods should only be called within the context of the current -# thread. You should never try to call the methods of an NSRunLoop object -# running in a different thread, as doing so might cause unexpected results. -# See also the NSRunLoop Class Reference: -# http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html -# { -# drd-darwin-CFRunLoop* -# drd:ConflictingAccess -# ... -# fun:CFRunLoop* -# } -# See also the CFBag reference: -# http://developer.apple.com/documentation/CoreFoundation/Reference/CFBagRef/Reference/reference.html -# { -# drd-darwin-CFBag* -# drd:ConflictingAccess -# fun:CFBag* -# } - -# Suppression patterns for the memory allocation functions in WTF. -{ - drd-WTF::fastCalloc - drd:ConflictingAccess - ... - fun:_ZN3WTF10fastCallocEmm -} -{ - drd-WTF::fastMalloc - drd:ConflictingAccess - ... - fun:_ZN3WTF10fastMallocEm -} -{ - drd-WTF::fastFree - drd:ConflictingAccess - ... - fun:_ZN3WTF8fastFreeEPv -} - -# Suppression patterns for the string manipulation functions in WebCore. -{ - drd-WebCore::StringImpl::init - drd:ConflictingAccess - ... - fun:_ZN7WebCore10StringImpl4initEPKcj -} -{ - drd-WebCore::StringImpl::append - drd:ConflictingAccess - ... - fun:_ZN7WebCore10StringImpl6appendEPKtj -} -{ - drd-WebCore::CString::init - drd:ConflictingAccess - ... - fun:_ZN7WebCore7CString4initEPKcj -} - -# Suppression patterns for the text encoding functions in WebCore. -{ - drd-WebCore::WebCore::TextCodec::~TextCodec() - drd:ConflictingAccess - fun:_ZN7WebCore9TextCodecD2Ev -} -{ - drd-WebCore::TextCodecICU::TextCodecICU - drd:ConflictingAccess - fun:_ZN7WebCore12TextCodecICUC2ERKNS_12TextEncodingE -} -{ - drd-WebCore::TextCodecICU::~TextCodecICU - drd:ConflictingAccess - fun:_ZN7WebCore12TextCodecICUD0Ev -} diff --git a/darwin9.supp b/darwin9.supp deleted file mode 100644 index f7769c7c5b..0000000000 --- a/darwin9.supp +++ /dev/null @@ -1,297 +0,0 @@ - -# Suppressions for Darwin 9.x / Mac OS X 10.5 Leopard - -##----------------------------------------------------------------------## -# Memcheck -##----------------------------------------------------------------------## - -{ - mach_msg_trap-1 - Memcheck:Param - mach_msg(msg.msgh_remote_port) - fun:mach_msg_trap - obj:/System/Library/Frameworks/CoreFoundation* - obj:/System/Library/Frameworks/ApplicationServices* -} - -{ - mach_msg_trap-2 - Memcheck:Param - mach_msg(msg.msgh_remote_port) - fun:mach_msg_trap - obj:/System/Library/Frameworks/CoreFoundation* - obj:/System/Library/Frameworks/CoreServices* -} - -{ - mach_msg_trap-3 - Memcheck:Param - mach_msg(msg.msgh_remote_port) - fun:mach_msg_trap - obj:/System/Library/Frameworks/CoreFoundation* - obj:/System/Library/Frameworks/Carbon* -} - -{ - mach_msg_trap-4 - Memcheck:Param - mach_msg(msg.msgh_remote_port) - fun:mach_msg_trap - obj:/System/Library/Frameworks/CoreFoundation* - obj:/System/Library/Frameworks/CoreFoundation* -} - -{ - mach_msg_trap-5 - Memcheck:Param - mach_msg(msg.msgh_remote_port) - fun:mach_msg_trap - obj:/System/Library/Frameworks/CoreFoundation* - obj:/System/Library/Frameworks/AppKit* -} - -{ - macos-Cond-1 - Memcheck:Cond - fun:GetVariationInfoFromName - obj:/System/Library/Frameworks/ApplicationServices* - obj:/System/Library/Frameworks/ApplicationServices* -} - -{ - macos-Cond-2 - Memcheck:Cond - fun:*PMMutex*Lock* - obj:/System/Library/Frameworks/ApplicationServices* - obj:/System/Library/Frameworks/ApplicationServices* -} - -{ - macos-Cond-3 - Memcheck:Cond - fun:sseCGSBlendXXXX8888 - obj:/System/Library/Frameworks/ApplicationServices* - obj:/System/Library/Frameworks/ApplicationServices* -} - -{ - macos-Cond-4 - Memcheck:Cond - fun:*CASettingsStorage*RefreshSettings* - obj:/System/Library/Frameworks/CoreAudio* - obj:/System/Library/Frameworks/CoreAudio* -} - -{ - macos-Cond-5 - Memcheck:Cond - fun:gle* - obj:/System/Library/Frameworks/OpenGL* - obj:/System/Library/Frameworks/OpenGL* -} - -{ - macos-Cond-6 - Memcheck:Cond - fun:pthread_rwlock_init$UNIX2003 - fun:main -} - -# afaict this is legit. Might be caused by setenv("VAR=") -# where the value string is empty (not sure) -{ - macos-Cond-7 - Memcheck:Cond - fun:__setenv - fun:putenv* -} - -{ - macos-futimes-1 - Memcheck:Param - futimes(tvp[1]) - fun:futimes - obj:/usr/lib/libSystem* - obj:/usr/lib/libSystem* -} - -{ - macos-vsyslog-hole - Memcheck:Param - socketcall.sendto(msg) - fun:sendto$NOCANCEL$UNIX2003 - fun:vsyslog -} - -# Still-reachable memory. - -# I chopped this one off at libSystem_initializer, there were more frames. -{ - darwin-still-reachable-1 - Memcheck:Leak - fun:calloc - fun:dwarf2_unwind_dyld_add_image_hook - fun:_ZN4dyld19registerAddCallbackEPFvPK11mach_headerlE - fun:_dyld_register_func_for_add_image - fun:__keymgr_initializer - fun:libSystem_initializer -} - -# I chopped this one off at libSystem_initializer, there were more frames. -{ - darwin-still-reachable-2 - Memcheck:Leak - fun:malloc - fun:get_or_create_key_element - fun:_keymgr_get_and_lock_processwide_ptr_2 - fun:dwarf2_unwind_dyld_add_image_hook - fun:_ZN4dyld19registerAddCallbackEPFvPK11mach_headerlE - fun:_dyld_register_func_for_add_image - fun:__keymgr_initializer - fun:libSystem_initializer -} - -{ - darwin-still-reachable-3 - Memcheck:Leak - fun:malloc - fun:__smakebuf - fun:__swsetup - fun:__sfvwrite - fun:puts -} - -# Genuine leaks. -# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's -# unavoidable due to BSD setenv() semantics. -{ - macos-__setenv-leak-see-our-bug-188572 - Memcheck:Leak - fun:malloc_zone_malloc - fun:__setenv - fun:setenv$UNIX2003 -} -{ - macos-localeconv-leak - Memcheck:Leak - fun:malloc - fun:localeconv_l - fun:__vfprintf - fun:vsnprintf -} - -{ - macos-TFontFeatures::TFontFeatures(unsigned long)-uninitialised-stack-val - Memcheck:Cond - fun:_ZN13TFontFeaturesC2Em - fun:_ZNK9TBaseFont12CopyFeaturesEv -} - -# Conditional jump or move depends on uninitialised value(s) -# at 0x4E5CD59: _DPSNextEvent (in /System/Library/Frameworks -# /AppKit.framework/Versions/C/AppKit) -# by 0x4E5BF87: -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] -# (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit) -# by 0x4E54F9E: -[NSApplication run] (in /System/Library/Frameworks -# /AppKit.framework/Versions/C/AppKit) -# Uninitialised value was created by a stack allocation -# at 0x4E5C450: _DPSNextEvent (in /System/Library/Frameworks -# /AppKit.framework/Versions/C/AppKit) -{ - macos-_DPSNextEvent-stack-allocated-uninit - Memcheck:Cond - fun:_DPSNextEvent -} - - -##----------------------------------------------------------------------## -# Helgrind -##----------------------------------------------------------------------## - -# These ones were necessary to give no errors on a tiny non-threaded -# program. I don't know if they're real problems or false positives (njn). - -# keymgr seems to deliberately do some bogus actions, and if they are bogus, -# it passes the error codes back to the caller. -{ - __keymgr_initializer lock failed - Helgrind:PthAPIerror - fun:pthread_mutex_lock - fun:_dyld_register_func_for_*_image - fun:__keymgr_initializer - fun:libSystem_initializer -} -{ - __keymgr_initializer unlock failed - Helgrind:PthAPIerror - fun:pthread_mutex_unlock - fun:_dyld_register_func_for_*_image - fun:__keymgr_initializer - fun:libSystem_initializer -} -{ - __keymgr_initializer bogus unlock - Helgrind:UnlockBogus - fun:pthread_mutex_unlock - fun:_dyld_register_func_for_*_image - fun:__keymgr_initializer - fun:libSystem_initializer -} - -# These ones were necessary to give no errors on a tiny threaded program. -# I don't know if they're real problems or false positives (njn). - -#{ -# helgrind-darwinlibc-nuke-everything-in-dyld -# Helgrind:Race -# obj:/usr/lib/dyld -#} - -{ - helgrind-darwinlibc-nuke-everything-in-libSystem.B.dylib - Helgrind:Race - obj:/usr/lib/libSystem.B.dylib -} - -# This would be better as "fun:\?\?\?" but string matching doesn't seem to -# allow escaping meta-chars. -# -# This is very bad .. not only will it hide races in any -# un-identified piece of code, the ??? also matches any 3-char -# function name. -{ - helgrind-darwinlibc-nuke-everything-in-???-(unknown-code) - Helgrind:Race - fun:??? -} - -{ - helgrind-darwinlibc--mythread_wrapper-*thread*start* - Helgrind:Race - fun:mythread_wrapper - fun:*thread*start* -} - -{ - helgrind-darwinlibc--pthread_create_WRK-pthread_create - Helgrind:Race - fun:pthread_create_WRK - fun:pthread_create -} - - -# Thread #9: Bug in libpthread: recursive write lock granted on -# mutex/wrlock which does not support recursion -# at 0x18696: pthread_cond_wait* (hg_intercepts.c:655) -# by 0x2300B8: pthread_rwlock_wrlock$UNIX2003 (in /usr/lib/libSystem.B.dylib) -# by 0x18F41: pthread_rwlock_wrlock* (hg_intercepts.c:1177) -# -# no idea what this is about -# -{ - helgrind-darwin9--pthread-rwlock-kludgery - Helgrind:Misc - fun:pthread_cond_wait* - fun:pthread_rwlock_*lock* - fun:pthread_rwlock_*lock* -} diff --git a/dhat/tests/Makefile.am b/dhat/tests/Makefile.am index aba7f06fdf..2b183782cc 100644 --- a/dhat/tests/Makefile.am +++ b/dhat/tests/Makefile.am @@ -12,8 +12,7 @@ EXTRA_DIST = \ empty.stderr.exp empty.vgtest \ sig.stderr.exp sig.vgtest \ single.stderr.exp single.vgtest \ - user_histo1.stderr.exp user_histo1.vgtest \ - user_histo1.stdout.exp + user_histo1.stderr.exp user_histo1.vgtest check_PROGRAMS = \ acc \ diff --git a/dhat/tests/user_histo1.stdout.exp b/dhat/tests/user_histo1.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/Makefile.am b/docs/Makefile.am index 7e5ed389c5..6eefe186fc 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -66,6 +66,7 @@ EXTRA_DIST = \ internals/Darwin-debug.txt \ internals/Darwin-notes.txt \ internals/SPEC-notes.txt \ + internals/client_syscall_arguments.txt \ internals/directory-structure.txt \ internals/git-HOWTO.txt \ internals/howto_BUILD_KDE42.txt \ @@ -206,7 +207,7 @@ MANPAGES_XML_FILES = $(myxmldir)/manpages-index.xml \ all-docs: FAQ.txt man-pages html-docs print-docs valid-manual: $(MANUAL_XML_FILES) - if type $(XMLLINT) 2>/dev/null; then \ + if command -v $(XMLLINT) >/dev/null; then \ if [ -f $(XML_CATALOG_FILES) ]; then \ export XML_CATALOG_FILES=$(XML_CATALOG_FILES) && \ $(XMLLINT) $(XMLLINT_FLAGS) $(myxmldir)/index.xml && \ @@ -215,7 +216,7 @@ valid-manual: $(MANUAL_XML_FILES) fi valid-manpages: $(MANPAGES_XML_FILES) - if type $(XMLLINT) 2>/dev/null; then \ + if command -v $(XMLLINT) >/dev/null; then \ if [ -f $(XML_CATALOG_FILES) ]; then \ export XML_CATALOG_FILES=$(XML_CATALOG_FILES) && \ $(XMLLINT) $(XMLLINT_FLAGS) $(myxmldir)/manpages-index.xml && \ diff --git a/docs/internals/3_1_BUGSTATUS.txt b/docs/internals/3_1_BUGSTATUS.txt index 6add0ccac0..4134c3cb9c 100644 --- a/docs/internals/3_1_BUGSTATUS.txt +++ b/docs/internals/3_1_BUGSTATUS.txt @@ -54,7 +54,7 @@ v5877 fixed 126217 increase # threads v5880 fixed n-i-bz vectorise copy_address_range_state n-i-bz mpicc -fpic bug (Goedeken Richard, inbox) vx1611 fixed 126243 vex x86->IR: popw mem - low 125265 vex x86->IR: 0xD9 0xD0 (fnop) + low 126256 vex x86->IR: 0xD9 0xD0 (fnop) low 126257 vex x86->IR: 0xF2 0x0F 0xF0 0x40 (lddqu) (sse3) low 126258 vex x86->IR: 0xDF 0x4D (fisttp) (sse3) 126384 rdpmc diff --git a/docs/internals/Darwin-notes.txt b/docs/internals/Darwin-notes.txt index 8c320a35be..0cedd16981 100644 --- a/docs/internals/Darwin-notes.txt +++ b/docs/internals/Darwin-notes.txt @@ -58,13 +58,23 @@ storage.c to choose between symbol table names vs. Dwarf3 names. So this machinery was removed in r10155. +Mac OS X / macOS supported platforms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since January 2025 (and thus Valgrind 3.25) we have required a compiler +that supports C11. See 42eb19c0da3bb280de88b7f8fc9b7caaa44aedfem for +details. We also need an xcrun that supports --show-sdk-path (since +December 2025). I'm not sure when both of those became supported. +Definitely neither are on Mac OS 10.7 with XCode 4.6.3. And equally +definitely both are supported on macOS 10.13 with XCode 10.1. That +means that I don't know which is the oldest version of macOS that +will build Valgrind (as of December 2025). Somewhere between 10.8 (Darwin 12) +and 10.12 (Darwin 16). + + Valgrind-developer notes, todos re the MacOSX port ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* m_syswrap/syscall-amd64-darwin.S - - correct signal mask is not applied during syscall - - restart-labels are completely bogus - * m_syswrap/syswrap-darwin.c: - PRE(sys_posix_spawn) completely ignores signal issues, and also ignores the file_actions argument @@ -95,12 +105,6 @@ Valgrind-developer notes, todos re the MacOSX port -------- -m_main doesn't read symbols for the valgrind exe itself, which is -annoying. On minimal investigation it seems that the executable isn't -even listed by aspacem. This is very strange and not in accordance -with the Linux or AIX ports. - - m_main: relatedly, Darwin version does not collect/give out initial debuginfo handles; hence ptrcheck won't work diff --git a/docs/internals/client_syscall_arguments.txt b/docs/internals/client_syscall_arguments.txt new file mode 100644 index 0000000000..233d332122 --- /dev/null +++ b/docs/internals/client_syscall_arguments.txt @@ -0,0 +1,113 @@ +Client Syscall Arguments +======================== + +This document describes how Valgrind handles arguments for client syscalls. +Everything described here takes place in VG_(client_syscall), syswrap-main.c. + + +Data Structures +~~~~~~~~~~~~~~~ + +There are 3 data structures that get used during the argument handling. + +1. VexGuestArchState, the usual storage for registers. +2. SyscallArgLayout, contains info about where the arguments are. +3. SyscallArgs (two copies in SyscallInfo), contains the argument values. + +Flow +~~~~ + +The main steps in the function are to call the PRE syscall wrapper. +That may perform the syscall (or simulate the syscall) and it may +also mark the syscall as blocking. If the PRE did not mark the syscall +as completed it will proceed to either make a non-blocking or a blocking +call. Lastly the POST gets called, if required. + +All of the above can be complicated by the fact that some platforms have +a "syscall syscall". Most platforms have a libc function called "syscall()". +On some platforms libc shuffles the arguments and just performs the +requested syscall directly . Other platforms have a syscall for performing syscalls. +There may even be more than one such syscall. In these cases it is the kernel +that shuffles the arguments to pass them on to the appropriate +syscall. + +The main platforms that have a "syscall syscall" are Darwin and FreeBSD. +Linux mips32 also has some special handling for syscall syscall. + +In Valgrind when there is a "syscall syscall" we don't want to just pass +all of the parameters through. If we did that then "syscall syscall" PRE wrapper +would need to handle all other kinds of syscalls, probably by some kind +of second level of recursive call. This is not the approach that has been taken. +Instead the arguments get "canonicalised" so that the PRE sees "syscall(SYS_write)" +is if it were just a normal direct write syscall. + +The argument layout for such "syscall syscalls" is the same as normal syscalls +but offset by one in register/stack positions. The first argument will be that for +syscall or __syscall. The second argument will be the target normal syscall +followed by the target arguments. + + +Flow in Detail +~~~~~~~~~~~~~~ + +1. Get the canonical arguments. +Call getSyscallArgsFromGuestState() +This stores the canonical arguments (syscall syscall format gets shuffled) +in the SyscallArgs structure. + +2. Get the syscall argument layout +Call getSyscallArgLayout() +This just initialises the fields of the SyscallArgLayout structure. The layout +will be different depending if it is a normal syscall or a syscall syscall. +It cannot be canonicalised - we can shuffle around the values but we can't +shuffle around where they are stored. + +4. Call the syscall PRE wrapper +The argument values are passed in a pointer to SyscallArgs. The fields of that +structure are used by the ARGX and SARGX macros to access the argument values +in the wrapper. + +The argument layout is passed in a pointer to SyscallArgLayout. The fields of +this structure are used indirectly by the PRE_REG_READX macros (X being an +integer for the argument position) For each argument the PRE_REG_READX macro +uses a PRAX macro which in turn uses either PSRAn for stack accesses or +PRRAn for register accesses. In the case of amd64 the location of argument 6 +depends on whether it is a normal syscall or a syscall syscall. In the former +case it will be in a register. In the latter case it will be on the stack. +There is special handling for this case. + +If the syscall has not been completed by the PRE then either step 5 or step 6 +will be executed for blocking and non-blocking syscalls respectively. + +5. Perform a blocking syscall +This is the more complicated of the two as we need to release the global lock, +change to using the guest signal mask, do the syscall, restore the Valgrind +signal mask and request the global lock again. + +A call to putSyscallArgsIntoGuestState() is made. The PRE may have changed +some of the arguments so we need to put the arguments back into +VexGuestArchState. + +The syscall (and the signal mask handling) is performed in a call to +do_syscall_for_client(). This takes the arguments other than the syscall number +from VexGuestArchState. + +6. Perform a non-blocking syscall. + +This is much simpler. It performs the syscall via VG_(do_syscall)(). +The arguments are passed via struct SyscallArgs (possibly modified by the PRE +wrapper). + +7. Call VG_(post_syscall)() +This will call the POST wrapper if required. + +Future Work +~~~~~~~~~~~ + +The flow would be simpler if do_syscall_for_client() used struct SyscallArgs +to get the arg values like VG_(do_syscall). That would avoid having to +put modified arguments back into the guest state. I have not checked, but +I am not certain that the modified guest state is not visible after the syscall. + +The handling of "syscall syscall" does an excessive amount of shuffling, +especially for the syscall number. I think that this can be simplified. diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv index abee097ace..08620375d0 100644 --- a/docs/internals/s390-opcodes.csv +++ b/docs/internals/s390-opcodes.csv @@ -1768,73 +1768,73 @@ lpswey,"load PSW extended",N/A,"privileged instruction" lbear,"load bear",N/A,"privileged instruction" stbear,"store bear",N/A,"privileged instruction" qpaci,"query processor activity counter information",N/A,"privileged instruction" -bdepg,"bit deposit","not implemented",arch15 -bextg,"bit extract","not implemented",arch15 +bdepg,"bit deposit",implemented,arch15 +bextg,"bit extract",implemented,arch15 cal,"compare and load 32","not implemented",arch15 calg,"compare and load 64","not implemented",arch15 calgf,"compare and load 64<32","not implemented",arch15 -clzg,"count leading zeros","not implemented",arch15 -ctzg,"count trailing zeros","not implemented",arch15 -llxab,"load logical indexed address (shift left 0)","not implemented",arch15 -llxah,"load logical indexed address (shift left 1)","not implemented",arch15 -llxaf,"load logical indexed address (shift left 2)","not implemented",arch15 -llxag,"load logical indexed address (shift left 3)","not implemented",arch15 -llxaq,"load logical indexed address (shift left 4)","not implemented",arch15 -lxab,"load indexed address (shift left 0)","not implemented",arch15 -lxah,"load indexed address (shift left 1)","not implemented",arch15 -lxaf,"load indexed address (shift left 2)","not implemented",arch15 -lxag,"load indexed address (shift left 3)","not implemented",arch15 -lxaq,"load indexed address (shift left 4)","not implemented",arch15 +clzg,"count leading zeros",implemented,arch15 +ctzg,"count trailing zeros",implemented,arch15 +llxab,"load logical indexed address (shift left 0)",implemented,arch15 +llxah,"load logical indexed address (shift left 1)",implemented,arch15 +llxaf,"load logical indexed address (shift left 2)",implemented,arch15 +llxag,"load logical indexed address (shift left 3)",implemented,arch15 +llxaq,"load logical indexed address (shift left 4)",implemented,arch15 +lxab,"load indexed address (shift left 0)",implemented,arch15 +lxah,"load indexed address (shift left 1)",implemented,arch15 +lxaf,"load indexed address (shift left 2)",implemented,arch15 +lxag,"load indexed address (shift left 3)",implemented,arch15 +lxaq,"load indexed address (shift left 4)",implemented,arch15 pfcr,"perform functions with concurrent results","not implemented",arch15 -vblend,"vector blend","not implemented",arch15 +vblend,"vector blend",implemented,arch15 vcvbq,"vector convert to binary 128 bit","not implemented",arch15 vcvdq,"vector convert to decimal 128 bit","not implemented",arch15 -vd,"vector divide","not implemented",arch15 -vdl,"vector divide logical","not implemented",arch15 -veval,"vector evaluate","not implemented",arch15 -vgem,"vector generate element masks","not implemented",arch15 -vr,"vector remainder","not implemented",arch15 -vrl,"vector remainder logical","not implemented",arch15 +vd,"vector divide",implemented,arch15 +vdl,"vector divide logical",implemented,arch15 +veval,"vector evaluate",implemented,arch15 +vgem,"vector generate element masks",implemented,arch15 +vr,"vector remainder",implemented,arch15 +vrl,"vector remainder logical",implemented,arch15 vtz,"vector test zoned","not implemented",arch15 -vavgq,"vector average quadword","not implemented",arch15 -vavglq,"vector average logical quadword","not implemented",arch15 -vecq,"vector element compare quadword","not implemented",arch15 -veclq,"vector element compare logical quadword","not implemented",arch15 -vceqq,"vector compare equal quadword","not implemented",arch15 -vceqqs,"vector compare equal quadword","not implemented",arch15 -vchq,"vector compare high quadword","not implemented",arch15 -vchqs,"vector compare high quadword","not implemented",arch15 -vchlq,"vector compare high logical quadword","not implemented",arch15 -vchlqs,"vector compare high logical quadword","not implemented",arch15 -vclzq,"vector count leading zeros quadword","not implemented",arch15 -vctzq,"vector count trailing zeros quadword","not implemented",arch15 -vlcq,"vector load complement quadword","not implemented",arch15 -vlpq,"vector load positive quadword","not implemented",arch15 -vmxq,"vector maximum quadword","not implemented",arch15 -vmxlq,"vector maximum logical quadword","not implemented",arch15 -vmnq,"vector minimum quadword","not implemented",arch15 -vmnlq,"vector minimum logical quadword","not implemented",arch15 -vmalg,"vector multiply and add low doubleword","not implemented",arch15 -vmalq,"vector multiply and add low quadword","not implemented",arch15 -vmahg,"vector multiply and add high doubleword","not implemented",arch15 -vmahq,"vector multiply and add high quadword","not implemented",arch15 -vmalhg,"vector multiply and add logical high doubleword","not implemented",arch15 -vmalhq,"vector multiply and add logical high quadword","not implemented",arch15 -vmaeg,"vector multiply and add even doubleword","not implemented",arch15 -vmaleg,"vector multiply and add logical even doubleword","not implemented",arch15 -vmaog,"vector multiply and add odd doubleword","not implemented",arch15 -vmalog,"vector multiply and add logical odd doubleword","not implemented",arch15 -vmhg,"vector multiply high doubleword","not implemented",arch15 -vmhq,"vector multiply high quadword","not implemented",arch15 -vmlhg,"vector multiply logical high doubleword","not implemented",arch15 -vmlhq,"vector multiply logical high quadword","not implemented",arch15 -vmlg,"vector multiply low doubleword","not implemented",arch15 -vmlq,"vector multiply low quadword","not implemented",arch15 -vmeg,"vector multiply even doubleword","not implemented",arch15 -vmleg,"vector multiply logical even doubleword","not implemented",arch15 -vmog,"vector multiply odd doubleword","not implemented",arch15 -vmlog,"vector multiply logical odd doubleword","not implemented",arch15 -vuphg,"vector unpack high doubleword","not implemented",arch15 -vuplhg,"vector unpack logical high doubleword","not implemented",arch15 -vuplg,"vector unpack low doubleword","not implemented",arch15 -vupllg,"vector unpack logical low doubleword","not implemented",arch15 +vavgq,"vector average quadword",implemented,arch15 +vavglq,"vector average logical quadword",implemented,arch15 +vecq,"vector element compare quadword",implemented,arch15 +veclq,"vector element compare logical quadword",implemented,arch15 +vceqq,"vector compare equal quadword",implemented,arch15 +vceqqs,"vector compare equal quadword",implemented,arch15 +vchq,"vector compare high quadword",implemented,arch15 +vchqs,"vector compare high quadword",implemented,arch15 +vchlq,"vector compare high logical quadword",implemented,arch15 +vchlqs,"vector compare high logical quadword",implemented,arch15 +vclzq,"vector count leading zeros quadword",implemented,arch15 +vctzq,"vector count trailing zeros quadword",implemented,arch15 +vlcq,"vector load complement quadword",implemented,arch15 +vlpq,"vector load positive quadword",implemented,arch15 +vmxq,"vector maximum quadword",implemented,arch15 +vmxlq,"vector maximum logical quadword",implemented,arch15 +vmnq,"vector minimum quadword",implemented,arch15 +vmnlq,"vector minimum logical quadword",implemented,arch15 +vmalg,"vector multiply and add low doubleword",implemented,arch15 +vmalq,"vector multiply and add low quadword",implemented,arch15 +vmahg,"vector multiply and add high doubleword",implemented,arch15 +vmahq,"vector multiply and add high quadword",implemented,arch15 +vmalhg,"vector multiply and add logical high doubleword",implemented,arch15 +vmalhq,"vector multiply and add logical high quadword",implemented,arch15 +vmaeg,"vector multiply and add even doubleword",implemented,arch15 +vmaleg,"vector multiply and add logical even doubleword",implemented,arch15 +vmaog,"vector multiply and add odd doubleword",implemented,arch15 +vmalog,"vector multiply and add logical odd doubleword",implemented,arch15 +vmhg,"vector multiply high doubleword",implemented,arch15 +vmhq,"vector multiply high quadword",implemented,arch15 +vmlhg,"vector multiply logical high doubleword",implemented,arch15 +vmlhq,"vector multiply logical high quadword",implemented,arch15 +vmlg,"vector multiply low doubleword",implemented,arch15 +vmlq,"vector multiply low quadword",implemented,arch15 +vmeg,"vector multiply even doubleword",implemented,arch15 +vmleg,"vector multiply logical even doubleword",implemented,arch15 +vmog,"vector multiply odd doubleword",implemented,arch15 +vmlog,"vector multiply logical odd doubleword",implemented,arch15 +vuphg,"vector unpack high doubleword",implemented,arch15 +vuplhg,"vector unpack logical high doubleword",implemented,arch15 +vuplg,"vector unpack low doubleword",implemented,arch15 +vupllg,"vector unpack logical low doubleword",implemented,arch15 diff --git a/docs/xml/FAQ.xml b/docs/xml/FAQ.xml index 5d458a01be..bd217f4105 100644 --- a/docs/xml/FAQ.xml +++ b/docs/xml/FAQ.xml @@ -497,9 +497,9 @@ int main(void) First, check if you are using an optimized build of Google tcmalloc (part of Google perftools). This library uses a single - alias for free/scalar delete/array delete as an unmeasurable - micro-optimization. There is simply no way for Memcheck to tell - which of these was originally used. There are a few possible + alias for free/scalar delete/array delete as a micro-optimization. + There is simply no way for Memcheck to tell which of these was + originally used. There are a few possible workarounds. @@ -517,7 +517,18 @@ int main(void) - Second, if you are replacing operator new or operator delete + Second, check that you are not using "Identical Code Folding". + The options look like "--icf=all" (or, if you are using a + C or C++ compiler as the linker driver "-Wl,--icf=all"). + This is a feature present in the gold, lld and mold linkers. When this + option is used, the linker will compare the code emitted for functions + and may emit only one function for duplicates. If any of the + C++ "operator new" and "operator delete" overloads are treated in this + manner Memcheck may generate mismatch errors. The solution to this is + not to use identical code folding for builds that you will use for + testing with Valgrind. + + Third, if you are replacing operator new or operator delete make sure that the compiler does not perform optimizations such as inlining on calls to these functions. Such optimizations can prevent Memcheck from correctly identifying the allocator or @@ -546,15 +557,18 @@ int main(void) Why does Valgrind hang when using tcmalloc? - This is because tcmalloc makes a recursive call in its initialisation code. + This is because tcmalloc versions 2.16-2.17 make a recursive call in its initialisation code. Under Valgrind that becomes either an infinite loop with optimised builds of tcmalloc - or a stack overflow crash with debug builds of it. + or a stack overflow crash with debug builds. Your options are: Do not use tcmalloc in the builds that you test with Valgrind. Use an older version of tcmalloc. This problem started on 2024-03-24. If you use gperftools 2.15 or older you should not have this problem. + Use a more recent version of tcmalloc. This problem was fixed on 2025-10-07. + If you use gperftools 2.18 or later you should also not have this problem. + diff --git a/docs/xml/manual-core-adv.xml b/docs/xml/manual-core-adv.xml index 3591cf731f..e7481d50eb 100644 --- a/docs/xml/manual-core-adv.xml +++ b/docs/xml/manual-core-adv.xml @@ -113,6 +113,32 @@ tool-specific macros). + + VALGRIND_REPLACES_MALLOC: + + Returns 1 if the tool replaces malloc (e.g., memcheck). + Returns 0 if the tool does not replace malloc (e.g., cachegrind + and callgrind) or if the executable is not running under VALGRIND. + + + + + + VALGRIND_GET_TOOLNAME: + + Get the running tool name as a string. Takes two arguments, + an input buffer pointer and the length of that buffer. Returns the + required length (including terminating nul) for the tool + name. Returns 0 and the contents supplied buffer are not modified + if not running under Valgrind. The provided buffer may be NULL, + which can be used to query the required buffer length before + making a real request for the tool name. The returned string in + the input buffer will be nul terminated. If given length is too + small to contain the tool name then the name will be truncated. + + + + VALGRIND_COUNT_ERRORS: diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index ea5dee5cc7..ad5c9e1311 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -1207,6 +1207,14 @@ that can report errors, e.g. Memcheck, but not Cachegrind. will make Valgrind run a bit more slowly and take a bit more memory, but can be useful when working with programs with deeply-nested call chains. + + The minimum value for this is 2. A value of 1 is not allowed + for two reasons. Firstly, some of the default suppressions use + "..." which is forbidden with + --num-callers=1. Secondly, it would + make leak suppressions match all allocations using the allocation + function (e.g., malloc). + @@ -1837,6 +1845,23 @@ that can report errors, e.g. Memcheck, but not Cachegrind. + + + + + + By default, Valgrind can handle to up to 500 madvise + guard pages. With thread heavy workloads the default value + might not be sufficient. Use this option to provide a different + limit. E.g. + --max-guard-pages=3000. + If --max-guard-pages is not + set explicitly, then it will default to the + --max-threads setting. + + + + diff --git a/docs/xml/vg-entities.xml.in b/docs/xml/vg-entities.xml.in index 9cf75536db..60c5b38b69 100644 --- a/docs/xml/vg-entities.xml.in +++ b/docs/xml/vg-entities.xml.in @@ -2,7 +2,7 @@ - + diff --git a/drd/drd_hb.h b/drd/drd_hb.h index e7dfe97ab6..fe8956a010 100644 --- a/drd/drd_hb.h +++ b/drd/drd_hb.h @@ -38,8 +38,6 @@ struct hb_info; void DRD_(hb_set_trace)(const Bool trace_hb); struct hb_info* DRD_(hb_get)(const Addr hb); struct hb_info* DRD_(hb_get_or_allocate)(const Addr hb); -void DRD_(hb_init)(const Addr hb); -void DRD_(hb_destroy)(const Addr hb); void DRD_(hb_happens_after)(const DrdThreadId tid, const Addr hb); void DRD_(hb_happens_before)(const DrdThreadId tid, const Addr hb); void DRD_(hb_happens_done)(const DrdThreadId tid, const Addr hb); diff --git a/drd/drd_load_store.c b/drd/drd_load_store.c index 968ec885ef..fe26793530 100644 --- a/drd/drd_load_store.c +++ b/drd/drd_load_store.c @@ -379,10 +379,14 @@ static void instr_trace_mem_store(IRSB* const bb, IRExpr* const addr_expr, HWord size; tl_assert(sizeof(HWord) == 4 || sizeof(HWord) == 8); - tl_assert(!data_expr_hi || typeOfIRExpr(bb->tyenv, data_expr_hi) == Ity_I32); + tl_assert(!data_expr_hi + || typeOfIRExpr(bb->tyenv, data_expr_hi) == Ity_I32 + || typeOfIRExpr(bb->tyenv, data_expr_hi) == Ity_I64); ty_data_expr = typeOfIRExpr(bb->tyenv, data_expr_lo); size = sizeofIRType(ty_data_expr); + if (data_expr_hi) + size *= 2; #if 0 // Test code diff --git a/drd/drd_main.c b/drd/drd_main.c index 455685a064..4c97dd3ae4 100644 --- a/drd/drd_main.c +++ b/drd/drd_main.c @@ -824,7 +824,7 @@ void drd_pre_clo_init(void) VG_(details_name) ("drd"); VG_(details_version) (NULL); VG_(details_description) ("a thread error detector"); - VG_(details_copyright_author)("Copyright (C) 2006-2024, and GNU GPL'd," + VG_(details_copyright_author)("Copyright (C) 2006-2026, and GNU GPL'd," " by Bart Van Assche et al."); VG_(details_bug_reports_to) (VG_BUGS_TO); diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index 0cd7c0be62..cea44e87de 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -202,6 +202,13 @@ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ { return implf argl; } #endif +#if defined(VGO_darwin) +#define LIBC_FUNC(ret_ty, zf, implf, argl_decl, argl) \ + ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSYSTEM_KERNEL_SONAME,zf) argl_decl; \ + ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSYSTEM_KERNEL_SONAME,zf) argl_decl \ + { return implf argl; } +#endif + /** * Macro for generating three Valgrind interception functions: one with the * Z-encoded name zf, one with ZAZa ("@*") appended to the name zf and one @@ -869,6 +876,17 @@ int pthread_once_intercept(pthread_once_t *once_control, CALL_FN_W_WW(ret, fn, once_control, init_routine); ANNOTATE_IGNORE_READS_AND_WRITES_END(); DRD_STOP_IGNORING_VAR(*once_control); +#if defined(VGO_darwin) + /* + * The Darwin function that implemented this is _os_once. That uses + * __ulock_wait/__ulock_wake to make any subsequent threads wait for + * the first thread to complete calling the init_routine. + * DRD can't see these ulock functions so we need to create + * an HB edge manually. + */ + ANNOTATE_HAPPENS_BEFORE(once_control); + ANNOTATE_HAPPENS_AFTER(once_control); +#endif return ret; } @@ -1491,7 +1509,7 @@ int sem_init_intercept(sem_t *sem, int pshared, unsigned int value) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZuinit, sem_init_intercept, (sem_t *sem, int pshared, unsigned int value), (sem, pshared, value)); #else @@ -1534,7 +1552,7 @@ int sem_destroy_intercept(sem_t *sem) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); #else PTH_FUNCS(int, semZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); @@ -1570,7 +1588,7 @@ sem_t* sem_open_intercept(const char *name, int oflag, mode_t mode, return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(sem_t *, semZuopen, sem_open_intercept, (const char *name, int oflag, mode_t mode, unsigned int value), (name, oflag, mode, value)); @@ -1593,7 +1611,7 @@ static __always_inline int sem_close_intercept(sem_t *sem) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem)); #else PTH_FUNCS(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem)); @@ -1612,7 +1630,7 @@ static __always_inline int sem_wait_intercept(sem_t *sem) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem)); #else PTH_FUNCS(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem)); @@ -1635,7 +1653,7 @@ static __always_inline int sem_trywait_intercept(sem_t *sem) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); #else PTH_FUNCS(int, semZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); @@ -1658,7 +1676,7 @@ int sem_timedwait_intercept(sem_t *sem, const struct timespec *abs_timeout) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZutimedwait, sem_timedwait_intercept, (sem_t *sem, const struct timespec *abs_timeout), (sem, abs_timeout)); @@ -1711,7 +1729,7 @@ static __always_inline int sem_post_intercept(sem_t *sem) return ret; } -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, semZupost, sem_post_intercept, (sem_t *sem), (sem)); #else PTH_FUNCS(int, semZupost, sem_post_intercept, (sem_t *sem), (sem)); diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index bf5daf247f..ddef5b692c 100644 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -158,14 +158,12 @@ EXTRA_DIST = \ hold_lock_1.vgtest \ hold_lock_2.stderr.exp \ hold_lock_2.vgtest \ - getaddrinfo.stderr.exp \ getaddrinfo.vgtest \ linuxthreads_det.stderr.exp \ linuxthreads_det.stderr.exp-linuxthreads \ linuxthreads_det.stdout.exp \ linuxthreads_det.stdout.exp-linuxthreads \ linuxthreads_det.vgtest \ - local_static.stderr.exp \ local_static.vgtest \ matinv.stderr.exp \ matinv.stdout.exp \ @@ -220,17 +218,14 @@ EXTRA_DIST = \ pth_create_glibc_2_0.stderr.exp \ pth_create_glibc_2_0.vgtest \ pth_detached.stderr.exp \ - pth_detached.stdout.exp \ pth_detached.vgtest \ pth_detached2.stderr.exp \ - pth_detached2.stdout.exp \ pth_detached2.vgtest \ pth_detached3.stderr.exp1 \ pth_detached3.stderr.exp2 \ pth_detached3.stderr.exp-freebsd \ pth_detached3.vgtest \ pth_detached_sem.stderr.exp \ - pth_detached_sem.stdout.exp \ pth_detached_sem.vgtest \ pth_inconsistent_cond_wait.stderr.exp1 \ pth_inconsistent_cond_wait.stderr.exp2 \ @@ -271,7 +266,6 @@ EXTRA_DIST = \ sem_as_mutex3.stderr.exp-mips32-be \ sem_as_mutex3.stderr.exp-mips32-le \ sem_as_mutex3.vgtest \ - sem_clockwait_np.stderr.exp \ sem_clockwait_np.stdout.exp \ sem_clockwait_np.vgtest \ sem_open.stderr.exp \ @@ -364,8 +358,9 @@ EXTRA_DIST = \ tc21_pthonce.stderr.exp \ tc21_pthonce.stdout.exp \ tc21_pthonce.vgtest \ - tc22_exit_w_lock.stderr.exp-32bit \ - tc22_exit_w_lock.stderr.exp-64bit \ + tc22_exit_w_lock.stderr.exp \ + tc22_exit_w_lock.stderr.exp-darwin \ + tc22_exit_w_lock.stderr.exp-solaris \ tc22_exit_w_lock.vgtest \ tc23_bogus_condwait.stderr.exp-linux-x86 \ tc23_bogus_condwait.stderr.exp-linux-ppc \ @@ -576,10 +571,11 @@ pth_create_chain_CFLAGS += -D__EXTENSIONS__ pth_detached_CFLAGS += -D__EXTENSIONS__ endif +sem_as_mutex_CGLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ tsan_unittest_SOURCES = tsan_unittest.cpp tsan_unittest_CXXFLAGS = $(AM_CXXFLAGS) \ -DTHREAD_WRAPPERS='"tsan_thread_wrappers_pthread.h"' \ - @FLAG_W_NO_UNUSED_BUT_SET_VARIABLE@ + @FLAG_W_NO_UNUSED_BUT_SET_VARIABLE@ @FLAG_W_NO_DEPRECATED_DECLARATIONS@ unit_bitmap_CFLAGS = $(AM_CFLAGS) -O2 \ -DENABLE_DRD_CONSISTENCY_CHECKS \ @@ -626,6 +622,7 @@ if HAVE_PTHREAD_BARRIER matinv_LDADD = $(LDADD) -lm endif +pth_detached_sem_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ rwlock_test_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNUSED_BUT_SET_VARIABLE@ if VGCONF_OS_IS_SOLARIS rwlock_test_CFLAGS += -D__EXTENSIONS__ @@ -662,10 +659,11 @@ if !VGCONF_OS_IS_SOLARIS std_thread2_LDFLAGS = -Wl,--no-as-needed endif +sem_as_mutex_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ sem_wait_SOURCES = sem_wait.cpp swapcontext_SOURCES = swapcontext.c -swapcontext_CFLAGS = $(AM_CFLAGS) -g +swapcontext_CFLAGS = $(AM_CFLAGS) -g @FLAG_W_NO_DEPRECATED_DECLARATIONS@ if VGCONF_OS_IS_SOLARIS swapcontext_CFLAGS += -D__EXTENSIONS__ endif diff --git a/drd/tests/annotate_sem.vgtest b/drd/tests/annotate_sem.vgtest index 3c5071ca14..4cec9ee371 100644 --- a/drd/tests/annotate_sem.vgtest +++ b/drd/tests/annotate_sem.vgtest @@ -1,4 +1,4 @@ -prereq: test -e annotate_sem && ./supported_libpthread +prereq: test -e annotate_sem && ./supported_libpthread && ! ../../tests/os_test darwin vgopts: --fair-sched=try --read-var-info=yes --check-stack-var=yes --show-confl-seg=no prog: annotate_sem stderr_filter: filter_stderr_and_thread_no diff --git a/drd/tests/annotate_smart_pointer2.stderr.exp-darwin b/drd/tests/annotate_smart_pointer2.stderr.exp-darwin index 54fa41e12a..e3e33c5c57 100644 --- a/drd/tests/annotate_smart_pointer2.stderr.exp-darwin +++ b/drd/tests/annotate_smart_pointer2.stderr.exp-darwin @@ -1,12 +1,12 @@ Conflicting store by thread x at 0x........ size 4 at 0x........: counter::~counter() (annotate_smart_pointer.cpp:?) + by 0x........: counter::~counter() (annotate_smart_pointer.cpp:?) by 0x........: smart_ptr::set(counter*, AtomicInt32*) (annotate_smart_pointer.cpp:?) by 0x........: smart_ptr::operator=(counter*) (annotate_smart_pointer.cpp:?) by 0x........: main (annotate_smart_pointer.cpp:?) Address 0x........ is at offset ... from 0x......... Allocation context: - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: operator new(unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib) + at 0x........: ...operator new... (vg_replace_malloc.c:...) by 0x........: main (annotate_smart_pointer.cpp:?) Done. diff --git a/drd/tests/filter_lambda b/drd/tests/filter_lambda index 248132dc8a..31dcc75939 100755 --- a/drd/tests/filter_lambda +++ b/drd/tests/filter_lambda @@ -3,5 +3,6 @@ ./filter_stderr | sed -e 's/\$_0/LAMBDA/' | -sed -e 's/{lambda()#1}/LAMBDA/' +sed -e 's/{lambda()#1}/LAMBDA/' | +sed -e '/std::_/d' diff --git a/drd/tests/filter_stderr.in b/drd/tests/filter_stderr.in index 485a588b89..7f19676de3 100644 --- a/drd/tests/filter_stderr.in +++ b/drd/tests/filter_stderr.in @@ -27,18 +27,20 @@ $SED \ -e "/^warning: evaluate_Dwarf3_Expr: unhandled DW_OP_.*/d" \ -e '/^warning: addVar:.*/d' \ -e 's/^Allocation context: Data section of .\//Allocation context: BSS section of /' \ --e '/^run: \/usr\/bin\/dsymutil.*/d' \ -e "s/, in frame #[0-9]* of thread /, in frame #? of thread /" \ -e "s/(\(functional\|thread\):[0-9]*)/(\1:...)/" \ -e "s/(tc20_verifywrap.c:261)/(tc20_verifywrap.c:262)/" \ -e "/^Copyright (C) 2006-20.., and GNU GPL'd, by Bart Van Assche et al.$/d" \ -e "s/start_thread ([^)]*)/start_thread/" \ +-e "s/_pthread_start ([^)]*)/start_thread/" \ -e "s/\([A-Za-z_]*\) (clone.S:[0-9]*)/\1 (in \/...libc...)/" \ -e "s/\([A-Za-z_]*\) (swapcontext.S:[0-9]*)/\1 (in \/...libc...)/" \ -e "s/_swapcontext/swapcontext/" \ -e "s/[A-Za-z_]* (pthread_create.c:[0-9]*)/(within libpthread-?.?.so)/" \ -e "s/[A-Za-z_]* (in [^ ]*libpthread-[0-9.]*\.so)/(within libpthread-?.?.so)/" \ -e "s/... (in \/lib\/libthr.so.3)/start_thread/" \ +-e "s#: .*/lib/libthr/thread/thr_create.*#: start_thread#" \ +-e "s/_pthread_body (in \/...libc...)/start_thread/" \ -e "s:(within /lib[0-9]*/ld-[0-9.]*\.so):(within ld-?.?.so):" \ -e "s/was held during [0-9][0-9]*/was held during .../" \ -e "s: BSS section of [^<]*/: BSS section of :g" \ @@ -51,7 +53,8 @@ $SED \ -e "s/\( name [^ ]*\)-[0-9]*\( oflag \)/\1\2/" \ -e "s/??? (in \/[A-Za-z0-9_/-]*)/???/" \ -e '/^ by 0x[0-9a-fA-F]*: process_dl_debug (in \/lib[0-9]*\/ld-[0-9.]*\.so)$/d' \ --e "/^For lists of detected and suppressed errors, rerun with: -s$/d" | +-e "/^For lists of detected and suppressed errors, rerun with: -s$/d" \ +-e "s/__kill/kill/" | # Remove the message that more than hundred errors have been detected # (consists of two lines) and also the empty line above it. diff --git a/drd/tests/getaddrinfo.stderr.exp b/drd/tests/getaddrinfo.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/local_static.stderr.exp b/drd/tests/local_static.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/pth_cond_destroy_busy.vgtest b/drd/tests/pth_cond_destroy_busy.vgtest index f3cf778252..a5895f3520 100644 --- a/drd/tests/pth_cond_destroy_busy.vgtest +++ b/drd/tests/pth_cond_destroy_busy.vgtest @@ -1,2 +1,2 @@ -prereq: ./supported_libpthread && ! ../../tests/libc_test glibc 2.24.90 +prereq: ./supported_libpthread && ! ../../tests/libc_test glibc 2.24.90 && ! ../../tests/os_test darwin prog: pth_cond_destroy_busy diff --git a/drd/tests/pth_detached.stdout.exp b/drd/tests/pth_detached.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/pth_detached2.stdout.exp b/drd/tests/pth_detached2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/pth_detached3.stderr.exp1 b/drd/tests/pth_detached3.stderr.exp1 index 8dd58ba0f3..683d634b0e 100644 --- a/drd/tests/pth_detached3.stderr.exp1 +++ b/drd/tests/pth_detached3.stderr.exp1 @@ -1,11 +1,11 @@ pthread_detach(): invalid thread ID 0x........ at 0x........: pthread_detach (drd_pthread_intercepts.c:?) - by 0x........: main (pth_detached3.c:22) + by 0x........: main (pth_detached3.c:26) pthread_detach(): invalid thread ID 0x........ at 0x........: pthread_detach (drd_pthread_intercepts.c:?) - by 0x........: main (pth_detached3.c:25) + by 0x........: main (pth_detached3.c:32) Finished. diff --git a/drd/tests/pth_detached_sem.stdout.exp b/drd/tests/pth_detached_sem.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/sem_clockwait_np.stderr.exp b/drd/tests/sem_clockwait_np.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/drd/tests/std_thread2.supp b/drd/tests/std_thread2.supp index 40741b06f8..39a201da9a 100644 --- a/drd/tests/std_thread2.supp +++ b/drd/tests/std_thread2.supp @@ -98,3 +98,10 @@ drd:ConflictingAccess fun:__set_vma_name } + +{ + drd-libc-__is_decorate_maps_enabled + drd:ConflictingAccess + fun:__is_decorate_maps_enabled +} + diff --git a/drd/tests/std_thread2.vgtest b/drd/tests/std_thread2.vgtest index 74917b289d..785eadebc2 100644 --- a/drd/tests/std_thread2.vgtest +++ b/drd/tests/std_thread2.vgtest @@ -1,4 +1,4 @@ prereq: test -e std_thread2 && ./supported_libpthread -vgopts: --check-stack-var=yes --show-confl-seg=no --num-callers=1 --default-suppressions=no --suppressions=std_thread2.supp +vgopts: --check-stack-var=yes --show-confl-seg=no --num-callers=2 --default-suppressions=no --suppressions=std_thread2.supp prog: std_thread2 stderr_filter: filter_lambda diff --git a/drd/tests/swapcontext.vgtest b/drd/tests/swapcontext.vgtest index 98e3712c40..0c05ab7021 100644 --- a/drd/tests/swapcontext.vgtest +++ b/drd/tests/swapcontext.vgtest @@ -1,4 +1,4 @@ -prereq: test -e swapcontext && ./supported_libpthread +prereq: test -e swapcontext && ./supported_libpthread && ! ../../tests/os_test darwin vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no --num-callers=2 prog: swapcontext stderr_filter: filter_stderr diff --git a/drd/tests/tc22_exit_w_lock.stderr.exp b/drd/tests/tc22_exit_w_lock.stderr.exp new file mode 100644 index 0000000000..ce55c062b8 --- /dev/null +++ b/drd/tests/tc22_exit_w_lock.stderr.exp @@ -0,0 +1,15 @@ + +Mutex still locked at thread exit: mutex 0x........, recursion count 1, owner 3. + at 0x........: pthread_join (drd_pthread_intercepts.c:?) + by 0x........: main (tc22_exit_w_lock.c:43) +mutex 0x........ was first observed at: + at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?) + by 0x........: child_fn1 (tc22_exit_w_lock.c:18) + by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + + +Process terminating with default action of signal 6 (SIGABRT) + at 0x........: kill (in /...libc...) + by 0x........: main (tc22_exit_w_lock.c:48) + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/drd/tests/tc22_exit_w_lock.stderr.exp-32bit b/drd/tests/tc22_exit_w_lock.stderr.exp-32bit deleted file mode 100644 index 5563126437..0000000000 --- a/drd/tests/tc22_exit_w_lock.stderr.exp-32bit +++ /dev/null @@ -1,137 +0,0 @@ - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_lock (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_lock (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_used (offset 4, size 8) in libpthread-?.?.so, libpthread.so.0:Data -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_used (offset 0, size 8) in libpthread-?.?.so, libpthread.so.0:Data -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache (offset 0, size 8) in libpthread-?.?.so, libpthread.so.0:Data -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache (offset 4, size 8) in libpthread-?.?.so, libpthread.so.0:Data -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_actsize (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache (offset 0, size 8) in libpthread-?.?.so, libpthread.so.0:Data -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_actsize (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_lock (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: __deallocate_stack (in libpthread-?.?.so) - by 0x........: __free_tcb (in libpthread-?.?.so) - by 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) -Allocation context: stack_cache_lock (offset 0, size 4) in libpthread-?.?.so, libpthread.so.0:BSS -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Mutex still locked at thread exit: address 0x........, recursion count 1, owner 3. - at 0x........: pthread_join (drd_pthread_intercepts.c:?) - by 0x........: main (tc22_exit_w_lock.c:43) - diff --git a/drd/tests/tc22_exit_w_lock.stderr.exp-darwin b/drd/tests/tc22_exit_w_lock.stderr.exp-darwin new file mode 100644 index 0000000000..791a9bd12d --- /dev/null +++ b/drd/tests/tc22_exit_w_lock.stderr.exp-darwin @@ -0,0 +1,15 @@ + +Mutex still locked at thread exit: mutex 0x........, recursion count 1, owner 3. + at 0x........: pthread_join (drd_pthread_intercepts.c:?) + by 0x........: main (tc22_exit_w_lock.c:43) +mutex 0x........ was first observed at: + at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?) + by 0x........: child_fn1 (tc22_exit_w_lock.c:18) + by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + + +Process terminating with default action of signal 6 (SIGABRT) + at 0x........: kill (in /...libc...) + by 0x........: (below main) + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/drd/tests/tc22_exit_w_lock.stderr.exp-64bit b/drd/tests/tc22_exit_w_lock.stderr.exp-solaris similarity index 68% rename from drd/tests/tc22_exit_w_lock.stderr.exp-64bit rename to drd/tests/tc22_exit_w_lock.stderr.exp-solaris index 03e8046506..93c257511c 100644 --- a/drd/tests/tc22_exit_w_lock.stderr.exp-64bit +++ b/drd/tests/tc22_exit_w_lock.stderr.exp-solaris @@ -1,3 +1,4 @@ + Mutex still locked at thread exit: mutex 0x........, recursion count 1, owner 3. at 0x........: pthread_join (drd_pthread_intercepts.c:?) by 0x........: main (tc22_exit_w_lock.c:43) @@ -6,3 +7,9 @@ mutex 0x........ was first observed at: by 0x........: child_fn1 (tc22_exit_w_lock.c:18) by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + +Process terminating with default action of signal 6 (SIGABRT) + at 0x........: (below main) + by 0x........: (below main) + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/drd/tests/tc22_exit_w_lock.vgtest b/drd/tests/tc22_exit_w_lock.vgtest index 5edf4e5ffe..023fea0e07 100644 --- a/drd/tests/tc22_exit_w_lock.vgtest +++ b/drd/tests/tc22_exit_w_lock.vgtest @@ -1,4 +1,4 @@ prereq: ./supported_libpthread && [ -e ../../helgrind/tests/tc22_exit_w_lock ] -vgopts: --num-callers=3 -q +vgopts: --num-callers=3 prog: ../../helgrind/tests/tc22_exit_w_lock cleanup: rm -f vgcore.* diff --git a/drd/tests/tc23_bogus_condwait.stderr.exp-darwin-amd64 b/drd/tests/tc23_bogus_condwait.stderr.exp-darwin-amd64 index 3310390001..9fc4b77d79 100644 --- a/drd/tests/tc23_bogus_condwait.stderr.exp-darwin-amd64 +++ b/drd/tests/tc23_bogus_condwait.stderr.exp-darwin-amd64 @@ -1,76 +1,70 @@ The object at address 0x........ is not a mutex. at 0x........: pthread_cond_wait (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:69) + by 0x........: main (tc23_bogus_condwait.c:75) Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_wait (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:72) + by 0x........: main (tc23_bogus_condwait.c:79) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:54) + by 0x........: main (tc23_bogus_condwait.c:59) Thread 3: Probably a race condition: condition variable 0x........ has been signaled but the associated mutex 0x........ is not locked by the signalling thread. at 0x........: pthread_cond_signal (drd_pthread_intercepts.c:?) - by 0x........: rescue_me (tc23_bogus_condwait.c:20) + by 0x........: rescue_me (tc23_bogus_condwait.c:24) by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) cond 0x........ was first observed at: at 0x........: pthread_cond_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:56) + by 0x........: main (tc23_bogus_condwait.c:61) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:54) + by 0x........: main (tc23_bogus_condwait.c:59) Thread 1: The object at address 0x........ is not a mutex. at 0x........: pthread_cond_wait (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:75) + by 0x........: main (tc23_bogus_condwait.c:82) rwlock 0x........ was first observed at: at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:57) + by 0x........: main (tc23_bogus_condwait.c:62) Mutex not locked by calling thread: mutex 0x........, recursion count 1, owner 2. at 0x........: pthread_cond_wait (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:78) + by 0x........: main (tc23_bogus_condwait.c:85) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:53) + by 0x........: main (tc23_bogus_condwait.c:58) Thread 3: Probably a race condition: condition variable 0x........ has been signaled but the associated mutex 0x........ is not locked by the signalling thread. at 0x........: pthread_cond_signal (drd_pthread_intercepts.c:?) - by 0x........: rescue_me (tc23_bogus_condwait.c:24) + by 0x........: rescue_me (tc23_bogus_condwait.c:29) by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) cond 0x........ was first observed at: at 0x........: pthread_cond_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:56) + by 0x........: main (tc23_bogus_condwait.c:61) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:53) + by 0x........: main (tc23_bogus_condwait.c:58) Thread 1: The impossible happened: mutex is locked simultaneously by two threads: mutex 0x........, recursion count 1, owner 2. at 0x........: pthread_cond_wait (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:78) + by 0x........: main (tc23_bogus_condwait.c:85) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:53) + by 0x........: main (tc23_bogus_condwait.c:58) Thread 2: Mutex not locked by calling thread: mutex 0x........, recursion count 2, owner 1. at 0x........: pthread_mutex_unlock (drd_pthread_intercepts.c:?) - by 0x........: grab_the_lock (tc23_bogus_condwait.c:42) + by 0x........: grab_the_lock (tc23_bogus_condwait.c:47) by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) mutex 0x........ was first observed at: at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?) - by 0x........: main (tc23_bogus_condwait.c:53) - -Assertion failed: (!r), function main, file tc23_bogus_condwait.c, line 86. + by 0x........: main (tc23_bogus_condwait.c:58) -Process terminating with default action of signal 6 (SIGABRT) - at 0x........: __kill (in /...libc...) - by 0x........: __assert_rtn (in /...libc...) - by 0x........: main (tc23_bogus_condwait.c:86) ERROR SUMMARY: 10 errors from 8 contexts (suppressed: 0 from 0) diff --git a/drd/tests/trylock.c b/drd/tests/trylock.c index 1aca703408..b2199e3057 100644 --- a/drd/tests/trylock.c +++ b/drd/tests/trylock.c @@ -57,7 +57,12 @@ int main(int argc, char** argv) #endif fprintf(stderr, "Attempt to lock for writing recursively (not allowed).\n"); r = pthread_rwlock_wrlock(&rwlock); assert(r == 0); - r = pthread_rwlock_trywrlock(&rwlock); assert(r == EBUSY); + r = pthread_rwlock_trywrlock(&rwlock); +#if defined(__APPLE__) + assert(r == EDEADLK); +#else + assert(r == EBUSY); +#endif r = pthread_rwlock_unlock(&rwlock); assert(r == 0); r = pthread_rwlock_destroy(&rwlock); assert(r == 0); diff --git a/exp-bbv/tests/amd64-linux/Makefile.am b/exp-bbv/tests/amd64-linux/Makefile.am index 67bcc02beb..dfc1adbaff 100644 --- a/exp-bbv/tests/amd64-linux/Makefile.am +++ b/exp-bbv/tests/amd64-linux/Makefile.am @@ -25,7 +25,7 @@ EXTRA_DIST = \ AM_CCASFLAGS += -ffreestanding -AM_LDFLAGS = -nostartfiles -nodefaultlibs +AM_LDFLAGS = -nostartfiles -nodefaultlibs @LDFLAG_NO_PIE@ clone_test_SOURCES = clone_test.S complex_rep_SOURCES = complex_rep.S @@ -40,10 +40,3 @@ AM_CCASFLAGS += -Xassembler -I$(top_srcdir)/exp-bbv/tests check_PROGRAMS += ll ll_SOURCES = ll.S endif - -clone_test_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -complex_rep_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -fldcw_check_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -ll_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -million_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -rep_prefix_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ diff --git a/exp-bbv/tests/x86/million.S b/exp-bbv/tests/x86/million.S index ffef1e5544..6ddd27a8ab 100644 --- a/exp-bbv/tests/x86/million.S +++ b/exp-bbv/tests/x86/million.S @@ -31,9 +31,6 @@ exit: #elif defined(VGO_solaris) pushl $0 # we return 0 int $0x91 # and exit -#elif defined(VGO_freebsd) - mov $0x1,%eax # we return 0 - int $0x80 # and exit #else # error "Unknown OS" #endif diff --git a/freebsd-helgrind-dbgrtld.supp b/freebsd-helgrind-dbgrtld.supp deleted file mode 100644 index ed16159c07..0000000000 --- a/freebsd-helgrind-dbgrtld.supp +++ /dev/null @@ -1,90 +0,0 @@ -{ - HELGRIND-LIB-RTLD2 - Helgrind:Race - fun:allocate_tls -} -{ - HELGRIND-LIB-RTLD3 - Helgrind:Race - fun:symlook_obj -} -{ - HELGRIND-LIB-RTLD4 - Helgrind:Race - fun:objlist_call_fini -} -{ - HELGRIND-LIB-RTLD5 - Helgrind:Race - fun:_rtld_error -} -{ - HELGRIND-LIB-RTLD6 - Helgrind:Race - fun:errmsg_save -} -{ - HELGRIND-LIB-RTLD7 - Helgrind:Race - fun:rtld_vsnprintf -} -{ - HELGRIND-LIB-RTLD8 - Helgrind:Race - fun:snprintf_func -} -{ - HELGRIND-LIB-RTLD9 - Helgrind:Race - fun:strlen -} -{ - HELGRIND-LIB-RTLD10 - Helgrind:Race - fun:symlook_default -} -{ - HELGRIND-LIB-RTLD11 - Helgrind:Race - ... - fun:dl_iterate_phdr -} -{ - HELGRIND-LIB-RTLD12 - Helgrind:Race - fun:morecore -} -{ - HELGRIND-LIB-RTLD13 - Helgrind:Race - fun:__crt_malloc -} -{ - HELGRIND-LIB-RTLD14 - Helgrind:Race - fun:globallist_curr -} -{ - HELGRIND-LIB-RTLD15 - Helgrind:Race - fun:tls_get_addr_common -} -{ - HELGRIND-LIB-RTLD16 - Helgrind:Race - fun:memset - ... - fun:allocate_tls -} -{ - HELGRIND-LIB-RTLD17 - Helgrind:Race - fun:__crt_free -} -{ - HELGRIND-LIB-RTLD18 - Helgrind:Race - ... - fun:free_tls -} - diff --git a/freebsd-helgrind.supp b/freebsd-helgrind.supp index 1a6f372492..434a926602 100644 --- a/freebsd-helgrind.supp +++ b/freebsd-helgrind.supp @@ -94,6 +94,17 @@ obj:*/lib*/libthr.so.3 fun:pthread_create } + +{ + HELGRIND-PTHREAD-CREATE3 + Helgrind:Race + fun:free + obj:*/lib*/libthr.so.3 + fun:_pthread_exit_mask + fun:_Tthr_exit + obj:*/lib*/libthr.so.3 +} + # PJF again a pthread_self() hazard { HELGRIND-PTHREAD-SELF1 @@ -244,3 +255,10 @@ Helgrind:Race fun:malloc } + +{ + FREEBSD16-ARM64-std::__1::ostreambuf_iterator> std::__1::__pad_and_output[abi:se190107]>(std::__1::ostreambuf_iterator>, char const*, char const*, char const*, std::__1::ios_base&, char) + Helgrind:Race + fun:_ZNSt3__116__pad_and_outputB8se190107IcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_ +} + diff --git a/freebsd.supp b/freebsd.supp index 0a392fecb6..a9996928bc 100644 --- a/freebsd.supp +++ b/freebsd.supp @@ -185,6 +185,16 @@ Memcheck:Leak match-leak-kinds: reachable fun:malloc - obj:/lib/libc.so.7 + obj:*/lib*/libc.so.7 fun:__cxa_atexit } +# this is a heisensuppression +# thread_alloca and lsframe1 tests fail regularly with make regtest +# but refuse to fail when run on their own +{ + MEMCHECK-RTLD-_SIGPROCMASK + Memcheck:Param + sigprocmask(set) + obj:/libexec/ld-elf*.so.1 + obj:/libexec/ld-elf*.so.1 +} diff --git a/gdbserver_tests/Makefile.am b/gdbserver_tests/Makefile.am index 6b73a24e94..ef3b1767e7 100644 --- a/gdbserver_tests/Makefile.am +++ b/gdbserver_tests/Makefile.am @@ -32,17 +32,13 @@ EXTRA_DIST = \ hginfo.stdinB.gdb \ hginfo.stdoutB.exp \ hginfo.vgtest \ - hgtls.stderrB.exp \ - hgtls.stderr.exp \ hgtls.stdinB.gdb \ hgtls.stdoutB.exp \ hgtls.vgtest \ - mcblocklistsearch.stderr.exp \ mcblocklistsearch.stdinB.gdb \ mcblocklistsearch.vgtest \ mcblocklistsearch.stderrB.exp \ mcbreak.stderrB.exp \ - mcbreak.stderr.exp \ mcbreak.stdinB.gdb \ mcbreak.stdoutB.exp \ mcbreak.stdout.exp \ @@ -53,10 +49,8 @@ EXTRA_DIST = \ mcclean_after_fork.stdoutB.exp \ mcclean_after_fork.vgtest \ mchelp.stderrB.exp \ - mchelp.stderr.exp \ mchelp.stdoutB.exp \ mchelp.vgtest \ - mcinfcallRU.stderrB.exp \ mcinfcallRU.stderr.exp \ mcinfcallRU.stdinB.gdb \ mcinfcallRU.vgtest \ @@ -65,11 +59,9 @@ EXTRA_DIST = \ mcinfcallWSRU.stdinB.gdb \ mcinfcallWSRU.vgtest \ mcinvokeRU.stderrB.exp \ - mcinvokeRU.stderr.exp \ mcinvokeRU.stdoutB.exp \ mcinvokeRU.vgtest \ mcinvokeWS.stderrB.exp \ - mcinvokeWS.stderr.exp \ mcinvokeWS.stdoutB.exp \ mcinvokeWS.vgtest \ mcleak.stderrB.exp \ @@ -89,34 +81,28 @@ EXTRA_DIST = \ mcmain_pic.stdinB.gdb \ mcmain_pic.stdoutB.exp \ mcmain_pic.stdout.exp \ - mcsignopass.stderrB.exp \ mcsignopass.stderr.exp \ mcsignopass.stdinB.gdb \ mcsignopass.stdoutB.exp \ mcsignopass.stdoutB.exp-freebsd \ mcsignopass.vgtest \ - mcsigpass.stderrB.exp \ mcsigpass.stderr.exp \ mcsigpass.stdinB.gdb \ mcsigpass.stdoutB.exp \ mcsigpass.stdoutB.exp-freebsd \ mcsigpass.vgtest \ mcvabits.stderrB.exp \ - mcvabits.stderr.exp \ mcvabits.stdinB.gdb \ mcvabits.stdoutB.exp \ mcvabits.vgtest \ - mcwatchpoints.stderrB.exp \ mcwatchpoints.stderr.exp \ mcwatchpoints.stdinB.gdb \ mcwatchpoints.stdoutB.exp \ mcwatchpoints.vgtest \ mssnapshot.stderrB.exp \ - mssnapshot.stderr.exp \ mssnapshot.stdinB.gdb \ mssnapshot.stdoutB.exp \ mssnapshot.vgtest \ - nlcontrolc.stderrB.exp \ nlcontrolc.stderr.exp \ nlcontrolc.stdinB.gdb \ nlcontrolc.stdoutB.exp \ @@ -126,17 +112,14 @@ EXTRA_DIST = \ nlfork_chain.stdout.exp \ nlfork_chain.vgtest \ nlgone_abrt.stderr.exp \ - nlgone_abrt.stderrB.exp \ nlgone_abrt.stdinB.gdb \ nlgone_abrt.stdoutB.exp \ nlgone_abrt.vgtest \ nlgone_exit.stderr.exp \ - nlgone_exit.stderrB.exp \ nlgone_exit.stdinB.gdb \ nlgone_exit.stdoutB.exp \ nlgone_exit.vgtest \ nlgone_return.stderr.exp \ - nlgone_return.stderrB.exp \ nlgone_return.stdinB.gdb \ nlgone_return.stdoutB.exp \ nlgone_return.vgtest \ @@ -145,7 +128,6 @@ EXTRA_DIST = \ nlpasssigalrm.stderr.exp \ nlpasssigalrm.stdinB.gdb \ nlpasssigalrm.stdoutB.exp \ - nlself_invalidate.stderrB.exp \ nlself_invalidate.stderr.exp \ nlself_invalidate.stdinB.gdb \ nlself_invalidate.vgtest \ @@ -154,7 +136,6 @@ EXTRA_DIST = \ nlsigvgdb.stderrB.exp \ nlsigvgdb.stdinB.gdb \ nlvgdbsigqueue.vgtest \ - nlvgdbsigqueue.stderrB.exp \ nlvgdbsigqueue.stderr.exp \ nlvgdbsigqueue.stdinB.gdb \ nlvgdbsigqueue.stdoutB.exp \ diff --git a/gdbserver_tests/filter_gdb.in b/gdbserver_tests/filter_gdb.in index ccd48212dc..07d035b564 100644 --- a/gdbserver_tests/filter_gdb.in +++ b/gdbserver_tests/filter_gdb.in @@ -106,9 +106,7 @@ s/\(#0 0x........ in do_burn ()\) at sleepers.c:41/\1/ # delete Reading symbols file lines -# Note: The 'done.' in "Reading symbols from ...done." -# is optional (bugzilla 406357). -/^Reading symbols from .*\.\.\.\(done\.\)\?/d +/^Reading symbols from /d # delete Loaded symbols file lines /^Loaded symbols for .*$/d diff --git a/gdbserver_tests/hgtls.stderr.exp b/gdbserver_tests/hgtls.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/hgtls.stderrB.exp b/gdbserver_tests/hgtls.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcblocklistsearch.stderr.exp b/gdbserver_tests/mcblocklistsearch.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcbreak.stderr.exp b/gdbserver_tests/mcbreak.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mchelp.stderr.exp b/gdbserver_tests/mchelp.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcinfcallRU.stderrB.exp b/gdbserver_tests/mcinfcallRU.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcinvokeRU.stderr.exp b/gdbserver_tests/mcinvokeRU.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcinvokeWS.stderr.exp b/gdbserver_tests/mcinvokeWS.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcinvokeWS.vgtest b/gdbserver_tests/mcinvokeWS.vgtest index ced90fa183..54b11f7bc1 100644 --- a/gdbserver_tests/mcinvokeWS.vgtest +++ b/gdbserver_tests/mcinvokeWS.vgtest @@ -4,7 +4,7 @@ prog: sleepers args: 1 10000000 0 -S-S-S-S vgopts: --tool=memcheck --vgdb=yes --vgdb-prefix=./vgdb-prefix-mcinvokeWS stderr_filter: filter_make_empty -prereq: test -f vgdb.invoker +prereq: test -f vgdb.invoker && ( ! ../tests/os_test freebsd || [ "$(sysctl -n debug.ptrace_attach_transparent 2>/dev/null || echo 0)" -eq 0 ] ) progB: invoker argsB: 10 --vgdb-prefix=./vgdb-prefix-mcinvokeWS --wait=60 -c v.wait 0 # if the --wait is not enough, the test will fail or block diff --git a/gdbserver_tests/mcsignopass.stderrB.exp b/gdbserver_tests/mcsignopass.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcsigpass.stderrB.exp b/gdbserver_tests/mcsigpass.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcvabits.stderr.exp b/gdbserver_tests/mcvabits.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mcwatchpoints.stderrB.exp b/gdbserver_tests/mcwatchpoints.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/mssnapshot.stderr.exp b/gdbserver_tests/mssnapshot.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlcontrolc.stderrB.exp b/gdbserver_tests/nlcontrolc.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlcontrolc.vgtest b/gdbserver_tests/nlcontrolc.vgtest index 09edfcaba5..6c60972c21 100644 --- a/gdbserver_tests/nlcontrolc.vgtest +++ b/gdbserver_tests/nlcontrolc.vgtest @@ -13,7 +13,7 @@ args: 1000000000 0 100000 BSBSBSBS 1 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/os_test solaris +prereq: test -e gdb -a -f vgdb.invoker && ( ! ../tests/os_test solaris ) && ( ! ../tests/os_test freebsd || [ "$(sysctl -n debug.ptrace_attach_transparent 2>/dev/null || echo 0)" -eq 0 ] ) progB: gdb argsB: --quiet -l 60 --nx ./sleepers stdinB: nlcontrolc.stdinB.gdb diff --git a/gdbserver_tests/nlgone_abrt.stderrB.exp b/gdbserver_tests/nlgone_abrt.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlgone_exit.stderrB.exp b/gdbserver_tests/nlgone_exit.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlgone_return.stderrB.exp b/gdbserver_tests/nlgone_return.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlself_invalidate.stderrB.exp b/gdbserver_tests/nlself_invalidate.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/nlsigvgdb.vgtest b/gdbserver_tests/nlsigvgdb.vgtest index ad69a129f4..2e69109a29 100644 --- a/gdbserver_tests/nlsigvgdb.vgtest +++ b/gdbserver_tests/nlsigvgdb.vgtest @@ -7,7 +7,7 @@ prog: sleepers args: 1 10000000 0 -S-S-S-S 1 vgopts: --tool=none --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-nlsigvgdb stderr_filter: filter_stderr -prereq: test -e gdb -a -f vgdb.invoker +prereq: test -e gdb -a -f vgdb.invoker && ( ! ../tests/os_test freebsd || [ "$(sysctl -n debug.ptrace_attach_transparent 2>/dev/null || echo 0)" -eq 0 ] ) envB: LC_ALL=C progB: gdb argsB: --quiet -l 60 --nx ./sleepers diff --git a/gdbserver_tests/nlvgdbsigqueue.stderrB.exp b/gdbserver_tests/nlvgdbsigqueue.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gdbserver_tests/self_invalidate.c b/gdbserver_tests/self_invalidate.c index 52b3d2bef1..5a671e33cb 100644 --- a/gdbserver_tests/self_invalidate.c +++ b/gdbserver_tests/self_invalidate.c @@ -15,7 +15,11 @@ __asm__ __volatile__ "dec %%eax\n\t" "cmp $0x0,%%eax\n\t" "jne top\n\t" - "mov $60, %%eax\n\t" +#if defined(__APPLE__) + "mov $0x02000001, %%eax\n\t" /* macOS exit */ +#else + "mov $60, %%eax\n\t" /* Linux exit, FreeBSD and Solaris umask. umask works by accident. */ +#endif "mov $0, %%rdi\n\t" "syscall\n\t" : : : "eax", "ebx", "rdi" diff --git a/gdbserver_tests/sleepers.c b/gdbserver_tests/sleepers.c index 51d197a8e7..819536ca19 100644 --- a/gdbserver_tests/sleepers.c +++ b/gdbserver_tests/sleepers.c @@ -15,7 +15,7 @@ static int sleepms = 1000; // in each loop, will sleep "sleepms" milliseconds static int burn = 0; // after each sleep, will burn cpu in a tight 'burn' loop static void setup_sigusr_handler(void); // sigusr1 and 2 sigaction setup. -static pid_t gettid_sys() +static pid_t gettid_sys(void) { #ifdef __NR_gettid return syscall(__NR_gettid); @@ -32,7 +32,7 @@ void whoami(char *msg) } -static void do_burn () +static void do_burn(void) { int i; int loopnr = 0; @@ -124,13 +124,29 @@ static void wait_ready(void) // threads wanting to burn cpu. static void setaffinity(void) { -#ifdef VGO_linux +#if defined(VGO_linux) cpu_set_t single_cpu; CPU_ZERO(&single_cpu); CPU_SET(1, &single_cpu); (void) sched_setaffinity(0, sizeof(single_cpu), &single_cpu); #endif - // GDBTD: equivalent for Darwin ? + +#if defined(VGO_freebsd) + /* + * FreeBSD has something similar but it needs privileges + * somethinmg like this + */ + /* + cpuset_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + if (cpuset_setaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(cpuset), &cpuset) != 0) { + perror("cpuset_setaffinity"); + } + */ +#endif + + // FIXME: equivalent for Darwin and Solaris ? } int main (int argc, char *argv[]) diff --git a/gdbserver_tests/solaris/Makefile.am b/gdbserver_tests/solaris/Makefile.am index e9ebcc8fcc..7108f44c76 100644 --- a/gdbserver_tests/solaris/Makefile.am +++ b/gdbserver_tests/solaris/Makefile.am @@ -5,7 +5,6 @@ dist_noinst_SCRIPTS = \ filter_stderr EXTRA_DIST = \ - nlcontrolc.stderrB.exp \ nlcontrolc.stderr.exp \ nlcontrolc.stdinB.gdb \ nlcontrolc.stdoutB.exp \ diff --git a/gdbserver_tests/solaris/nlcontrolc.stderrB.exp b/gdbserver_tests/solaris/nlcontrolc.stderrB.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/glibc-2.X-drd.supp.in b/glibc-2.X-drd.supp.in index 419ff2256c..6866904470 100644 --- a/glibc-2.X-drd.supp.in +++ b/glibc-2.X-drd.supp.in @@ -369,3 +369,9 @@ fun:_dl_exception_create_format } +{ + drd-libc-__is_decorate_maps_enabled + drd:ConflictingAccess + fun:__is_decorate_maps_enabled +} + diff --git a/glibc-2.X-helgrind.supp.in b/glibc-2.X-helgrind.supp.in index 9b1ef9ae48..61d4e1d724 100644 --- a/glibc-2.X-helgrind.supp.in +++ b/glibc-2.X-helgrind.supp.in @@ -356,3 +356,9 @@ obj:/usr/lib/*/libnss_mdns4*.so.* } +{ + helgrind---_dl_allocate_tls_init + Helgrind:Race + fun:mempcpy + fun:_dl_allocate_tls_init +} diff --git a/helgrind/docs/hg-manual.xml b/helgrind/docs/hg-manual.xml index 398fd73a70..268d8a4d50 100644 --- a/helgrind/docs/hg-manual.xml +++ b/helgrind/docs/hg-manual.xml @@ -1318,6 +1318,49 @@ unlock(mx) unlock(mx) + + + + + + + Controls tracing of internal Helgrind synchronization, threading + and memory events. At level 1, Helgrind prints a trace of its + synchronization, threading and memory events. At level 2, + additional memory events are also traced. The default value of + 0 disables tracing. + + + + + + + + + + + Controls checking for missing + pthread_mutex_destroy and + pthread_rwlock_destroy calls. + With yes, Helgrind warns that a + destroy call is missing when + pthread_mutex_init or + pthread_rwlock_init is called on + an address that already has a live lock record. With + all, Helgrind reports at process + exit all mutexes and rwlocks that were explicitly initialized + but never destroyed. Locks that were not explicitly initialized + (such as those using static initializers like + PTHREAD_MUTEX_INITIALIZER) are + not reported. The default value of no disables tracking. + + + + diff --git a/helgrind/hg_basics.c b/helgrind/hg_basics.c index 1487d6b53d..ae2a4478c0 100644 --- a/helgrind/hg_basics.c +++ b/helgrind/hg_basics.c @@ -90,6 +90,10 @@ UWord HG_(clo_vts_pruning) = 1; Bool HG_(clo_check_stack_refs) = True; +UWord HG_(clo_show_events) = 0; + +UWord HG_(clo_track_destroy) = 0; + /*--------------------------------------------------------------------*/ /*--- end hg_basics.c ---*/ /*--------------------------------------------------------------------*/ diff --git a/helgrind/hg_basics.h b/helgrind/hg_basics.h index d62b47af74..c023a4c79a 100644 --- a/helgrind/hg_basics.h +++ b/helgrind/hg_basics.h @@ -137,6 +137,21 @@ extern UWord HG_(clo_vts_pruning); the stack, which speeds things up a bit. Default: True. */ extern Bool HG_(clo_check_stack_refs); +/* Controls which internal Helgrind events to trace: + + 0: No trace is printed (default). + + 1: Trace Helgrind's synchronization, threading and memory events. + + 2: Trace additional memory events. */ +extern UWord HG_(clo_show_events); + +/* Controls the reporting of undestroyed locks at guest exit. Also + detects when a lock is initialized at the same start address as an + undestroyed lock. Defaults to 0 since undestroyed locks aren't + necessarily a bug. */ +extern UWord HG_(clo_track_destroy); + #endif /* ! __HG_BASICS_H */ /*--------------------------------------------------------------------*/ diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index 4bef0ab959..0078a2a9e7 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -119,6 +119,12 @@ #include #endif +#if defined(VGO_darwin) +#define LIBC_FUNC(ret_ty, f, args...) \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBSYSTEM_KERNEL_SONAME,f)(args); \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBSYSTEM_KERNEL_SONAME,f)(args) +#endif + // Do a client request. These are macros rather than a functions so // as to avoid having an extra frame in stack traces. @@ -2309,6 +2315,33 @@ static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock) // darwin: pthread_rwlock_init$UNIX2003 // Solaris: rwlock_init (pthread_rwlock_init is built atop of rwlock_init) // FreeBSD: pthread_rwlock_init +#if defined(VGO_solaris) +__attribute__((noinline)) +static int pthread_rwlock_init_WRK(rwlock_t *rwlock, + int type, void *arg) +{ + int ret; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + if (TRACE_PTH_FNS) { + fprintf(stderr, "<< rwl_init %p", rwlock); fflush(stderr); + } + + CALL_FN_W_WWW(ret, fn, rwlock, type, arg); + + if (ret == 0 /*success*/) { + DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST, + rwlock_t *, rwlock); + } else { + DO_PthAPIerror("rwlock_init", ret); + } + + if (TRACE_PTH_FNS) { + fprintf(stderr, " :: rwl_init -> %d >>\n", ret); + } + return ret; +} +#else __attribute__((noinline)) static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl, pthread_rwlockattr_t* attr) @@ -2334,6 +2367,7 @@ static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl, } return ret; } +#endif #if defined(VGO_linux) PTH_FUNC(int, pthreadZurwlockZuinit, // pthread_rwlock_init pthread_rwlock_t *rwl, @@ -2353,42 +2387,14 @@ static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl, return pthread_rwlock_init_WRK(rwl, attr); } #elif defined(VGO_solaris) -static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl, - pthread_rwlockattr_t* attr) - __attribute__((unused)); + PTH_FUNC(int, rwlockZuinit, // rwlock_init + rwlock_t *rwlock, int type, void *arg) { + return pthread_rwlock_init_WRK(rwlock, type, arg); + } #else # error "Unsupported OS" #endif -#if defined(VGO_solaris) -PTH_FUNC(int, rwlockZuinit, // rwlock_init - rwlock_t *rwlock, - int type, - void *arg) -{ - int ret; - OrigFn fn; - VALGRIND_GET_ORIG_FN(fn); - if (TRACE_PTH_FNS) { - fprintf(stderr, "<< rwl_init %p", rwlock); fflush(stderr); - } - - CALL_FN_W_WWW(ret, fn, rwlock, type, arg); - - if (ret == 0 /*success*/) { - DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST, - rwlock_t *, rwlock); - } else { - DO_PthAPIerror("rwlock_init", ret); - } - - if (TRACE_PTH_FNS) { - fprintf(stderr, " :: rwl_init -> %d >>\n", ret); - } - return ret; -} -#endif /* VGO_solaris */ - //----------------------------------------------------------- // glibc: pthread_rwlock_destroy @@ -2650,7 +2656,19 @@ static int pthread_rwlock_trywrlock_WRK(pthread_rwlock_t* rwlock) pthread_rwlock_t*,rwlock, long,1/*isW*/, long, (ret == 0) ? True : False); if (ret != 0) { + Bool api_error = False; +#if defined(VGO_darwin) + // When rwlock is locked and there is an attempt to trylock it on the + // same thread POSIX says that it may return EADADLK. Darwin is the + // only one to do this, Linux, FreeBSD and Solaris all return EBUSY. + if (ret != EBUSY && ret != EDEADLK) + api_error = True; +#else if (ret != EBUSY) + api_error = True; +#endif + + if (api_error) DO_PthAPIerror( "pthread_rwlock_trywrlock", ret ); } @@ -3112,7 +3130,8 @@ static int sem_init_WRK(sem_t* sem, int pshared, unsigned long value) return sem_init_WRK(sem, pshared, value); } #elif defined(VGO_darwin) - PTH_FUNC(int, semZuinit, // sem_init +// exists but fails with ENOSYS function not implemented + LIBC_FUNC(int, semZuinit, // sem_init sem_t* sem, int pshared, unsigned long value) { return sem_init_WRK(sem, pshared, value); } @@ -3200,7 +3219,8 @@ static int sem_destroy_WRK(sem_t* sem) return sem_destroy_WRK(sem); } #elif defined(VGO_darwin) - PTH_FUNC(int, semZudestroy, // sem_destroy +// exists but fails with ENOSYS function not implemented + LIBC_FUNC(int, semZudestroy, // sem_destroy sem_t* sem) { return sem_destroy_WRK(sem); } @@ -3268,10 +3288,11 @@ static int sem_wait_WRK(sem_t* sem) return sem_wait_WRK(sem); } #elif defined(VGO_darwin) - PTH_FUNC(int, semZuwait, sem_t* sem) { /* sem_wait */ +// exists but fails with EBADF bad file number + LIBC_FUNC(int, semZuwait, sem_t* sem) { /* sem_wait */ return sem_wait_WRK(sem); } - PTH_FUNC(int, semZuwaitZDZa, sem_t* sem) { /* sem_wait$* */ + LIBC_FUNC(int, semZuwaitZDZa, sem_t* sem) { /* sem_wait$* */ return sem_wait_WRK(sem); } #elif defined(VGO_freebsd) @@ -3334,7 +3355,7 @@ PTH_FUNC(int, semZutrywaitZAZa, sem_t* sem) { /* sem_trywait@* */ return sem_trywait_WRK(sem); } #elif defined(VGO_darwin) -PTH_FUNC(int, semZutrywait, sem_t* sem) { /* sem_trywait */ +LIBC_FUNC(int, semZutrywait, sem_t* sem) { /* sem_trywait */ return sem_trywait_WRK(sem); } #elif defined(VGO_freebsd) @@ -3511,7 +3532,7 @@ static int sem_post_WRK(sem_t* sem) return sem_post_WRK(sem); } #elif defined(VGO_darwin) - PTH_FUNC(int, semZupost, sem_t* sem) { /* sem_post */ + LIBC_FUNC(int, semZupost, sem_t* sem) { /* sem_post */ return sem_post_WRK(sem); } #elif defined(VGO_freebsd) @@ -3533,7 +3554,7 @@ static int sem_post_WRK(sem_t* sem) // Solaris: sem_open // FreeBSD: sem_open // -#if defined(VGO_freebsd) +#if defined(VGO_freebsd) || defined(VGO_DARWIN) LIBC_FUNC(sem_t*, semZuopen, const char* name, long oflag, long mode, unsigned long value) @@ -3578,7 +3599,7 @@ PTH_FUNC(sem_t*, semZuopen, // darwin: sem_close // Solaris: sem_close // FreeBSD: sem_close -#if defined (VGO_freebsd) +#if defined (VGO_freebsd) || defined(VGO_darwin) LIBC_FUNC(int, sem_close, sem_t* sem) #else PTH_FUNC(int, sem_close, sem_t* sem) diff --git a/helgrind/hg_lock_n_thread.h b/helgrind/hg_lock_n_thread.h index fc13c14e29..6e59d69ff4 100644 --- a/helgrind/hg_lock_n_thread.h +++ b/helgrind/hg_lock_n_thread.h @@ -163,6 +163,9 @@ typedef Addr guestaddr; /* Guest address of lock */ LockKind kind; /* what kind of lock this is */ /* USEFUL-DYNAMIC */ + /* True if pthread_*_init was seen. Avoids spurious reporting + of static/inferred locks with --track-destroy. */ + Bool explicit_init; Bool heldW; WordBag* heldBy; /* bag of threads that hold this lock */ /* .heldBy is NULL: lock is unheld, and .heldW is meaningless diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 3f81a9d255..5aed987197 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -100,10 +100,6 @@ /* ------------ Debug/trace options ------------ */ -// 0 for silent, 1 for some stuff, 2 for lots of stuff -#define SHOW_EVENTS 0 - - static void all__sanity_check ( const HChar* who ); /* fwds */ #define HG_CLI__DEFAULT_MALLOC_REDZONE_SZB 16 /* let's say */ @@ -216,6 +212,7 @@ static Lock* mk_LockN ( LockKind kind, Addr guestaddr ) { lock->kind = kind; lock->heldW = False; lock->heldBy = NULL; + lock->explicit_init = False; tl_assert(HG_(is_sane_LockN)(lock)); return lock; } @@ -754,6 +751,10 @@ static Int HG_(get_pthread_create_nesting_level)(ThreadId tid) { /*--- map_locks :: WordFM guest-Addr-of-lock Lock* ---*/ /*----------------------------------------------------------------*/ +static void map_locks_delete ( Addr ga ); /* fwds */ +__attribute__((noinline)) +static void laog__handle_one_lock_deletion ( Lock* lk ); /* fwds */ + /* Make sure there is a lock table entry for the given (lock) guest address. If not, create one of the stated 'kind' in unheld state. In any case, return the address of the existing or new Lock. */ @@ -776,6 +777,33 @@ Lock* map_locks_lookup_or_create ( LockKind lkk, Addr ga, ThreadId tid ) tl_assert(oldlock != NULL); tl_assert(HG_(is_sane_LockN)(oldlock)); tl_assert(oldlock->guestaddr == ga); + /* Check for a mismatch between an rwlock and a mutex of either + kind. evh__HG_PTHREAD_MUTEX_LOCK_POST uses LK_mbRec as the + fallback kind, so a non-recursive mutex first encountered + at lock time rather than init time is expected to mismatch. */ + Bool old_is_mutex = (oldlock->kind == LK_nonRec + || oldlock->kind == LK_mbRec); + Bool new_is_mutex = (lkk == LK_nonRec || lkk == LK_mbRec); + if (old_is_mutex != new_is_mutex) { + /* At address GA a mutex has replaced an rwlock or an rwlock + has replaced a mutex. Remove the stale oldlock record. */ + if (oldlock->heldBy) { + remove_Lock_from_locksets_of_all_owning_Threads(oldlock); + VG_(deleteBag)(oldlock->heldBy); + oldlock->heldBy = NULL; + oldlock->heldW = False; + oldlock->acquired_at = NULL; + } + if (HG_(clo_track_lockorders)) + laog__handle_one_lock_deletion(oldlock); + map_locks_delete(ga); + del_LockN(oldlock); + Lock* lock = mk_LockN( lkk, ga ); + lock->appeared_at = VG_(record_ExeContext)( tid, 0 ); + tl_assert(HG_(is_sane_LockN)(lock)); + VG_(addToFM)( map_locks, (UWord)ga, (UWord)lock ); + return lock; + } return oldlock; } } @@ -1012,8 +1040,6 @@ static void all__sanity_check ( const HChar* who ) { static void laog__pre_thread_acquires_lock ( Thread*, Lock* ); /* fwds */ //static void laog__handle_lock_deletions ( WordSetID ); /* fwds */ static inline Thread* get_current_Thread ( void ); /* fwds */ -__attribute__((noinline)) -static void laog__handle_one_lock_deletion ( Lock* lk ); /* fwds */ /* Block-copy states (needed for implementing realloc()). */ @@ -1478,7 +1504,7 @@ static inline Thread* get_current_Thread ( void ) { static void evh__new_mem ( Addr a, SizeT len ) { Thread *thr = get_current_Thread(); - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__new_mem(%p, %lu)\n", (void*)a, len ); shadow_mem_make_New( thr, a, len ); if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE)) @@ -1490,7 +1516,7 @@ void evh__new_mem ( Addr a, SizeT len ) { static void evh__new_mem_stack ( Addr a, SizeT len ) { Thread *thr = get_current_Thread(); - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__new_mem_stack(%p, %lu)\n", (void*)a, len ); shadow_mem_make_New( thr, -VG_STACK_REDZONE_SZB + a, len ); if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE)) @@ -1503,7 +1529,7 @@ void evh__new_mem_stack ( Addr a, SizeT len ) { static void VG_REGPARM(1) evh__new_mem_stack_##syze(Addr new_SP) \ { \ Thread *thr = get_current_Thread(); \ - if (SHOW_EVENTS >= 2) \ + if (HG_(clo_show_events) >= 2) \ VG_(printf)("evh__new_mem_stack_" #syze "(%p, %lu)\n", \ (void*)new_SP, (SizeT)syze ); \ shadow_mem_make_New( thr, -VG_STACK_REDZONE_SZB + new_SP, syze ); \ @@ -1526,7 +1552,7 @@ DCL_evh__new_mem_stack(160); static void evh__new_mem_w_tid ( Addr a, SizeT len, ThreadId tid ) { Thread *thr = get_current_Thread(); - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__new_mem_w_tid(%p, %lu)\n", (void*)a, len ); shadow_mem_make_New( thr, a, len ); if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE)) @@ -1539,7 +1565,7 @@ static void evh__new_mem_w_perms ( Addr a, SizeT len, Bool rr, Bool ww, Bool xx, ULong di_handle ) { Thread *thr = get_current_Thread(); - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__new_mem_w_perms(%p, %lu, %d,%d,%d)\n", (void*)a, len, (Int)rr, (Int)ww, (Int)xx ); if (rr || ww || xx) { @@ -1557,7 +1583,7 @@ void evh__set_perms ( Addr a, SizeT len, // This handles mprotect requests. If the memory is being put // into no-R no-W state, paint it as NoAccess, for the reasons // documented at evh__die_mem_munmap(). - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__set_perms(%p, %lu, r=%d w=%d x=%d)\n", (void*)a, len, (Int)rr, (Int)ww, (Int)xx ); /* Hmm. What should we do here, that actually makes any sense? @@ -1572,7 +1598,7 @@ void evh__set_perms ( Addr a, SizeT len, static void evh__die_mem ( Addr a, SizeT len ) { // Urr, libhb ignores this. - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__die_mem(%p, %lu)\n", (void*)a, len ); shadow_mem_make_NoAccess_NoFX( get_current_Thread(), a, len ); if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE)) @@ -1589,7 +1615,7 @@ void evh__die_mem_munmap ( Addr a, SizeT len ) { // VTS references in the affected area are dropped. Marking memory // as NoAccess is expensive, but we assume that munmap is sufficiently // rare that the space gains of doing this are worth the costs. - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__die_mem_munmap(%p, %lu)\n", (void*)a, len ); shadow_mem_make_NoAccess_AHAE( get_current_Thread(), a, len ); } @@ -1597,7 +1623,7 @@ void evh__die_mem_munmap ( Addr a, SizeT len ) { static void evh__untrack_mem ( Addr a, SizeT len ) { // Libhb doesn't ignore this. - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__untrack_mem(%p, %lu)\n", (void*)a, len ); shadow_mem_make_Untracked( get_current_Thread(), a, len ); if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE)) @@ -1606,7 +1632,7 @@ void evh__untrack_mem ( Addr a, SizeT len ) { static void evh__copy_mem ( Addr src, Addr dst, SizeT len ) { - if (SHOW_EVENTS >= 2) + if (HG_(clo_show_events) >= 2) VG_(printf)("evh__copy_mem(%p, %p, %lu)\n", (void*)src, (void*)dst, len ); Thread *thr = get_current_Thread(); if (LIKELY(thr->synchr_nesting == 0)) @@ -1618,7 +1644,7 @@ void evh__copy_mem ( Addr src, Addr dst, SizeT len ) { static void evh__pre_thread_ll_create ( ThreadId parent, ThreadId child ) { - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__pre_thread_ll_create(p=%d, c=%d)\n", (Int)parent, (Int)child ); @@ -1692,7 +1718,7 @@ void evh__pre_thread_ll_exit ( ThreadId quit_tid ) { Int nHeld; Thread* thr_q; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__pre_thread_ll_exit(thr=%d)\n", (Int)quit_tid ); @@ -1808,7 +1834,7 @@ void evh__HG_PTHREAD_JOIN_POST ( ThreadId stay_tid, Thread* quit_thr ) Thr* hbthr_s; Thr* hbthr_q; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__post_thread_join(stayer=%d, quitter=%p)\n", (Int)stay_tid, quit_thr ); @@ -1847,8 +1873,8 @@ void evh__HG_PTHREAD_JOIN_POST ( ThreadId stay_tid, Thread* quit_thr ) static void evh__pre_mem_read ( CorePart part, ThreadId tid, const HChar* s, Addr a, SizeT size) { - if (SHOW_EVENTS >= 2 - || (SHOW_EVENTS >= 1 && size != 1)) + if (HG_(clo_show_events) >= 2 + || (HG_(clo_show_events) >= 1 && size != 1)) VG_(printf)("evh__pre_mem_read(ctid=%d, \"%s\", %p, %lu)\n", (Int)tid, s, (void*)a, size ); Thread *thr = map_threads_lookup(tid); @@ -1862,7 +1888,7 @@ static void evh__pre_mem_read_asciiz ( CorePart part, ThreadId tid, const HChar* s, Addr a ) { Int len; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__pre_mem_asciiz(ctid=%d, \"%s\", %p)\n", (Int)tid, s, (void*)a ); // Don't segfault if the string starts in an obviously stupid @@ -1882,7 +1908,7 @@ void evh__pre_mem_read_asciiz ( CorePart part, ThreadId tid, static void evh__pre_mem_write ( CorePart part, ThreadId tid, const HChar* s, Addr a, SizeT size ) { - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__pre_mem_write(ctid=%d, \"%s\", %p, %lu)\n", (Int)tid, s, (void*)a, size ); Thread *thr = map_threads_lookup(tid); @@ -1894,7 +1920,7 @@ void evh__pre_mem_write ( CorePart part, ThreadId tid, const HChar* s, static void evh__new_mem_heap ( Addr a, SizeT len, Bool is_inited ) { - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__new_mem_heap(%p, %lu, inited=%d)\n", (void*)a, len, (Int)is_inited ); // We ignore the initialisation state (is_inited); that's ok. @@ -1906,7 +1932,7 @@ void evh__new_mem_heap ( Addr a, SizeT len, Bool is_inited ) { static void evh__die_mem_heap ( Addr a, SizeT len ) { Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__die_mem_heap(%p, %lu)\n", (void*)a, len ); thr = get_current_Thread(); tl_assert(thr); @@ -2062,16 +2088,37 @@ void evh__mem_help_cwrite_N(Addr a, SizeT size) { user where the lock was initialised, rather than only being able to show where it was first locked. Intercepting lock initialisations is not necessary for the basic operation of the race checker. */ + +/* Warn if --track-destroy is enabled and a live lock record already + exists at ga, suggesting a missing pthread_*_destroy call. fn_name + should be the pthread init function name, such as "pthread_mutex_init". */ +static +void maybe_warn_lock_reinit ( Addr ga, const HChar* fn_name ) +{ + if (HG_(clo_track_destroy) == 0) + return; + Lock* lk = map_locks_maybe_lookup(ga); + if (lk != NULL) { + VG_(message)(Vg_UserMsg, + "%s called on address %p which already has a live lock record\n", + fn_name, (void*)ga); + if (lk->appeared_at) + VG_(pp_ExeContext)(lk->appeared_at); + } +} + static -void evh__HG_PTHREAD_MUTEX_INIT_POST( ThreadId tid, +void evh__HG_PTHREAD_MUTEX_INIT_POST( ThreadId tid, void* mutex, Word mbRec ) { - if (SHOW_EVENTS >= 1) - VG_(printf)("evh__hg_PTHREAD_MUTEX_INIT_POST(ctid=%d, mbRec=%ld, %p)\n", + if (HG_(clo_show_events) >= 1) + VG_(printf)("evh__hg_PTHREAD_MUTEX_INIT_POST(ctid=%d, mbRec=%ld, %p)\n", (Int)tid, mbRec, (void*)mutex ); tl_assert(mbRec == 0 || mbRec == 1); - map_locks_lookup_or_create( mbRec ? LK_mbRec : LK_nonRec, - (Addr)mutex, tid ); + maybe_warn_lock_reinit( (Addr)mutex, "pthread_mutex_init" ); + Lock* lk = map_locks_lookup_or_create( mbRec ? LK_mbRec : LK_nonRec, + (Addr)mutex, tid ); + lk->explicit_init = True; if (HG_(clo_sanity_flags) & SCE_LOCKS) all__sanity_check("evh__hg_PTHREAD_MUTEX_INIT_POST"); } @@ -2082,7 +2129,7 @@ void evh__HG_PTHREAD_MUTEX_DESTROY_PRE( ThreadId tid, void* mutex, { Thread* thr; Lock* lk; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_MUTEX_DESTROY_PRE" "(ctid=%d, %p, isInit=%d)\n", (Int)tid, (void*)mutex, (Int)mutex_is_init ); @@ -2141,7 +2188,7 @@ static void evh__HG_PTHREAD_MUTEX_LOCK_PRE ( ThreadId tid, // 'mutex' may be invalid - not checked by wrapper Thread* thr; Lock* lk; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_MUTEX_LOCK_PRE(ctid=%d, mutex=%p)\n", (Int)tid, (void*)mutex ); @@ -2181,7 +2228,7 @@ static void evh__HG_PTHREAD_MUTEX_LOCK_POST ( ThreadId tid, void* mutex ) { // only called if the real library call succeeded - so mutex is sane Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_MUTEX_LOCK_POST(ctid=%d, mutex=%p)\n", (Int)tid, (void*)mutex ); @@ -2199,7 +2246,7 @@ static void evh__HG_PTHREAD_MUTEX_UNLOCK_PRE ( ThreadId tid, void* mutex ) { // 'mutex' may be invalid - not checked by wrapper Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_MUTEX_UNLOCK_PRE(ctid=%d, mutex=%p)\n", (Int)tid, (void*)mutex ); @@ -2213,7 +2260,7 @@ static void evh__HG_PTHREAD_MUTEX_UNLOCK_POST ( ThreadId tid, void* mutex ) { // only called if the real library call succeeded - so mutex is sane Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_MUTEX_UNLOCK_POST(ctid=%d, mutex=%p)\n", (Int)tid, (void*)mutex ); thr = map_threads_maybe_lookup( tid ); @@ -2239,7 +2286,7 @@ static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE( ThreadId tid, it. Since this is the pre-routine, if it is locked, unlock it and take a dependence edge. Otherwise, do nothing. */ - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE" "(ctid=%d, slock=%p)\n", (Int)tid, (void*)slock ); @@ -2266,7 +2313,7 @@ static void evh__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST( ThreadId tid, actions as per evh__HG_PTHREAD_MUTEX_INIT_POST. Else do nothing. */ - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_SPIN_INIT_OR_UNLOCK_POST" "(ctid=%d, slock=%p)\n", (Int)tid, (void*)slock ); @@ -2413,7 +2460,7 @@ static void evh__HG_PTHREAD_COND_SIGNAL_PRE ( ThreadId tid, void* cond ) CVInfo* cvi; //Lock* lk; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_COND_SIGNAL_PRE(ctid=%d, cond=%p)\n", (Int)tid, (void*)cond ); @@ -2490,7 +2537,7 @@ static Bool evh__HG_PTHREAD_COND_WAIT_PRE ( ThreadId tid, Bool lk_valid = True; CVInfo* cvi; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_COND_WAIT_PRE" "(ctid=%d, cond=%p, mutex=%p)\n", (Int)tid, (void*)cond, (void*)mutex ); @@ -2559,7 +2606,7 @@ static void evh__HG_PTHREAD_COND_WAIT_POST ( ThreadId tid, Thread* thr; CVInfo* cvi; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_COND_WAIT_POST" "(ctid=%d, cond=%p, mutex=%p)\n, timeout=%d", (Int)tid, (void*)cond, (void*)mutex, (Int)timeout ); @@ -2604,7 +2651,7 @@ static void evh__HG_PTHREAD_COND_INIT_POST ( ThreadId tid, { CVInfo* cvi; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_COND_INIT_POST" "(ctid=%d, cond=%p, cond_attr=%p)\n", (Int)tid, (void*)cond, (void*) cond_attr ); @@ -2621,7 +2668,7 @@ static void evh__HG_PTHREAD_COND_DESTROY_PRE ( ThreadId tid, /* Deal with destroy events. The only purpose is to free storage associated with the CV, so as to avoid any possible resource leaks. */ - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_COND_DESTROY_PRE" "(ctid=%d, cond=%p, cond_is_init=%d)\n", (Int)tid, (void*)cond, (Int)cond_is_init ); @@ -2638,10 +2685,12 @@ static void evh__HG_PTHREAD_COND_DESTROY_PRE ( ThreadId tid, static void evh__HG_PTHREAD_RWLOCK_INIT_POST( ThreadId tid, void* rwl ) { - if (SHOW_EVENTS >= 1) - VG_(printf)("evh__hg_PTHREAD_RWLOCK_INIT_POST(ctid=%d, %p)\n", + if (HG_(clo_show_events) >= 1) + VG_(printf)("evh__hg_PTHREAD_RWLOCK_INIT_POST(ctid=%d, %p)\n", (Int)tid, (void*)rwl ); - map_locks_lookup_or_create( LK_rdwr, (Addr)rwl, tid ); + maybe_warn_lock_reinit( (Addr)rwl, "pthread_rwlock_init" ); + Lock* lk = map_locks_lookup_or_create( LK_rdwr, (Addr)rwl, tid ); + lk->explicit_init = True; if (HG_(clo_sanity_flags) & SCE_LOCKS) all__sanity_check("evh__hg_PTHREAD_RWLOCK_INIT_POST"); } @@ -2651,7 +2700,7 @@ void evh__HG_PTHREAD_RWLOCK_DESTROY_PRE( ThreadId tid, void* rwl ) { Thread* thr; Lock* lk; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_RWLOCK_DESTROY_PRE(ctid=%d, %p)\n", (Int)tid, (void*)rwl ); @@ -2702,7 +2751,7 @@ void evh__HG_PTHREAD_RWLOCK_LOCK_PRE ( ThreadId tid, // 'rwl' may be invalid - not checked by wrapper Thread* thr; Lock* lk; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_PRE(ctid=%d, isW=%d, %p)\n", (Int)tid, (Int)isW, (void*)rwl ); @@ -2726,7 +2775,7 @@ void evh__HG_PTHREAD_RWLOCK_LOCK_POST ( ThreadId tid, void* rwl, Word isW ) { // only called if the real library call succeeded - so mutex is sane Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_RWLOCK_LOCK_POST(ctid=%d, isW=%d, %p)\n", (Int)tid, (Int)isW, (void*)rwl ); @@ -2746,7 +2795,7 @@ static void evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE ( ThreadId tid, void* rwl ) { // 'rwl' may be invalid - not checked by wrapper Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_RWLOCK_UNLOCK_PRE(ctid=%d, rwl=%p)\n", (Int)tid, (void*)rwl ); @@ -2760,7 +2809,7 @@ static void evh__HG_PTHREAD_RWLOCK_UNLOCK_POST ( ThreadId tid, void* rwl ) { // only called if the real library call succeeded - so mutex is sane Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__hg_PTHREAD_RWLOCK_UNLOCK_POST(ctid=%d, rwl=%p)\n", (Int)tid, (void*)rwl ); thr = map_threads_maybe_lookup( tid ); @@ -2863,7 +2912,7 @@ static void evh__HG_POSIX_SEM_DESTROY_PRE ( ThreadId tid, void* sem ) UWord keyW, valW; SO* so; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_POSIX_SEM_DESTROY_PRE(ctid=%d, sem=%p)\n", (Int)tid, (void*)sem ); @@ -2892,7 +2941,7 @@ void evh__HG_POSIX_SEM_INIT_POST ( ThreadId tid, void* sem, UWord value ) SO* so; Thread* thr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_POSIX_SEM_INIT_POST(ctid=%d, sem=%p, value=%lu)\n", (Int)tid, (void*)sem, value ); @@ -2941,7 +2990,7 @@ static void evh__HG_POSIX_SEM_POST_PRE ( ThreadId tid, void* sem ) SO* so; Thr* hbthr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_POSIX_SEM_POST_PRE(ctid=%d, sem=%p)\n", (Int)tid, (void*)sem ); @@ -2969,7 +3018,7 @@ static void evh__HG_POSIX_SEM_WAIT_POST ( ThreadId tid, void* sem ) SO* so; Thr* hbthr; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_POSIX_SEM_WAIT_POST(ctid=%d, sem=%p)\n", (Int)tid, (void*)sem ); @@ -3068,7 +3117,7 @@ static void evh__HG_PTHREAD_BARRIER_INIT_PRE ( ThreadId tid, Thread* thr; Bar* bar; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_BARRIER_INIT_PRE" "(tid=%d, barrier=%p, count=%lu, resizable=%lu)\n", (Int)tid, (void*)barrier, count, resizable ); @@ -3125,7 +3174,7 @@ static void evh__HG_PTHREAD_BARRIER_DESTROY_PRE ( ThreadId tid, /* Deal with destroy events. The only purpose is to free storage associated with the barrier, so as to avoid any possible resource leaks. */ - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_BARRIER_DESTROY_PRE" "(tid=%d, barrier=%p)\n", (Int)tid, (void*)barrier ); @@ -3244,7 +3293,7 @@ static void evh__HG_PTHREAD_BARRIER_WAIT_PRE ( ThreadId tid, Bar* bar; UWord present; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_BARRIER_WAIT_PRE" "(tid=%d, barrier=%p)\n", (Int)tid, (void*)barrier ); @@ -3287,7 +3336,7 @@ static void evh__HG_PTHREAD_BARRIER_RESIZE_PRE ( ThreadId tid, Bar* bar; UWord present; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_PTHREAD_BARRIER_RESIZE_PRE" "(tid=%d, barrier=%p, newcount=%lu)\n", (Int)tid, (void*)barrier, newcount ); @@ -3406,7 +3455,7 @@ void evh__HG_USERSO_SEND_PRE ( ThreadId tid, UWord usertag ) Thread* thr; SO* so; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_USERSO_SEND_PRE(ctid=%d, usertag=%#lx)\n", (Int)tid, usertag ); @@ -3431,7 +3480,7 @@ void evh__HG_USERSO_RECV_POST ( ThreadId tid, UWord usertag ) Thread* thr; SO* so; - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_USERSO_RECV_POST(ctid=%d, usertag=%#lx)\n", (Int)tid, usertag ); @@ -3455,7 +3504,7 @@ void evh__HG_USERSO_FORGET_ALL ( ThreadId tid, UWord usertag ) SO is associated with USERTAG, then the association is removed and all resources associated with SO are freed. Importantly, that frees up any VTSs stored in SO. */ - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_USERSO_FORGET_ALL(ctid=%d, usertag=%#lx)\n", (Int)tid, usertag ); @@ -3471,7 +3520,7 @@ void evh__HG_USERSO_FORGET_ALL ( ThreadId tid, UWord usertag ) static void evh__HG_RTLD_BIND_GUARD(ThreadId tid, Int flags) { - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_RTLD_BIND_GUARD" "(tid=%d, flags=%d)\n", (Int)tid, flags); @@ -3491,7 +3540,7 @@ void evh__HG_RTLD_BIND_GUARD(ThreadId tid, Int flags) static void evh__HG_RTLD_BIND_CLEAR(ThreadId tid, Int flags) { - if (SHOW_EVENTS >= 1) + if (HG_(clo_show_events) >= 1) VG_(printf)("evh__HG_RTLD_BIND_CLEAR" "(tid=%d, flags=%d)\n", (Int)tid, flags); @@ -5843,6 +5892,22 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) HG_(clo_ignore_thread_creation)) {} else if VG_BOOL_CLO(arg, "--check-cond-signal-mutex", HG_(clo_check_cond_signal_mutex)) {} + + else if VG_BINT_CLO(arg, "--show-events", + HG_(clo_show_events), 0, 2) {} + + else if VG_STR_CLO(arg, "--track-destroy", tmp_str) { + if (VG_(strcmp)(tmp_str, "no") == 0) + HG_(clo_track_destroy) = 0; + else if (VG_(strcmp)(tmp_str, "yes") == 0) + HG_(clo_track_destroy) = 1; + else if (VG_(strcmp)(tmp_str, "all") == 0) + HG_(clo_track_destroy) = 2; + else + VG_(fmsg_bad_option)(arg, + "Bad argument, should be 'no', 'yes' or 'all'\n"); + } + else return VG_(replacement_malloc_process_cmd_line_option)(arg); @@ -5873,7 +5938,13 @@ static void hg_print_usage ( void ) " no: do not check that the associated mutex is locked for calls\n" " to pthread_cond_{signal,broadcast}\n" " yes: generate 'dubious' error messages if the associated mutex\n" -" is unlocked\n", +" is unlocked\n" +" --track-destroy=no|yes|all report missing pthread_*_destroy calls? [no]\n" +" no: do not warn about missing pthread_*_destroy calls\n" +" yes: warn when pthread_mutex_init or pthread_rwlock_init is called\n" +" on an address that already has a live lock record\n" +" all: like yes but also lists all undestroyed locks at exit (except\n" +" those using static initializers)\n", HG_(clo_ignore_thread_creation) ? "yes" : "no" ); } @@ -5898,6 +5969,11 @@ static void hg_print_debug_usage ( void ) " auto: done just often enough to keep space usage under control\n" " always: done after every VTS GC (mostly just a big time waster)\n" ); + VG_(printf)(" --show-events=0|1|2 [0]\n" +" 0: Do not trace internal Helgrind events\n" +" 1: Trace Helgrind's synchronization, threading and memory events\n" +" 2: Trace additional memory events\n" + ); } static void hg_print_stats (void) @@ -5981,6 +6057,30 @@ static void hg_fini ( Int exitcode ) if (HG_(clo_sanity_flags)) all__sanity_check("SK_(fini)"); + if (HG_(clo_track_destroy) >= 2) { + Lock* lk; + UWord count = 0; + for (lk = admin_locks; lk != NULL; lk = lk->admin_next) + if (lk->explicit_init) + count++; + if (count > 0) { + VG_(umsg)("%lu lock(s) were not destroyed before exit.\n", count); + for (lk = admin_locks; lk != NULL; lk = lk->admin_next) { + const HChar* kind = lk->kind == LK_rdwr ? "rwlock" : "mutex"; + if (!lk->explicit_init) + continue; + if (lk->appeared_at) { + VG_(umsg)("Undestroyed %s at address %p, first observed at:\n", + kind, (void*)lk->guestaddr); + VG_(pp_ExeContext)(lk->appeared_at); + } else { + VG_(umsg)("Undestroyed %s at address %p\n", + kind, (void*)lk->guestaddr); + } + } + } + } + if (VG_(clo_stats)) hg_print_stats(); } @@ -6062,7 +6162,7 @@ static void hg_pre_clo_init ( void ) VG_(details_version) (NULL); VG_(details_description) ("a thread error detector"); VG_(details_copyright_author)( - "Copyright (C) 2007-2024, and GNU GPL'd, by OpenWorks LLP et al."); + "Copyright (C) 2007-2026, and GNU GPL'd, by OpenWorks LLP et al."); VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 320 ); diff --git a/helgrind/libhb_core.c b/helgrind/libhb_core.c index 302028acec..f5c50a21e1 100644 --- a/helgrind/libhb_core.c +++ b/helgrind/libhb_core.c @@ -3158,7 +3158,6 @@ static void vts_tab__do_GC ( Bool show_stats ) tl_assert(old_te->u.remap == VtsID_INVALID); tl_assert(old_vts != NULL); tl_assert(old_vts->id == i); - tl_assert(old_vts->ts != NULL); /* It is in use. Make a pruned version. */ nBeforePruning++; diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index b8c5fd0e78..bfdb3fff2f 100644 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -7,6 +7,7 @@ dist_noinst_SCRIPTS = \ filter_xml \ filter_fiw \ filter_freebsd.awk \ + filter_darwin.awk \ filter_stderr_freebsd \ filter_bug392331 @@ -14,120 +15,110 @@ noinst_SCRIPTS = \ filter_stderr EXTRA_DIST = \ - annotate_hbefore.vgtest annotate_hbefore.stdout.exp \ - annotate_hbefore.stderr.exp \ - annotate_rwlock.vgtest annotate_rwlock.stdout.exp \ - annotate_rwlock.stderr.exp \ - annotate_smart_pointer.vgtest annotate_smart_pointer.stdout.exp \ - annotate_smart_pointer.stderr.exp \ + bug513598.vgtest \ + lock_destroy_report.vgtest lock_destroy_report.stderr.exp \ + annotate_hbefore.vgtest \ + annotate_hbefore_fair_sched.vgtest \ + annotate_rwlock.vgtest annotate_rwlock.stderr.exp \ + annotate_smart_pointer.vgtest annotate_smart_pointer.stderr.exp \ bug322621.vgtest bug322621.stderr.exp \ - bug327548.vgtest bug327548.stderr.exp \ + bug327548.vgtest \ bug392331.vgtest bug392331.stdout.exp bug392331.stderr.exp \ - bug392331_supp.vgtest bug392331_supp.stdout.exp bug392331_supp.stderr.exp \ + bug392331_supp.vgtest bug392331_supp.stdout.exp \ bug392331.supp \ - bug484480.vgtest bug484480.stderr.exp bug484480.stdout.exp \ + bug484480.vgtest bug484480.stdout.exp \ cond_init_destroy.vgtest cond_init_destroy.stderr.exp \ - cond_timedwait_invalid.vgtest cond_timedwait_invalid.stdout.exp \ - cond_timedwait_invalid.stderr.exp \ - cond_timedwait_test.vgtest cond_timedwait_test.stdout.exp \ - cond_timedwait_test.stderr.exp \ - bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \ + cond_timedwait_invalid.vgtest cond_timedwait_invalid.stderr.exp \ + cond_timedwait_test.vgtest cond_timedwait_test.stderr.exp \ + bar_bad.vgtest bar_bad.stderr.exp \ bar_bad.stderr.exp-destroy-hang \ bar_bad.stderr.exp-freebsd \ bar_bad.stderr.exp-illumos \ - bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \ - free_is_write.vgtest free_is_write.stdout.exp \ - free_is_write.stderr.exp \ - getaddrinfo.vgtest getaddrinfo.stderr.exp \ - hg01_all_ok.vgtest hg01_all_ok.stdout.exp hg01_all_ok.stderr.exp \ - hg02_deadlock.vgtest hg02_deadlock.stdout.exp hg02_deadlock.stderr.exp \ - hg03_inherit.vgtest hg03_inherit.stdout.exp hg03_inherit.stderr.exp \ - hg04_race.vgtest hg04_race.stdout.exp hg04_race.stderr.exp \ - hg04_race_h9.vgtest hg04_race_h9.stdout.exp hg04_race_h9.stderr.exp \ - hg05_race2.vgtest hg05_race2.stdout.exp hg05_race2.stderr.exp \ - hg06_readshared.vgtest hg06_readshared.stdout.exp \ - hg06_readshared.stderr.exp \ + bar_trivial.vgtest bar_trivial.stdout.exp \ + free_is_write.vgtest free_is_write.stderr.exp \ + getaddrinfo.vgtest \ + hg01_all_ok.vgtest hg01_all_ok.stderr.exp \ + hg02_deadlock.vgtest hg02_deadlock.stderr.exp \ + hg03_inherit.vgtest hg03_inherit.stderr.exp \ + hg04_race.vgtest hg04_race.stderr.exp \ + hg04_race_h9.vgtest hg04_race_h9.stderr.exp \ + hg05_race2.vgtest hg05_race2.stderr.exp \ + hg06_readshared.vgtest hg06_readshared.stderr.exp \ locked_vs_unlocked1_fwd.vgtest \ locked_vs_unlocked1_fwd.stderr.exp \ - locked_vs_unlocked1_fwd.stdout.exp \ locked_vs_unlocked1_rev.vgtest \ locked_vs_unlocked1_rev.stderr.exp \ - locked_vs_unlocked1_rev.stdout.exp \ locked_vs_unlocked2.vgtest \ locked_vs_unlocked2.stderr.exp \ - locked_vs_unlocked2.stdout.exp \ locked_vs_unlocked2.stderr.exp-freebsd \ locked_vs_unlocked3.vgtest \ locked_vs_unlocked3.stderr.exp \ - locked_vs_unlocked3.stdout.exp \ locked_vs_unlocked3.stderr.exp-freebsd \ - pth_barrier1.vgtest pth_barrier1.stdout.exp pth_barrier1.stderr.exp \ - pth_barrier2.vgtest pth_barrier2.stdout.exp pth_barrier2.stderr.exp \ - pth_barrier3.vgtest pth_barrier3.stdout.exp pth_barrier3.stderr.exp \ + pth_barrier1.vgtest pth_barrier1.stderr.exp \ + pth_barrier2.vgtest pth_barrier2.stderr.exp \ + pth_barrier3.vgtest pth_barrier3.stderr.exp \ pth_destroy_cond.vgtest \ pth_destroy_cond.stdout.exp pth_destroy_cond.stderr.exp \ pth_cond_destroy_busy.vgtest pth_cond_destroy_busy.stderr.exp \ pth_cond_destroy_busy.stderr.exp-ppc64 \ pth_cond_destroy_busy.stderr.exp-solaris \ pth_cond_destroy_busy.stderr.exp-freebsd \ - pth_mempcpy_false_races.vgtest pth_mempcpy_false_races.stderr.exp \ - pth_spinlock.vgtest pth_spinlock.stdout.exp pth_spinlock.stderr.exp \ - rwlock_race.vgtest rwlock_race.stdout.exp rwlock_race.stderr.exp \ - rwlock_test.vgtest rwlock_test.stdout.exp rwlock_test.stderr.exp \ + pth_mempcpy_false_races.vgtest \ + pth_spinlock.vgtest pth_spinlock.stderr.exp \ + rwlock_race.vgtest rwlock_race.stderr.exp \ + rwlock_test.vgtest rwlock_test.stderr.exp \ sem_clockwait_np.vgtest sem_clockwait_np.stdout.exp \ - sem_clockwait_np.stderr.exp \ - sem_timedwait.vgtest sem_timedwait.stdout.exp sem_timedwait.stderr.exp \ + sem_timedwait.vgtest sem_timedwait.stdout.exp \ shared_timed_mutex.vgtest shared_timed_mutex.stderr.exp \ - shmem_abits.vgtest shmem_abits.stdout.exp shmem_abits.stderr.exp \ - stackteardown.vgtest stackteardown.stdout.exp stackteardown.stderr.exp \ + shmem_abits.vgtest shmem_abits.stderr.exp \ + stackteardown.vgtest stackteardown.stderr.exp \ t2t_laog.vgtest t2t_laog.stdout.exp t2t_laog.stderr.exp \ - tc01_simple_race.vgtest tc01_simple_race.stdout.exp \ + tc01_simple_race.vgtest \ tc01_simple_race.stderr.exp \ - tc02_simple_tls.vgtest tc02_simple_tls.stdout.exp \ + tc02_simple_tls.vgtest \ tc02_simple_tls.stderr.exp \ - tc03_re_excl.vgtest tc03_re_excl.stdout.exp \ + tc03_re_excl.vgtest \ tc03_re_excl.stderr.exp \ - tc04_free_lock.vgtest tc04_free_lock.stdout.exp \ + tc04_free_lock.vgtest \ tc04_free_lock.stderr.exp \ tc04_free_lock.stderr.exp-freebsd \ - tc05_simple_race.vgtest tc05_simple_race.stdout.exp \ + tc05_simple_race.vgtest \ tc05_simple_race.stderr.exp \ - tc06_two_races.vgtest tc06_two_races.stdout.exp \ + tc06_two_races.vgtest \ tc06_two_races.stderr.exp \ - tc06_two_races_xml.vgtest tc06_two_races_xml.stdout.exp \ + tc06_two_races_xml.vgtest \ tc06_two_races_xml.stderr.exp \ tc06_two_races_xml.stderr.exp-freebsd \ tc07_hbl1.vgtest tc07_hbl1.stdout.exp tc07_hbl1.stderr.exp \ tc08_hbl2.vgtest tc08_hbl2.stdout.exp tc08_hbl2.stderr.exp \ - tc09_bad_unlock.vgtest tc09_bad_unlock.stdout.exp \ + tc09_bad_unlock.vgtest \ tc09_bad_unlock.stderr.exp tc09_bad_unlock.stderr.exp-solaris \ tc09_bad_unlock.stderr.exp-freebsd \ - tc10_rec_lock.vgtest tc10_rec_lock.stdout.exp tc10_rec_lock.stderr.exp \ + tc10_rec_lock.vgtest tc10_rec_lock.stderr.exp \ tc11_XCHG.vgtest tc11_XCHG.stdout.exp tc11_XCHG.stderr.exp \ - tc12_rwl_trivial.vgtest tc12_rwl_trivial.stdout.exp \ + tc12_rwl_trivial.vgtest \ tc12_rwl_trivial.stderr.exp \ tc12_rwl_trivial.stderr.exp-darwin970 \ - tc12_rwl_trivial.stderr.exp-solaris \ tc12_rwl_trivial.stderr.exp-freebsd \ - tc13_laog1.vgtest tc13_laog1.stdout.exp tc13_laog1.stderr.exp \ - tc14_laog_dinphils.vgtest tc14_laog_dinphils.stdout.exp \ + tc13_laog1.vgtest tc13_laog1.stderr.exp \ + tc14_laog_dinphils.vgtest \ tc14_laog_dinphils.stderr.exp \ - tc15_laog_lockdel.vgtest tc15_laog_lockdel.stdout.exp \ + tc15_laog_lockdel.vgtest \ tc15_laog_lockdel.stderr.exp \ - tc16_byterace.vgtest tc16_byterace.stdout.exp \ + tc16_byterace.vgtest \ tc16_byterace.stderr.exp \ - tc17_sembar.vgtest tc17_sembar.stdout.exp \ + tc17_sembar.vgtest \ tc17_sembar.stderr.exp \ - tc18_semabuse.vgtest tc18_semabuse.stdout.exp \ + tc18_semabuse.vgtest \ tc18_semabuse.stderr.exp \ tc18_semabuse.stderr.exp-linux-mips32 \ tc18_semabuse.stderr.exp-linux-mips32-b \ tc18_semabuse.stderr.exp-solaris \ tc18_semabuse.stderr.exp-freebsd \ - tc19_shadowmem.vgtest tc19_shadowmem.stdout.exp \ + tc19_shadowmem.vgtest \ tc19_shadowmem.stderr.exp tc19_shadowmem.stderr.exp-mips32 \ tc19_shadowmem.stderr.exp-mips32-BE \ - tc20_verifywrap.vgtest tc20_verifywrap.stdout.exp \ + tc20_verifywrap.vgtest \ tc20_verifywrap.stderr.exp \ tc20_verifywrap.stderr.exp-glibc-2.18 \ tc20_verifywrap.stderr.exp-glibc-2.21 \ @@ -136,19 +127,17 @@ EXTRA_DIST = \ tc20_verifywrap.stderr.exp-s390x \ tc20_verifywrap.stderr.exp-solaris \ tc21_pthonce.vgtest tc21_pthonce.stdout.exp tc21_pthonce.stderr.exp \ - tc22_exit_w_lock.vgtest tc22_exit_w_lock.stdout.exp \ + tc22_exit_w_lock.vgtest \ tc22_exit_w_lock.stderr.exp \ tc22_exit_w_lock.stderr.exp-kfail-x86 \ tc22_exit_w_lock.stderr.exp-solaris \ tc22_exit_w_lock.stderr.exp-freebsd15 \ - tc23_bogus_condwait.vgtest tc23_bogus_condwait.stdout.exp \ + tc23_bogus_condwait.vgtest \ tc23_bogus_condwait.stderr.exp \ tc23_bogus_condwait.stderr.exp-mips32 \ tc23_bogus_condwait.stderr.exp-freebsd \ - tc24_nonzero_sem.vgtest tc24_nonzero_sem.stdout.exp \ - tc24_nonzero_sem.stderr.exp \ - tls_threads.vgtest tls_threads.stdout.exp \ - tls_threads.stderr.exp \ + tc24_nonzero_sem.vgtest tc24_nonzero_sem.stderr.exp \ + tls_threads.vgtest tls_threads.stderr.exp \ tls_threads2.vgtest tls_threads2.stderr.exp \ trylock.vgtest trylock.stderr.exp @@ -159,7 +148,9 @@ noinst_HEADERS = safe-pthread.h safe-semaphore.h # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ + bug513598 \ bug327548 \ + lock_destroy_report \ bug484480 \ cond_init_destroy \ cond_timedwait_invalid \ @@ -272,11 +263,17 @@ else annotate_hbefore_CFLAGS = $(AM_CFLAGS) endif -tc09_bad_unlock_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_UNUSED_BUT_SET_VARIABLE@ bug322621_SOURCES = bug322621.cpp +bug327548_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +bug484480_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ if HAVE_CXX17 check_PROGRAMS += bug392331 bug392331_SOURCES = bug392331.cpp bug392331_CXXFLAGS = $(AM_CXXFLAGS) -std=c++17 endif +tc09_bad_unlock_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_UNUSED_BUT_SET_VARIABLE@ +tc17_sembar_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +tc18_semabuse_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +tc23_bogus_condwait_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +tc24_nonzero_sem_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ diff --git a/helgrind/tests/annotate_hbefore.stderr.exp b/helgrind/tests/annotate_hbefore.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/annotate_hbefore.stdout.exp b/helgrind/tests/annotate_hbefore.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/annotate_hbefore_fair_sched.vgtest b/helgrind/tests/annotate_hbefore_fair_sched.vgtest new file mode 100644 index 0000000000..9864513a45 --- /dev/null +++ b/helgrind/tests/annotate_hbefore_fair_sched.vgtest @@ -0,0 +1,3 @@ +prereq: ../../tests/os_test linux +vgopts: -q --fair-sched=yes +prog: annotate_hbefore diff --git a/helgrind/tests/annotate_rwlock.stdout.exp b/helgrind/tests/annotate_rwlock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/annotate_smart_pointer.stdout.exp b/helgrind/tests/annotate_smart_pointer.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bar_bad.stdout.exp b/helgrind/tests/bar_bad.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bar_trivial.stderr.exp b/helgrind/tests/bar_trivial.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bug327548.stderr.exp b/helgrind/tests/bug327548.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bug327548.vgtest b/helgrind/tests/bug327548.vgtest index e064b32572..c7505586ac 100644 --- a/helgrind/tests/bug327548.vgtest +++ b/helgrind/tests/bug327548.vgtest @@ -1,2 +1,3 @@ +prereq: ../../drd/tests/supported_sem_init vgopts: -q prog: bug327548 diff --git a/helgrind/tests/bug392331.vgtest b/helgrind/tests/bug392331.vgtest index f300c5cc13..3484935de7 100644 --- a/helgrind/tests/bug392331.vgtest +++ b/helgrind/tests/bug392331.vgtest @@ -1,4 +1,4 @@ -prereq: test -e bug392331 +prereq: test -e bug392331 && ! ../../tests/os_test darwin vgopts: -q --check-cond-signal-mutex=yes prog: bug392331 stderr_filter: filter_bug392331 diff --git a/helgrind/tests/bug392331_supp.stderr.exp b/helgrind/tests/bug392331_supp.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 64fc729607..5b4c526bf9 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,3 +1,3 @@ -prereq: test -e bug392331 +prereq: test -e bug392331 && ! ../../tests/os_test darwin vgopts: -q --suppressions=bug392331.supp prog: bug392331 diff --git a/helgrind/tests/bug484480.stderr.exp b/helgrind/tests/bug484480.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/bug484480.vgtest b/helgrind/tests/bug484480.vgtest index b130a2744e..44e7c68bb8 100644 --- a/helgrind/tests/bug484480.vgtest +++ b/helgrind/tests/bug484480.vgtest @@ -1,2 +1,3 @@ +prereq: ! ../../tests/os_test darwin vgopts: -q prog: bug484480 diff --git a/helgrind/tests/bug513598.c b/helgrind/tests/bug513598.c new file mode 100644 index 0000000000..9cc66fe5fa --- /dev/null +++ b/helgrind/tests/bug513598.c @@ -0,0 +1,22 @@ +/* Verify that no assert failure occurs when memory holding a mutex + is reused for an rwlock without calling pthread_mutex_destroy first. */ + +#include + +int main(void) +{ + /* Force both locks to occupy the same address. */ + union { + pthread_mutex_t mutex; + pthread_rwlock_t rwlock; + } u; + + pthread_mutex_init(&u.mutex, NULL); + /* Deliberately skip pthread_mutex_destroy, simulating memory reuse + with a different lock type. */ + pthread_rwlock_init(&u.rwlock, NULL); + pthread_rwlock_rdlock(&u.rwlock); + pthread_rwlock_unlock(&u.rwlock); + pthread_rwlock_destroy(&u.rwlock); + return 0; +} diff --git a/helgrind/tests/bug513598.vgtest b/helgrind/tests/bug513598.vgtest new file mode 100644 index 0000000000..99a2ae9956 --- /dev/null +++ b/helgrind/tests/bug513598.vgtest @@ -0,0 +1,3 @@ +prereq: test -e bug513598 +prog: bug513598 +vgopts: -q diff --git a/helgrind/tests/cond_timedwait_invalid.stdout.exp b/helgrind/tests/cond_timedwait_invalid.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/cond_timedwait_test.c b/helgrind/tests/cond_timedwait_test.c index e9b9be8a28..3b755917b4 100644 --- a/helgrind/tests/cond_timedwait_test.c +++ b/helgrind/tests/cond_timedwait_test.c @@ -1,20 +1,28 @@ #include #include +#include +#include -int main() { - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +int main(void) +{ + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + int res; - // This time has most definitely passed already. (Epoch) - struct timespec now; - memset(&now, 0, sizeof(now)); + // This time has most definitely passed already. (Epoch) + struct timespec now; + memset(&now, 0, sizeof(now)); - pthread_mutex_lock(&mutex); - pthread_cond_timedwait(&cond, &mutex, &now); - pthread_mutex_unlock(&mutex); + res = pthread_mutex_lock(&mutex); + assert(res == 0); + res = pthread_cond_timedwait(&cond, &mutex, &now); + assert(res == ETIMEDOUT); - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); + res = pthread_mutex_unlock(&mutex); + assert(res == 0); - return 0; + res = pthread_mutex_destroy(&mutex); + assert(res == 0); + res = pthread_cond_destroy(&cond); + assert(res == 0); } diff --git a/helgrind/tests/cond_timedwait_test.stdout.exp b/helgrind/tests/cond_timedwait_test.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/filter_darwin.awk b/helgrind/tests/filter_darwin.awk new file mode 100644 index 0000000000..b6c3c6c269 --- /dev/null +++ b/helgrind/tests/filter_darwin.awk @@ -0,0 +1,152 @@ +/pthread_create_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_create \(hg_intercepts.c/)) { + print " by 0x........: pthread_create@* (hg_intercepts.c:...)"; + print; + } else { + sub(/pthread_create/, "pthread_create@*"); + print; + } + next; +} +/pthread_cond_timedwait_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_cond_timedwait \(hg_intercepts.c/)) { + print " by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...)"; + print; + } else { + sub(/pthread_cond_timedwait/, "pthread_cond_timedwait@*"); + print; + } + next; +} +/pthread_cond_wait_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_cond_wait \(hg_intercepts.c/)) { + print " by 0x........: pthread_cond_wait@* (hg_intercepts.c:...)"; + print; + } else { + sub(/pthread_cond_wait/, "pthread_cond_wait@*"); + print; + } + next; +} +/pthread_cond_destroy_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_cond_destroy \(hg_intercepts.c/)) { + print " by 0x........: pthread_cond_destroy@* (hg_intercepts.c:...)"; + print; + } else { + sub(/pthread_cond_destroy/, "pthread_cond_destroy@*"); + print; + } + next; +} +/pthread_cond_signal_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_cond_signal \(hg_intercepts.c/)) { + print " by 0x........: pthread_cond_signal (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/mutex_lock_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_mutex_lock \(hg_intercepts.c/)) { + print " by 0x........: pthread_mutex_lock (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/mutex_unlock_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_mutex_unlock \(hg_intercepts.c/)) { + print " by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/pthread_rwlock_unlock_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_rwlock_unlock \(hg_intercepts.c/)) { + print " by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...)"; + if (!match($0, /pthread_rwlock_unlock\*/)) { + print; + } + } else { + print; + } + next; +} +/pthread_rwlock_init_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /pthread_rwlock_init \(hg_intercepts.c/)) { + print " by 0x........: pthread_rwlock_init (hg_intercepts.c:...)"; + if (!match($0, /pthread_rwlock_init*/)) { + print; + } + } else { + print; + } + next; +} +/sem_init_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /sem_init \(hg_intercepts.c/)) { + print " by 0x........: sem_init (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/sem_wait_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /sem_wait \(hg_intercepts.c/)) { + print " by 0x........: sem_wait (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/sem_post_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /sem_post \(hg_intercepts.c/)) { + print " by 0x........: sem_post (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +/sem_destroy_WRK \(hg_intercepts.c/ { + print; + getline; + if (!match($0, /sem_destroy \(hg_intercepts.c/)) { + print " by 0x........: sem_destroy (hg_intercepts.c:...)"; + print; + } else { + print; + } + next; +} +{print;} diff --git a/helgrind/tests/filter_stderr.in b/helgrind/tests/filter_stderr.in index 03a7d9e3b6..efb3e2f188 100644 --- a/helgrind/tests/filter_stderr.in +++ b/helgrind/tests/filter_stderr.in @@ -19,12 +19,18 @@ fi | # And FreeBSD if $dir/../../tests/os_test freebsd; then - #perl -p $dir/filter_stderr_freebsd awk -f $dir/filter_freebsd.awk else cat fi | +# And Darwin +if $dir/../../tests/os_test darwin; then + awk -f $dir/filter_darwin.awk +else + cat +fi | + # get rid of the numbers in bits of text "Thread #n", "thread #n", # "Thread n" and "thread n", "tid n" # as these make some tests more scheduling sensitive -- those where diff --git a/helgrind/tests/filter_stderr_solaris b/helgrind/tests/filter_stderr_solaris index b82dde943f..4a76ae09da 100755 --- a/helgrind/tests/filter_stderr_solaris +++ b/helgrind/tests/filter_stderr_solaris @@ -8,7 +8,7 @@ s/pthread_cond_timedwait \(hg_intercepts.c:/pthread_cond_timedwait@* \(hg_interc # We need to remove stack frames containing redundant function # names from libc, for example # by 0x........: pthread_mutex_init (in /...libc...) -my $check = join "|", ('pthread_mutex_init', 'pthread_cond_wait', 'pthread_cond_timedwait'); +my $check = join "|", ('pthread_mutex_init', 'pthread_cond_wait', 'pthread_cond_timedwait', 'pthread_rwlock_init'); s/^\s*by 0x........: (?:$check) \(in \/...libc...\)\s*//; # We also need to replace Solaris threading and sychronization function diff --git a/helgrind/tests/filter_xml b/helgrind/tests/filter_xml index 0dc77f7a44..d14887d91a 100755 --- a/helgrind/tests/filter_xml +++ b/helgrind/tests/filter_xml @@ -37,7 +37,7 @@ my %patterns = ( "(.*)" => "...", "(.*)" => "...", "thread #([0-9]+)" => "x", - "0x([0-9a-zA-Z]+)" => "........", + "(0x[0-9a-zA-Z]+)" => "0x........", "Using Valgrind-([^\\s]*)" => "X.Y.X", "Copyright \\(C\\) ([0-9]{4}-[0-9]{4}).*" => "XXXX-YYYY", 'pthread_.*(@\*)' => "", diff --git a/helgrind/tests/free_is_write.stdout.exp b/helgrind/tests/free_is_write.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/getaddrinfo.stderr.exp b/helgrind/tests/getaddrinfo.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg01_all_ok.stdout.exp b/helgrind/tests/hg01_all_ok.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg02_deadlock.stdout.exp b/helgrind/tests/hg02_deadlock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg03_inherit.stdout.exp b/helgrind/tests/hg03_inherit.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg04_race.stdout.exp b/helgrind/tests/hg04_race.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg04_race_h9.stdout.exp b/helgrind/tests/hg04_race_h9.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg05_race2.stdout.exp b/helgrind/tests/hg05_race2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/hg06_readshared.stdout.exp b/helgrind/tests/hg06_readshared.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/lock_destroy_report.c b/helgrind/tests/lock_destroy_report.c new file mode 100644 index 0000000000..5e0ad27d96 --- /dev/null +++ b/helgrind/tests/lock_destroy_report.c @@ -0,0 +1,20 @@ +/* Tests for --track-destroy. */ + +#include + +int main(void) +{ + pthread_mutex_t mx; + pthread_rwlock_t rw; + + pthread_mutex_init(&mx, NULL); + pthread_rwlock_init(&rw, NULL); + + /* mx is re-initialised without a prior destroy, which should + trigger a warning with --track-destroy=yes. */ + pthread_mutex_init(&mx, NULL); + + /* mx and rw are undestroyed at process exit, which should be + reported by --track-destroy=all. */ + return 0; +} diff --git a/helgrind/tests/lock_destroy_report.stderr.exp b/helgrind/tests/lock_destroy_report.stderr.exp new file mode 100644 index 0000000000..425cff742b --- /dev/null +++ b/helgrind/tests/lock_destroy_report.stderr.exp @@ -0,0 +1,14 @@ + +pthread_mutex_init called on address 0x........ which already has a live lock record + at 0x........: pthread_mutex_init (hg_intercepts.c:...) + by 0x........: main (lock_destroy_report.c:10) + +2 lock(s) were not destroyed before exit. +Undestroyed rwlock at address 0x........, first observed at: + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) + by 0x........: main (lock_destroy_report.c:11) +Undestroyed mutex at address 0x........, first observed at: + at 0x........: pthread_mutex_init (hg_intercepts.c:...) + by 0x........: main (lock_destroy_report.c:10) +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/lock_destroy_report.vgtest b/helgrind/tests/lock_destroy_report.vgtest new file mode 100644 index 0000000000..9fc361bb57 --- /dev/null +++ b/helgrind/tests/lock_destroy_report.vgtest @@ -0,0 +1,2 @@ +prog: lock_destroy_report +vgopts: --track-destroy=all diff --git a/helgrind/tests/locked_vs_unlocked1_fwd.stdout.exp b/helgrind/tests/locked_vs_unlocked1_fwd.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/locked_vs_unlocked1_rev.stdout.exp b/helgrind/tests/locked_vs_unlocked1_rev.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/locked_vs_unlocked2.stdout.exp b/helgrind/tests/locked_vs_unlocked2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/locked_vs_unlocked3.stdout.exp b/helgrind/tests/locked_vs_unlocked3.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/pth_barrier1.stdout.exp b/helgrind/tests/pth_barrier1.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/pth_barrier2.stdout.exp b/helgrind/tests/pth_barrier2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/pth_barrier3.stdout.exp b/helgrind/tests/pth_barrier3.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/pth_mempcpy_false_races.stderr.exp b/helgrind/tests/pth_mempcpy_false_races.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/pth_spinlock.stdout.exp b/helgrind/tests/pth_spinlock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/rwlock_race.stdout.exp b/helgrind/tests/rwlock_race.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/rwlock_test.stdout.exp b/helgrind/tests/rwlock_test.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/sem_clockwait_np.stderr.exp b/helgrind/tests/sem_clockwait_np.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/sem_timedwait.stderr.exp b/helgrind/tests/sem_timedwait.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/shmem_abits.stdout.exp b/helgrind/tests/shmem_abits.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/stackteardown.stdout.exp b/helgrind/tests/stackteardown.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc01_simple_race.stdout.exp b/helgrind/tests/tc01_simple_race.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc02_simple_tls.stdout.exp b/helgrind/tests/tc02_simple_tls.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc03_re_excl.stdout.exp b/helgrind/tests/tc03_re_excl.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc04_free_lock.stdout.exp b/helgrind/tests/tc04_free_lock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc05_simple_race.stdout.exp b/helgrind/tests/tc05_simple_race.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc06_two_races.stdout.exp b/helgrind/tests/tc06_two_races.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc06_two_races_xml.stdout.exp b/helgrind/tests/tc06_two_races_xml.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc09_bad_unlock.stdout.exp b/helgrind/tests/tc09_bad_unlock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc10_rec_lock.stdout.exp b/helgrind/tests/tc10_rec_lock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc12_rwl_trivial.c b/helgrind/tests/tc12_rwl_trivial.c index 35702ebb09..24f312c663 100644 --- a/helgrind/tests/tc12_rwl_trivial.c +++ b/helgrind/tests/tc12_rwl_trivial.c @@ -27,7 +27,7 @@ int main ( void ) /* this should fail - lock is unowned now */ r = pthread_rwlock_unlock( &rwl ); -#if defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) +#if defined(VGO_solaris) || defined(VGO_freebsd) assert(r != 0); #else assert(r == 0); diff --git a/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris b/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris deleted file mode 100644 index 7de254993a..0000000000 --- a/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris +++ /dev/null @@ -1,31 +0,0 @@ - ----Thread-Announcement------------------------------------------ - -Thread #x is the program's root thread - ----------------------------------------------------------------- - -Thread #x unlocked a not-locked lock at 0x........ - at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) - by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) - ... - by 0x........: main (tc12_rwl_trivial.c:29) - Lock at 0x........ was first observed - at 0x........: pthread_rwlock_init (hg_intercepts.c:...) - ... - by 0x........: main (tc12_rwl_trivial.c:18) - Address 0x........ is on thread #x's stack - in frame #x, created by main (tc12_rwl_trivial.c:14) - - ----------------------------------------------------------------- - -Thread #x's call to pthread_rwlock_unlock failed - with error code 1 (EPERM: Operation not permitted) - at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) - by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) - ... - by 0x........: main (tc12_rwl_trivial.c:29) - - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/tc12_rwl_trivial.stdout.exp b/helgrind/tests/tc12_rwl_trivial.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc13_laog1.stdout.exp b/helgrind/tests/tc13_laog1.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc14_laog_dinphils.stdout.exp b/helgrind/tests/tc14_laog_dinphils.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc15_laog_lockdel.stdout.exp b/helgrind/tests/tc15_laog_lockdel.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc16_byterace.stdout.exp b/helgrind/tests/tc16_byterace.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc17_sembar.c b/helgrind/tests/tc17_sembar.c index ee40160b08..9f8d3fa8c0 100644 --- a/helgrind/tests/tc17_sembar.c +++ b/helgrind/tests/tc17_sembar.c @@ -253,7 +253,11 @@ static sem_t* my_sem_init (char* identity, int pshared, unsigned count) static int my_sem_destroy ( sem_t* s ) { +#if defined(VGO_darwin) +return 0; +#else return sem_destroy(s); +#endif } static int my_sem_wait(sem_t* s) diff --git a/helgrind/tests/tc17_sembar.stdout.exp b/helgrind/tests/tc17_sembar.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc18_semabuse.stdout.exp b/helgrind/tests/tc18_semabuse.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc18_semabuse.vgtest b/helgrind/tests/tc18_semabuse.vgtest index fe4d22ba17..4818d739d4 100644 --- a/helgrind/tests/tc18_semabuse.vgtest +++ b/helgrind/tests/tc18_semabuse.vgtest @@ -1 +1,2 @@ +prereq: ../../drd/tests/supported_sem_init prog: tc18_semabuse diff --git a/helgrind/tests/tc19_shadowmem.stdout.exp b/helgrind/tests/tc19_shadowmem.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris index 64edaaca2f..c22ec807cf 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris @@ -158,8 +158,8 @@ Thread #x unlocked a not-locked lock at 0x........ ... by 0x........: main (tc20_verifywrap.c:194) Lock at 0x........ was first observed - at 0x........: pthread_rwlock_init (hg_intercepts.c:...) - ... + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:193) Location 0x........ is 0 bytes inside rwl.__pthread_rwlock_readers, declared at tc20_verifywrap.c:57, in frame #x of thread x @@ -185,8 +185,8 @@ Thread #x unlocked a not-locked lock at 0x........ ... by 0x........: main (tc20_verifywrap.c:211) Lock at 0x........ was first observed - at 0x........: pthread_rwlock_init (hg_intercepts.c:...) - ... + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:201) Location 0x........ is 0 bytes inside rwl2.__pthread_rwlock_readers, declared at tc20_verifywrap.c:58, in frame #x of thread x @@ -214,8 +214,8 @@ Thread #x unlocked a not-locked lock at 0x........ ... by 0x........: main (tc20_verifywrap.c:232) Lock at 0x........ was first observed - at 0x........: pthread_rwlock_init (hg_intercepts.c:...) - ... + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:201) Location 0x........ is 0 bytes inside rwl2.__pthread_rwlock_readers, declared at tc20_verifywrap.c:58, in frame #x of thread x diff --git a/helgrind/tests/tc20_verifywrap.stdout.exp b/helgrind/tests/tc20_verifywrap.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc22_exit_w_lock.stdout.exp b/helgrind/tests/tc22_exit_w_lock.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc23_bogus_condwait.c b/helgrind/tests/tc23_bogus_condwait.c index f2ccf3517f..b106748179 100644 --- a/helgrind/tests/tc23_bogus_condwait.c +++ b/helgrind/tests/tc23_bogus_condwait.c @@ -90,7 +90,10 @@ int main ( void ) r= pthread_join( my_rescuer, NULL ); assert(!r); r= pthread_join( grabber, NULL ); assert(!r); - r= my_sem_destroy( quit_now ); assert(!r); + r= my_sem_destroy( quit_now ); +#if !defined(VGO_darwin) + assert(!r); +#endif return 0; } diff --git a/helgrind/tests/tc23_bogus_condwait.stdout.exp b/helgrind/tests/tc23_bogus_condwait.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc23_bogus_condwait.vgtest b/helgrind/tests/tc23_bogus_condwait.vgtest index 918cd86e4c..09ca6a65bf 100644 --- a/helgrind/tests/tc23_bogus_condwait.vgtest +++ b/helgrind/tests/tc23_bogus_condwait.vgtest @@ -1,3 +1,4 @@ +prereq: ../../drd/tests/supported_sem_init prog: tc23_bogus_condwait vgopts: -q --check-cond-signal-mutex=yes diff --git a/helgrind/tests/tc24_nonzero_sem.c b/helgrind/tests/tc24_nonzero_sem.c index 541fa7ddb8..9b08adee45 100644 --- a/helgrind/tests/tc24_nonzero_sem.c +++ b/helgrind/tests/tc24_nonzero_sem.c @@ -44,7 +44,14 @@ int main ( void ) assert(!r); } - r= my_sem_destroy(sem); assert(!r); + r= my_sem_destroy(sem); +#if defined(VGO_darwin) + // This outputs "function not implemented" if uncommented + //if (r != 0) + // perror("sem_destroy"); +#else + assert(!r); +#endif return 0; } diff --git a/helgrind/tests/tc24_nonzero_sem.stdout.exp b/helgrind/tests/tc24_nonzero_sem.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helgrind/tests/tc24_nonzero_sem.vgtest b/helgrind/tests/tc24_nonzero_sem.vgtest index 1a43121eb7..87f4b8bfd1 100644 --- a/helgrind/tests/tc24_nonzero_sem.vgtest +++ b/helgrind/tests/tc24_nonzero_sem.vgtest @@ -1,2 +1,3 @@ +prereq: ../../drd/tests/supported_sem_init prog: tc24_nonzero_sem vgopts: --hg-sanity-flags=111111 diff --git a/helgrind/tests/tls_threads.stdout.exp b/helgrind/tests/tls_threads.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/pub_tool_aspacemgr.h b/include/pub_tool_aspacemgr.h index 2f4775d6eb..cefd595afc 100644 --- a/include/pub_tool_aspacemgr.h +++ b/include/pub_tool_aspacemgr.h @@ -113,6 +113,9 @@ typedef #if defined(VGO_freebsd) Bool isFF; // True --> is a fixed file mapping Bool ignore_offset; // True --> we can't work out segment offset +#endif +#if defined(VGO_linux) + Bool hasGuardPages; // True --> contains guard page (bug 514297) #endif } NSegment; diff --git a/include/pub_tool_execontext.h b/include/pub_tool_execontext.h index 4f5d04ff8b..bcb3ce51a1 100644 --- a/include/pub_tool_execontext.h +++ b/include/pub_tool_execontext.h @@ -121,6 +121,10 @@ static inline Bool VG_(is_plausible_ECU)( UInt ecu ) { // Make an ExeContext containing exactly the specified stack frames. ExeContext* VG_(make_ExeContext_from_StackTrace)( const Addr* ips, UInt n_ips ); +// Get the name of the topmost function from an ExeContext +const HChar* VG_(get_ExeContext_first_fnname)(ExeContext* ec); + + // Returns the "null" exe context. The null execontext is an artificial // exe context, with a stack trace made of one Addr (the NULL address). extern diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h index 7fb7bf04de..854d7e3116 100644 --- a/include/pub_tool_libcbase.h +++ b/include/pub_tool_libcbase.h @@ -72,9 +72,9 @@ extern double VG_(strtod) ( const HChar* str, HChar** endptr ); ------------------------------------------------------------------ */ /* Use this for normal null-termination-style string comparison. */ -#define VG_STREQ(s1,s2) ( (s1 != NULL && s2 != NULL \ +#define VG_STREQ(s1,s2) ( ((s1) != NULL && (s2) != NULL \ && VG_(strcmp)((s1),(s2))==0) ? True : False ) -#define VG_STREQN(n,s1,s2) ( (s1 != NULL && s2 != NULL \ +#define VG_STREQN(n,s1,s2) ( ((s1) != NULL && (s2) != NULL \ && VG_(strncmp)((s1),(s2),(n))==0) ? True : False ) extern SizeT VG_(strlen) ( const HChar* str ); diff --git a/include/pub_tool_machine.h b/include/pub_tool_machine.h index c3d55efcba..b4f18951f2 100644 --- a/include/pub_tool_machine.h +++ b/include/pub_tool_machine.h @@ -32,14 +32,14 @@ #include "pub_tool_basics.h" // ThreadID #include "libvex.h" // VexArchInfo -#if defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd) +#if defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd) || defined(VGP_x86_darwin) # define VG_MIN_INSTR_SZB 1 // min length of native instruction # define VG_MAX_INSTR_SZB 16 // max length of native instruction # define VG_CLREQ_SZB 14 // length of a client request, may // be larger than VG_MAX_INSTR_SZB # define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP -#elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd) +#elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd) || defined(VGP_amd64_darwin) # define VG_MIN_INSTR_SZB 1 # define VG_MAX_INSTR_SZB 16 # define VG_CLREQ_SZB 19 @@ -77,19 +77,6 @@ # define VG_CLREQ_SZB 10 # define VG_STACK_REDZONE_SZB 0 // s390 has no redzone -#elif defined(VGP_x86_darwin) -# define VG_MIN_INSTR_SZB 1 // min length of native instruction -# define VG_MAX_INSTR_SZB 16 // max length of native instruction -# define VG_CLREQ_SZB 14 // length of a client request, may - // be larger than VG_MAX_INSTR_SZB -# define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP - -#elif defined(VGP_amd64_darwin) -# define VG_MIN_INSTR_SZB 1 -# define VG_MAX_INSTR_SZB 16 -# define VG_CLREQ_SZB 19 -# define VG_STACK_REDZONE_SZB 128 - #elif defined(VGP_mips32_linux) # define VG_MIN_INSTR_SZB 4 # define VG_MAX_INSTR_SZB 8 diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h index c19fd3d97e..e2cbac44fb 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -247,11 +247,11 @@ #else # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* #endif -#elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6) -# define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib +#elif defined(VGO_darwin) -#elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \ - || DARWIN_VERS == DARWIN_10_8) +#if (DARWIN_VERS <= DARWIN_10_6) +# define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib +#elif (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8) # define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib /* Note that the idea of a single name for the C library falls apart on more recent Darwins (10.8 and later) since the @@ -260,13 +260,17 @@ libsystem_platform.dylib. This makes VG_Z_LIBC_SONAME somewhat useless at least inside vg_replace_strmem.c, and that hardwires some dylib names directly, for OSX 10.9. */ - -#elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9) +#elif (DARWIN_VERS >= DARWIN_10_9) # define VG_Z_LIBC_SONAME libsystemZumallocZddylib // libsystem_malloc.dylib +#endif + +/* Not tested on systems older than OSX 10.13 */ +#define VG_Z_LIBSYSTEM_C_SONAME libsystemZucZddylib +#define VG_Z_LIBSYSTEM_PLATFORM_SONAME libsystemZuplatformZddylib +#define VG_Z_LIBSYSTEM_KERNEL_SONAME libsystemZukernelZddylib #else # error "Unknown platform" - #endif /* --- Sonames of the GNU C++ library. --- */ @@ -286,7 +290,8 @@ #elif defined(VGO_freebsd) # define VG_Z_LIBPTHREAD_SONAME libthrZdsoZa // libthr.so* #elif defined(VGO_darwin) -# define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib +//# define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib +# define VG_Z_LIBPTHREAD_SONAME libsystemZupthreadZddylib // libSystem.*.dylib #elif defined(VGO_solaris) # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd1 // libpthread.so.1 #else diff --git a/include/valgrind.h.in b/include/valgrind.h.in index 24a6599985..ed7d8c68e2 100644 --- a/include/valgrind.h.in +++ b/include/valgrind.h.in @@ -266,7 +266,7 @@ inline asm stuff to be useful. */ -/* ----------------- x86-{linux,darwin,solaris} ---------------- */ +/* -------------- x86-{linux,darwin,solaris,freebsd} ------------- */ #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ || (defined(PLAT_x86_win32) && defined(__GNUC__)) \ @@ -331,7 +331,7 @@ typedef } while (0) #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) - || PLAT_x86_solaris */ + || PLAT_x86_solaris || PLAT_x86_freebsd */ /* ------------------------- x86-Win32 ------------------------- */ @@ -406,7 +406,7 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, #endif /* PLAT_x86_win32 */ -/* ----------------- amd64-{linux,darwin,solaris} --------------- */ +/* -------------- amd64-{linux,darwin,solaris,freebsd} ------------ */ #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ || defined(PLAT_amd64_solaris) \ @@ -471,7 +471,8 @@ typedef ); \ } while (0) -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin + || PLAT_amd64_solaris || PLAT_amd64_freebsd */ /* ------------------------- amd64-Win64 ------------------------- */ @@ -774,7 +775,7 @@ typedef #endif /* PLAT_arm_linux */ -/* ------------------------ arm64-{linux,freebsd} ------------------------- */ +/* -------------------- arm64-{linux,freebsd} -------------------- */ #if defined(PLAT_arm64_linux) || defined(PLAT_arm64_freebsd) @@ -1310,7 +1311,7 @@ typedef do { volatile unsigned long _junk; \ CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) -/* ----------------- x86-{linux,darwin,solaris} ---------------- */ +/* -------------- x86-{linux,darwin,solaris,freebsd} ------------- */ #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ || defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd) @@ -1740,9 +1741,10 @@ typedef lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */ +#endif /* PLAT_x86_linux || PLAT_x86_darwin + || PLAT_x86_solaris || PLAT_x86_freebsd */ -/* ---------------- amd64-{linux,darwin,solaris} --------------- */ +/* ------------- amd64-{linux,darwin,solaris,freebsd} ------------ */ #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ || defined(PLAT_amd64_solaris) || defined(PLAT_amd64_freebsd) @@ -2294,7 +2296,8 @@ typedef lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin + || PLAT_amd64_solaris || PLAT_amd64_freebsd */ /* ------------------------ ppc32-linux ------------------------ */ @@ -4368,7 +4371,7 @@ typedef #endif /* PLAT_arm_linux */ -/* ------------------------ arm64-linux ------------------------ */ +/* ------------------- arm64-{linux,freebsd} -------------------- */ #if defined(PLAT_arm64_linux) || defined(PLAT_arm64_freebsd) @@ -4817,7 +4820,7 @@ typedef lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_arm64_linux */ +#endif /* PLAT_arm64_linux || PLAT_arm64_freebsd */ /* ------------------------- s390x-linux ------------------------- */ @@ -7166,8 +7169,10 @@ typedef ENTRIES, NOR DELETE ANY -- add new ones at the end of the most relevant group. */ typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, + enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, + VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, + VG_USERREQ__VALGRIND_REPLACES_MALLOC = 0x1003, + VG_USERREQ__VALGRIND_GET_TOOLNAME = 0x1004, /* These allow any function to be called from the simulated CPU but run on the real CPU. Nb: the first arg passed to @@ -7270,6 +7275,30 @@ typedef VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ _qzz_addr, _qzz_len, 0, 0, 0) +/* Returns 1 if the tool replaces malloc (e.g., memcheck). Returns 0 + if the tool does not replace malloc (e.g., cachegrind and callgrind) + or if the executable is not running under VALGRIND. */ +#define VALGRIND_REPLACES_MALLOC \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ + VG_USERREQ__VALGRIND_REPLACES_MALLOC, \ + 0, 0, 0, 0, 0) + +/* Get the running tool name as a string. + Returns the required length (including terminating nul) for the input + zzbuf. Returns 0 and the contents of zzbuf are not modified + if not running under Valgrind. + zzbuf may be NULL, which can be used to query the required buffer + length before making a real request for the tool name. + zzbuflen should be the length of zzbuf. + The returned string in zzbuf will be nul terminated. If zzbuf is too + small to contain the tool name then the name will be truncated */ +#define VALGRIND_GET_TOOLNAME(zzbuf,zzbuflen) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__VALGRIND_GET_TOOLNAME, \ + (char*)(zzbuf), \ + (zzbuflen), \ + 0, 0, 0) + #define VALGRIND_INNER_THREADS(_qzz_addr) \ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS, \ _qzz_addr, 0, 0, 0, 0) @@ -7684,6 +7713,9 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) #undef PLAT_x86_darwin #undef PLAT_amd64_darwin +#undef PLAT_x86_freebsd +#undef PLAT_amd64_freebsd +#undef PLAT_arm64_freebsd #undef PLAT_x86_win32 #undef PLAT_amd64_win64 #undef PLAT_x86_linux diff --git a/include/vki/vki-amd64-freebsd.h b/include/vki/vki-amd64-freebsd.h index 7db0e756d5..f52b4eaed2 100644 --- a/include/vki/vki-amd64-freebsd.h +++ b/include/vki/vki-amd64-freebsd.h @@ -4,7 +4,7 @@ Copyright (C) 2000-2005 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2022 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or diff --git a/include/vki/vki-darwin.h b/include/vki/vki-darwin.h index 93433d4f0b..47a90ec5f5 100644 --- a/include/vki/vki-darwin.h +++ b/include/vki/vki-darwin.h @@ -83,13 +83,112 @@ // magic mmap() flags #define VKI_MAP_ANONYMOUS MAP_ANON // linux synonym +// See xnu/osfmk/mach/vm_statistics.h +#define VKI_VM_MEMORY_MALLOC 1 +#define VKI_VM_MEMORY_MALLOC_SMALL 2 +#define VKI_VM_MEMORY_MALLOC_LARGE 3 +#define VKI_VM_MEMORY_MALLOC_HUGE 4 +#define VKI_VM_MEMORY_BRK 5 +#define VKI_VM_MEMORY_REALLOC 6 +#define VKI_VM_MEMORY_MALLOC_TINY 7 +#define VKI_VM_MEMORY_MALLOC_LARGE_REUSABLE 8 +#define VKI_VM_MEMORY_MALLOC_LARGE_REUSED 9 +#define VKI_VM_MEMORY_ANALYSIS_TOOL 10 +#define VKI_VM_MEMORY_MALLOC_NANO 11 +#define VKI_VM_MEMORY_MALLOC_MEDIUM 12 +#define VKI_VM_MEMORY_MALLOC_PROB_GUARD 13 +#define VKI_VM_MEMORY_MACH_MSG 20 +#define VKI_VM_MEMORY_IOKIT 21 +#define VKI_VM_MEMORY_STACK 30 +#define VKI_VM_MEMORY_GUARD 31 +#define VKI_VM_MEMORY_SHARED_PMAP 32 +#define VKI_VM_MEMORY_DYLIB 33 +#define VKI_VM_MEMORY_OBJC_DISPATCHERS 34 +#define VKI_VM_MEMORY_UNSHARED_PMAP 35 +#define VKI_VM_MEMORY_APPKIT 40 +#define VKI_VM_MEMORY_FOUNDATION 41 +#define VKI_VM_MEMORY_COREGRAPHICS 42 +#define VKI_VM_MEMORY_CORESERVICES 43 +#define VKI_VM_MEMORY_JAVA 44 +#define VKI_VM_MEMORY_COREDATA 45 +#define VKI_VM_MEMORY_COREDATA_OBJECTIDS 46 +#define VKI_VM_MEMORY_ATS 50 +#define VKI_VM_MEMORY_LAYERKIT 51 +#define VKI_VM_MEMORY_CGIMAGE 52 +#define VKI_VM_MEMORY_TCMALLOC 53 +#define VKI_VM_MEMORY_COREGRAPHICS_DATA 54 +#define VKI_VM_MEMORY_COREGRAPHICS_SHARED 55 +#define VKI_VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS 56 +#define VKI_VM_MEMORY_COREGRAPHICS_BACKINGSTORES 57 +#define VKI_VM_MEMORY_COREGRAPHICS_XALLOC 58 +#define VKI_VM_MEMORY_DYLD 60 +#define VKI_VM_MEMORY_DYLD_MALLOC 61 +#define VKI_VM_MEMORY_SQLITE 62 +#define VKI_VM_MEMORY_JAVASCRIPT_CORE 63 +#define VKI_VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR 64 +#define VKI_VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE 65 +#define VKI_VM_MEMORY_GLSL 66 +#define VKI_VM_MEMORY_OPENCL 67 +#define VKI_VM_MEMORY_COREIMAGE 68 +#define VKI_VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS 69 +#define VKI_VM_MEMORY_IMAGEIO 70 +#define VKI_VM_MEMORY_COREPROFILE 71 +#define VKI_VM_MEMORY_ASSETSD 72 +#define VKI_VM_MEMORY_OS_ALLOC_ONCE 73 +#define VKI_VM_MEMORY_LIBDISPATCH 74 +#define VKI_VM_MEMORY_ACCELERATE 75 +#define VKI_VM_MEMORY_COREUI 76 +#define VKI_VM_MEMORY_COREUIFILE 77 +#define VKI_VM_MEMORY_GENEALOGY 78 +#define VKI_VM_MEMORY_RAWCAMERA 79 +#define VKI_VM_MEMORY_CORPSEINFO 80 +#define VKI_VM_MEMORY_ASL 81 +#define VKI_VM_MEMORY_SWIFT_RUNTIME 82 +#define VKI_VM_MEMORY_SWIFT_METADATA 83 +#define VKI_VM_MEMORY_DHMM 84 +#define VKI_VM_MEMORY_SCENEKIT 86 +#define VKI_VM_MEMORY_SKYWALK 87 +#define VKI_VM_MEMORY_IOSURFACE 88 +#define VKI_VM_MEMORY_LIBNETWORK 89 +#define VKI_VM_MEMORY_AUDIO 90 +#define VKI_VM_MEMORY_VIDEOBITSTREAM 91 +#define VKI_VM_MEMORY_CM_XPC 92 +#define VKI_VM_MEMORY_CM_RPC 93 +#define VKI_VM_MEMORY_CM_MEMORYPOOL 94 +#define VKI_VM_MEMORY_CM_READCACHE 95 +#define VKI_VM_MEMORY_CM_CRABS 96 +#define VKI_VM_MEMORY_QUICKLOOK_THUMBNAILS 97 +#define VKI_VM_MEMORY_ACCOUNTS 98 +#define VKI_VM_MEMORY_SANITIZER 99 +#define VKI_VM_MEMORY_IOACCELERATOR 100 +#define VKI_VM_MEMORY_CM_REGWARP 101 +#define VKI_VM_MEMORY_EAR_DECODER 102 +#define VKI_VM_MEMORY_COREUI_CACHED_IMAGE_DATA 103 +#define VKI_VM_MEMORY_COLORSYNC 104 +#define VKI_VM_MEMORY_BTINFO 105 +#define VKI_VM_MEMORY_CM_HLS 106 +#define VKI_VM_MEMORY_ROSETTA 230 +#define VKI_VM_MEMORY_ROSETTA_THREAD_CONTEXT 231 +#define VKI_VM_MEMORY_ROSETTA_INDIRECT_BRANCH_MAP 232 +#define VKI_VM_MEMORY_ROSETTA_RETURN_STACK 233 +#define VKI_VM_MEMORY_ROSETTA_EXECUTABLE_HEAP 234 +#define VKI_VM_MEMORY_ROSETTA_USER_LDT 235 +#define VKI_VM_MEMORY_ROSETTA_ARENA 236 +#define VKI_VM_MEMORY_ROSETTA_10 239 +#define VKI_VM_MEMORY_APPLICATION_SPECIFIC_1 240 +#define VKI_VM_MEMORY_VALGRIND 242 +#define VKI_VM_MEMORY_APPLICATION_SPECIFIC_16 255 + // fds for mmap(MAP_ANON), displayed by vmmap -#define VM_TAG_VALGRIND VM_MAKE_TAG(239) // SkAnonV +#define VM_TAG_VALGRIND VM_MAKE_TAG(VKI_VM_MEMORY_VALGRIND) // SkAnonV // page sizes #define VKI_MAX_PAGE_SHIFT VKI_PAGE_SHIFT #define VKI_MAX_PAGE_SIZE VKI_PAGE_SIZE +// pthread +#define VKI_PTHREAD_START_CUSTOM 0x01000000 + // types typedef uint32_t vki_u32; @@ -197,7 +296,7 @@ typedef uint32_t vki_u32; #define vki_cmsghdr cmsghdr -#define VKI_CMSG_ALIGN(a) ALIGN(a) +#define VKI_CMSG_ALIGN(a) __DARWIN_ALIGN32(a) #define VKI_CMSG_DATA(cmsg) CMSG_DATA(cmsg) #define VKI_CMSG_FIRSTHDR(mhdr) CMSG_FIRSTHDR(mhdr) #define VKI_CMSG_NXTHDR(mhdr, cmsg) CMSG_NXTHDR(mhdr, cmsg) @@ -309,11 +408,20 @@ typedef uint32_t vki_u32; # define VKI_F_BARRIERFSYNC F_BARRIERFSYNC # define VKI_F_ADDFILESIGS_RETURN F_ADDFILESIGS_RETURN #endif +#if DARWIN_VERS >= DARWIN_10_14 +# define VKI_F_CHECK_LV F_CHECK_LV +#endif +#if DARWIN_VERS >= DARWIN_10_15 +# define VKI_F_SPECULATIVE_READ F_SPECULATIVE_READ +#endif #define VKI_F_FULLFSYNC F_FULLFSYNC #define VKI_F_PATHPKG_CHECK F_PATHPKG_CHECK #define VKI_F_FREEZE_FS F_FREEZE_FS #define VKI_F_THAW_FS F_THAW_FS #define VKI_F_GLOBAL_NOCACHE F_GLOBAL_NOCACHE +#if defined(F_GETPROTECTIONCLASS) +#define VKI_F_GETPROTECTIONCLASS F_GETPROTECTIONCLASS +#endif #define VKI_FD_CLOEXEC FD_CLOEXEC @@ -348,6 +456,10 @@ typedef uint32_t vki_u32; #define VKI_MAP_RESERVED0080 MAP_RESERVED0080 #define VKI_MAP_NOEXTEND MAP_NOEXTEND #define VKI_MAP_HASSEMAPHORE MAP_HASSEMAPHORE +#if DARWIN_VERS >= DARWIN_11_00 +#define VKI_MAP_NOCACHE MAP_NOCACHE +#define VKI_MAP_JIT MAP_JIT +#endif #define VKI_MAP_FILE MAP_FILE #define VKI_MAP_ANON MAP_ANON #define VKI_MAP_FAILED MAP_FAILED @@ -427,6 +539,9 @@ typedef struct { //typedef struct __sigaction vki_sigaction_toK_t; //typedef struct sigaction vki_sigaction_fromK_t; +#define VKI_UC_TRAD 1 +#define VKI_UC_FLAVOR 30 + typedef struct { void* ksa_handler; @@ -879,6 +994,11 @@ struct ByteRangeLockPB2 #define VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY 128 /* max() in the provided priority in the the priority of the event manager */ #define VKI_WQOPS_THREAD_WORKLOOP_RETURN 256 /* parks the thread after delivering the passed kevent array */ #define VKI_WQOPS_SHOULD_NARROW 512 /* checks whether we should narrow our concurrency */ +#define VKI_WQOPS_SETUP_DISPATCH 1024 /* setup pthread workqueue-related operations */ + +#define VKI_WORKQ_DISPATCH_CONFIG_VERSION 2 +#define VKI_WORKQ_DISPATCH_MIN_SUPPORTED_VERSION 1 +#define VKI_WORKQ_DISPATCH_SUPPORTED_FLAGS 0 #include @@ -1175,6 +1295,13 @@ struct vki_necp_aggregate_result { #define VKI_IFXNAMSIZ IFNAMSIZ + 8 #define VKI_IFNET_SIGNATURELEN 20 +#define VKI_UL_COMPARE_AND_WAIT 1 +#define VKI_UL_UNFAIR_LOCK 2 +#define VKI_UL_COMPARE_AND_WAIT_SHARED 3 +#define VKI_UL_UNFAIR_LOCK64_SHARED 4 +#define VKI_UL_COMPARE_AND_WAIT64 5 +#define VKI_UL_COMPARE_AND_WAIT64_SHARED 6 + struct vki_necp_client_signable { uuid_t client_id; u_int32_t sign_type; @@ -1215,4 +1342,41 @@ struct vki_necp_agent_use_parameters { #endif /* DARWIN_VERS >= DARWIN_10_12 */ +#include + +typedef posix_spawn_file_actions_t vki_posix_spawn_file_actions_t; +typedef posix_spawnattr_t vki_posix_spawnattr_t; + +// from sys/persona.h, not public +#define VKI_PERSONA_INFO_V1 1 +#define VKI_PERSONA_INFO_V2 2 +#define VKI_PERSONA_OP_ALLOC 1 +#define VKI_PERSONA_OP_PALLOC 2 +#define VKI_PERSONA_OP_DEALLOC 3 +#define VKI_PERSONA_OP_GET 4 +#define VKI_PERSONA_OP_INFO 5 +#define VKI_PERSONA_OP_PIDINFO 6 +#define VKI_PERSONA_OP_FIND 7 +#define VKI_PERSONA_OP_GETPATH 8 +#define VKI_PERSONA_OP_FIND_BY_TYPE 9 + +#define VKI_MAXLOGNAME 255 + +struct vki_kpersona_info { + /* v1 fields */ + vki_uint32_t persona_info_version; + + uid_t persona_id; + Int persona_type; + vki_gid_t persona_gid; /* unused */ + vki_uint32_t persona_ngroups; /* unused */ + vki_gid_t persona_groups[NGROUPS]; /* unused */ + vki_uid_t persona_gmuid; /* unused */ + HChar persona_name[VKI_MAXLOGNAME + 1]; + + /* v2 fields */ + vki_uid_t persona_uid; +} __attribute__((packed)); + + #endif diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index b5c7c84bc9..2a54f500ba 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -9,7 +9,7 @@ Copyright (C) 2000-2005 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -2236,6 +2236,18 @@ struct vki_kinfo_file { #define VKI_KENV_DUMP_LOADER 4 #define VKI_KENV_DUMP_STATIC 5 +//---------------------------------------------------------------------- +// From sys/kexec.h +//---------------------------------------------------------------------- + +struct vki_kexec_segment { + void *buf; + vki_size_t bufsz; + vki_vm_paddr_t mem; + vki_vm_size_t memsz; +}; + + //---------------------------------------------------------------------- // From sys/sysctl.h (and related) //---------------------------------------------------------------------- diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 3f9272f4d1..00e228a836 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -1364,6 +1364,13 @@ struct vki_seminfo { #define VKI_MREMAP_MAYMOVE 1 #define VKI_MREMAP_FIXED 2 +//---------------------------------------------------------------------- +// Common madvise flags mman-common.h +//---------------------------------------------------------------------- + +#define VKI_MADV_GUARD_INSTALL 102 +#define VKI_MADV_GUARD_REMOVE 103 + //---------------------------------------------------------------------- // From linux-2.6.31-rc4/include/linux/futex.h //---------------------------------------------------------------------- @@ -3900,6 +3907,30 @@ struct vki_ion_custom_data { #define VKI_ION_IOC_CUSTOM \ _VKI_IOWR(VKI_ION_IOC_MAGIC, 6, struct vki_ion_custom_data) +struct vki_procmap_query { + __vki_u64 size; + __vki_u64 query_flags; /* in */ + __vki_u64 query_addr; /* in */ + __vki_u64 vma_start; /* out */ + __vki_u64 vma_end; /* out */ + __vki_u64 vma_flags; /* out */ + __vki_u64 vma_page_size; /* out */ + __vki_u64 vma_offset; /* out */ + __vki_u64 inode; /* out */ + __vki_u32 dev_major; /* out */ + __vki_u32 dev_minor; /* out */ + __vki_u32 vma_name_size; /* in/out */ + __vki_u32 build_id_size; /* in/out */ + __vki_u64 vma_name_addr; /* in */ + __vki_u64 build_id_addr; /* in */ +}; + +// linux/fs.h +#define VKI_PROCFS_IOCTL_MAGIC 'f' + +#define VKI_PROCMAP_QUERY \ + _VKI_IOWR(VKI_PROCFS_IOCTL_MAGIC, 17, struct vki_procmap_query) + //---------------------------------------------------------------------- // From include/uapi/linux/sync_file.h 6.10.3 //---------------------------------------------------------------------- @@ -5574,6 +5605,81 @@ struct vki_statmount { char str[]; /* Variable size part containing strings */ }; +//---------------------------------------------------------------------- +// From uapi/linux/fs.h +//---------------------------------------------------------------------- + +struct vki_file_attr { + __vki_u64 fa_xflags; /* xflags field value (get/set) */ + __vki_u32 fa_extsize; /* extsize field value (get/set)*/ + __vki_u32 fa_nextents; /* nextents field value (get) */ + __vki_u32 fa_projid; /* project identifier (get/set) */ + __vki_u32 fa_cowextsize; /* CoW extsize field value (get/set) */ +}; + +//---------------------------------------------------------------------- +// From uapi/linux/mount.h +//---------------------------------------------------------------------- + +#define VKI_SUBCMDMASK 0x00ff +#define VKI_SUBCMDSHIFT 8 + +#define VKI_Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */ +#define VKI_Q_QUOTAON 0x800002 /* turn quotas on */ +#define VKI_Q_QUOTAOFF 0x800003 /* turn quotas off */ +#define VKI_Q_GETFMT 0x800004 /* get quota format used on given filesystem */ +#define VKI_Q_GETINFO 0x800005 /* get information about quota files */ +#define VKI_Q_SETINFO 0x800006 /* set information about quota files */ +#define VKI_Q_GETQUOTA 0x800007 /* get user quota structure */ +#define VKI_Q_SETQUOTA 0x800008 /* set user quota structure */ +#define VKI_Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */ + +struct vki_dqblk + { + __vki_u64 dqb_bhardlimit; /* absolute limit on disk quota blocks alloc */ + __vki_u64 dqb_bsoftlimit; /* preferred limit on disk quota blocks */ + __vki_u64 dqb_curspace; /* current quota block count */ + __vki_u64 dqb_ihardlimit; /* maximum # allocated inodes */ + __vki_u64 dqb_isoftlimit; /* preferred inode limit */ + __vki_u64 dqb_curinodes; /* current # allocated inodes */ + __vki_u64 dqb_btime; /* time limit for excessive disk use */ + __vki_u64 dqb_itime; /* time limit for excessive files */ + __vki_u32 dqb_valid; /* bitmask of QIF_* constants */ + }; + + +struct vki_nextdqblk { + __vki_u64 dqb_bhardlimit; + __vki_u64 dqb_bsoftlimit; + __vki_u64 dqb_curspace; + __vki_u64 dqb_ihardlimit; + __vki_u64 dqb_isoftlimit; + __vki_u64 dqb_curinodes; + __vki_u64 dqb_btime; + __vki_u64 dqb_itime; + __vki_u32 dqb_valid; + __vki_u32 dqb_id; +}; + +struct vki_dqinfo { + __vki_u64 dqi_bgrace; + __vki_u64 dqi_igrace; + __vki_u32 dqi_flags; /* DFQ_* */ + __vki_u32 dqi_valid; +}; + +//---------------------------------------------------------------------- +// From uapi/linux/lsm.h +//---------------------------------------------------------------------- + +struct vki_lsm_ctx { + __vki_u64 id; + __vki_u64 flags; + __vki_u64 len; + __vki_u64 ctx_len; + __vki_u8 ctx[]; /* __counted_by(ctx_len); */ +}; + /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-scnums-darwin.h b/include/vki/vki-scnums-darwin.h index 3a33520780..94d4cec93e 100644 --- a/include/vki/vki-scnums-darwin.h +++ b/include/vki/vki-scnums-darwin.h @@ -141,6 +141,7 @@ // osfmk/mach/syscall_sw.h #define __NR_kernelrpc_mach_vm_allocate_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10) +#define __NR_kernelrpc_mach_vm_purgable_control_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11) #define __NR_kernelrpc_mach_vm_deallocate_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12) @@ -173,6 +174,10 @@ #define __NR_semaphore_timedwait_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(38) #define __NR_semaphore_timedwait_signal_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(39) +#if DARWIN_VERS >= DARWIN_10_14 +#define __NR_kernelrpc_mach_port_get_attributes_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(40) +#endif + #if DARWIN_VERS >= DARWIN_10_9 #define __NR_kernelrpc_mach_port_guard_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(41) #define __NR_kernelrpc_mach_port_unguard_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(42) @@ -188,6 +193,10 @@ #define __NR_task_for_pid VG_DARWIN_SYSCALL_CONSTRUCT_MACH(45) #define __NR_pid_for_task VG_DARWIN_SYSCALL_CONSTRUCT_MACH(46) +#if DARWIN_VERS >= DARWIN_13_00 +#define __NR_mach_msg2_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(47) +#endif + #if defined(VGA_x86) #define __NR_macx_swapon VG_DARWIN_SYSCALL_CONSTRUCT_MACH(48) #define __NR_macx_swapoff VG_DARWIN_SYSCALL_CONSTRUCT_MACH(49) @@ -213,6 +222,13 @@ #define __NR_host_create_mach_voucher_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(70) #endif +#if DARWIN_VERS >= DARWIN_10_15 +#define __NR_kernelrpc_mach_port_type_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(76) +#define __NR_kernelrpc_mach_port_request_notification_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(77) +#endif + +#define __NR_mach_voucher_extract_attr_recipe_trap VG_DARWIN_SYSCALL_CONSTRUCT_MACH(72) + #define __NR_mach_timebase_info VG_DARWIN_SYSCALL_CONSTRUCT_MACH(89) #define __NR_mach_wait_until VG_DARWIN_SYSCALL_CONSTRUCT_MACH(90) #define __NR_mk_timer_create VG_DARWIN_SYSCALL_CONSTRUCT_MACH(91) @@ -463,7 +479,7 @@ #define __NR_kqueue_from_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214) #define __NR_kqueue_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215) #endif -#define __NR_mkcomplex VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(216) +#define __NR_open_dprotected_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(216) #define __NR_statv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(217) #define __NR_lstatv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(218) #define __NR_fstatv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(219) @@ -782,7 +798,9 @@ #endif #define __NR_faccessat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(466) #define __NR_fstatat64 VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(470) +#define __NR_unlinkat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(472) #define __NR_readlinkat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(473) +#define __NR_mkdirat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(475) #define __NR_bsdthread_ctl VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(478) #define __NR_csrctl VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(483) #define __NR_guarded_open_dprotected_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(484) @@ -845,26 +863,47 @@ #define __NR_os_fault_with_payload VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(529) #endif /* DARWIN_VERS >= DARWIN_10_13 */ -#if DARWIN_VERS < DARWIN_10_6 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(427) -#elif DARWIN_VERS < DARWIN_10_7 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(430) -#elif DARWIN_VERS < DARWIN_10_9 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(430) -#elif DARWIN_VERS == DARWIN_10_9 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(456) -#elif DARWIN_VERS == DARWIN_10_10 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(490) -#elif DARWIN_VERS == DARWIN_10_11 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(500) -#elif DARWIN_VERS == DARWIN_10_12 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(522) -#elif DARWIN_VERS == DARWIN_10_13 -#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(530) -#else -#error unknown darwin version +#if DARWIN_VERS >= DARWIN_10_14 +#define __NR_kqueue_workloop_ctl VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(530) +#define __NR___mach_bridge_remote_time VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(531) +#endif /* DARWIN_VERS >= DARWIN_10_14 */ + +#if DARWIN_VERS >= DARWIN_10_15 +#define __NR_coalition_ledger VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(532) +#define __NR_log_data VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(533) +#define __NR_memorystatus_available_memory VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(534) +#endif + +#if DARWIN_VERS >= DARWIN_11_00 +#define __NR_objc_bp_assist_cfg_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(535) +#define __NR_shared_region_map_and_slide_2_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(536) +#define __NR_pivot_root VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(537) +#define __NR_task_inspect_for_pid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(538) +#define __NR_task_read_for_pid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(539) +#define __NR_sys_preadv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(540) +#define __NR_sys_pwritev VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(541) +#define __NR_sys_preadv_nocancel VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(542) +#define __NR_sys_pwritev_nocancel VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(543) +#define __NR_ulock_wait2 VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(544) +#define __NR_proc_info_extended_id VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(545) +#endif + +#if DARWIN_VERS >= DARWIN_12_00 +#define __NR_tracker_action VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(546) +#define __NR_debug_syscall_reject VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(547) +#endif + +#if DARWIN_VERS >= DARWIN_13_00 +#define __NR_sys_debug_syscall_reject_config VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(548) +#define __NR_graftdmg VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(549) +#define __NR_map_with_linking_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(550) +#define __NR_freadlink VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(551) +#define __NR_sys_record_system_event VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(552) +#define __NR_mkfifoat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(553) +#define __NR_mknodat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(554) +#define __NR_ungraftdmg VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(555) #endif -#define __NR_DARWIN_FAKE_SIGRETURN (1 + __NR_MAXSYSCALL) +#define __NR_darwin_fake_sigreturn VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(1000) #endif diff --git a/include/vki/vki-scnums-freebsd.h b/include/vki/vki-scnums-freebsd.h index 924434f3fc..0f7bf3963d 100644 --- a/include/vki/vki-scnums-freebsd.h +++ b/include/vki/vki-scnums-freebsd.h @@ -5,7 +5,7 @@ Copyright (C) 2000-2005 Julian Seward jseward@acm.org - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2026 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or @@ -30,19 +30,6 @@ #include "config.h" #include -// this is the syscall format used by e.g., libc functions like 'write' -// this is the one used 99.999% of the time -// the two others are only for experimental or testing use -// (but we use them in the scalar tests). -#define VG_FREEBSD_SYSCALL_STD 0 -// this is the syscall format used by 'syscall' -#define VG_FREEBSD_SYSCALL0 1 -// this is the syscall format used by '__syscall' -// it is the same as VG_FREEBSD_SYSCALL0 except that -// it ensures that 64bit argument alignment is correct -// that makes no difference for amd64, x86 not sure -#define VG_FREEBSD_SYSCALL198 2 - // From sys/syscall.h // @todo PJF ugly leading double underscores @@ -652,7 +639,12 @@ #define __NR_jail_attach_jd 597 #define __NR_jail_remove_jd 598 +#define __NR_kexec_load 599 +#define __NR_pdrfork 600 +#define __NR_pdwait 601 +#define __NR_renameat2 602 + -#define __NR_fake_sigreturn 1000 +#define __NR_freebsd_fake_sigreturn 1000 #endif /* VKI_UNISTD_FREEBSD_H */ diff --git a/include/vki/vki-scnums-mips32-linux.h b/include/vki/vki-scnums-mips32-linux.h index 539db119b1..d30cbf46c0 100644 --- a/include/vki/vki-scnums-mips32-linux.h +++ b/include/vki/vki-scnums-mips32-linux.h @@ -462,7 +462,12 @@ #define __NR_fchmodat2 (__NR_Linux + 452) #define __NR_statmount (__NR_Linux + 457) #define __NR_listmount (__NR_Linux + 458) +#define __NR_lsm_get_self_attr (__NR_Linux + 459) +#define __NR_lsm_set_self_attr (__NR_Linux + 460) +#define __NR_lsm_list_modules (__NR_Linux + 461) #define __NR_mseal (__NR_Linux + 462) +#define __NR_file_getattr (__NR_Linux + 468) +#define __NR_file_setattr (__NR_Linux + 469) /* * Offset of the last Linux o32 flavoured syscall */ diff --git a/include/vki/vki-scnums-mips64-linux.h b/include/vki/vki-scnums-mips64-linux.h index a8fb5e2a8f..0e2f341535 100644 --- a/include/vki/vki-scnums-mips64-linux.h +++ b/include/vki/vki-scnums-mips64-linux.h @@ -402,6 +402,8 @@ #define __NR_lsm_set_self_attr (__NR_Linux + 460) #define __NR_lsm_list_modules (__NR_Linux + 461) #define __NR_mseal (__NR_Linux + 462) +#define __NR_file_getattr (__NR_Linux + 468) +#define __NR_file_setattr (__NR_Linux + 469) #elif defined(VGABI_N32) @@ -800,6 +802,9 @@ #define __NR_lsm_get_self_attr (__NR_Linux + 459) #define __NR_lsm_set_self_attr (__NR_Linux + 460) #define __NR_lsm_list_modules (__NR_Linux + 461) +#define __NR_mseal (__NR_Linux + 462) +#define __NR_file_getattr (__NR_Linux + 468) +#define __NR_file_setattr (__NR_Linux + 469) #else #error unknown mips64 abi diff --git a/include/vki/vki-scnums-shared-linux.h b/include/vki/vki-scnums-shared-linux.h index 8efba61690..f022c1ff3e 100644 --- a/include/vki/vki-scnums-shared-linux.h +++ b/include/vki/vki-scnums-shared-linux.h @@ -60,6 +60,11 @@ #define __NR_fchmodat2 452 #define __NR_statmount 457 #define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 #endif diff --git a/include/vki/vki-solaris.h b/include/vki/vki-solaris.h index 8d9d687092..d6e00cdc6d 100644 --- a/include/vki/vki-solaris.h +++ b/include/vki/vki-solaris.h @@ -335,14 +335,16 @@ typedef struct vki_kcf_door_arg_s { } vki_da_u; } vki_kcf_door_arg_t; - +// https://bugs.kde.org/show_bug.cgi?id=512291 +// crypto ioctl removed from Solaris late 2025 +#if defined(HAVE_SYS_CRYPTO_IOCTL_H) #include #define VKI_CRYPTO_SUCCESS CRYPTO_SUCCESS #define VKI_CRYPTO_GET_PROVIDER_LIST CRYPTO_GET_PROVIDER_LIST #define vki_crypto_provider_id_t crypto_provider_id_t #define vki_crypto_provider_entry_t crypto_provider_entry_t #define vki_crypto_get_provider_list_t crypto_get_provider_list_t - +#endif #include #include @@ -1527,6 +1529,14 @@ struct sysv_ucontext { #define VKI_SETCONTEXT SETCONTEXT #define VKI_GETUSTACK GETUSTACK #define VKI_SETUSTACK SETUSTACK +#ifdef CLRSSONSTACK +/* New in Oracle Solaris 11.4 SRU 30 */ +#define VKI_CLRSSONSTACK CLRSSONSTACK +#endif +#ifdef SETUJMPBUF +/* New in Oracle Solaris 11.4 SRU 81 */ +#define VKI_SETUJMPBUF SETUJMPBUF +#endif #define VKI_UC_SIGMASK UC_SIGMASK #define VKI_UC_STACK UC_STACK diff --git a/include/vki/vki-x86-freebsd.h b/include/vki/vki-x86-freebsd.h index 3a092f87ba..26db5203c0 100644 --- a/include/vki/vki-x86-freebsd.h +++ b/include/vki/vki-x86-freebsd.h @@ -11,7 +11,7 @@ jseward@acm.org Copyright (C) 2009 Stanislav Sedov - Copyright (C) 2018-2021 Paul Floyd + Copyright (C) 2018-2022 Paul Floyd pjfloyd@wanadoo.fr This program is free software; you can redistribute it and/or diff --git a/massif/ms_main.c b/massif/ms_main.c index 94eca658ea..104e9a136b 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -321,13 +321,13 @@ static void init_alloc_fns(void) // DO("malloc" ); DO("__builtin_new" ); -# if VG_WORDSIZE == 4 +# if VG_WORDSIZE == 4 && !defined(VGO_darwin) DO("operator new(unsigned)" ); #else DO("operator new(unsigned long)" ); #endif DO("__builtin_vec_new" ); -# if VG_WORDSIZE == 4 +# if VG_WORDSIZE == 4 && !defined(VGO_darwin) DO("operator new[](unsigned)" ); #else DO("operator new[](unsigned long)" ); @@ -338,7 +338,7 @@ static void init_alloc_fns(void) DO("memalign" ); DO("posix_memalign" ); DO("valloc" ); -# if VG_WORDSIZE == 4 +# if VG_WORDSIZE == 4 && !defined(VGO_darwin) DO("operator new(unsigned, std::nothrow_t const&)" ); DO("operator new[](unsigned, std::nothrow_t const&)" ); DO("operator new(unsigned, std::align_val_t)" ); @@ -2177,7 +2177,7 @@ static void ms_pre_clo_init(void) VG_(details_version) (NULL); VG_(details_description) ("a heap profiler"); VG_(details_copyright_author)( - "Copyright (C) 2003-2024, and GNU GPL'd, by Nicholas Nethercote et al."); + "Copyright (C) 2003-2025, and GNU GPL'd, by Nicholas Nethercote et al."); VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 330 ); diff --git a/massif/tests/Makefile.am b/massif/tests/Makefile.am index 5992039c43..776c6c6f60 100644 --- a/massif/tests/Makefile.am +++ b/massif/tests/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/Makefile.tool-tests.am -dist_noinst_SCRIPTS = filter_stderr filter_verbose filter_new_aligned +dist_noinst_SCRIPTS = filter_stderr filter_verbose filter_new_aligned filter_ignore_fn EXTRA_DIST = \ alloc-fns-A.post.exp alloc-fns-A.stderr.exp alloc-fns-A.vgtest \ @@ -21,13 +21,13 @@ EXTRA_DIST = \ custom_alloc.post.exp custom_alloc.stderr.exp custom_alloc.vgtest \ ignored.post.exp ignored.stderr.exp ignored.vgtest \ ignoring.post.exp ignoring.stderr.exp ignoring.vgtest \ - inlinfomalloc.post.exp inlinfomalloc.stderr.exp inlinfomalloc.vgtest \ + inlinfomalloc.post.exp inlinfomalloc.vgtest \ insig.post.exp insig.stderr.exp insig.vgtest \ long-names.post.exp long-names.stderr.exp long-names.vgtest \ long-time.post.exp long-time.stderr.exp long-time.vgtest \ - malloc_usable.stderr.exp malloc_usable.vgtest \ + malloc_usable.vgtest \ mmapunmap.post.exp mmapunmap.post.exp-ppc64 \ - mmapunmap.stderr.exp mmapunmap.vgtest \ + mmapunmap.vgtest \ new-cpp.post.exp new-cpp.stderr.exp new-cpp.vgtest \ no-stack-no-heap.post.exp no-stack-no-heap.stderr.exp no-stack-no-heap.vgtest \ null.post.exp null.stderr.exp null.vgtest \ @@ -111,5 +111,6 @@ insig_CFLAGS = $(AM_CFLAGS) -Wno-unused-result long_names_CFLAGS = $(AM_CFLAGS) -Wno-unused-result malloc_usable_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_MAYBE_UNINITIALIZED@ one_CFLAGS = $(AM_CFLAGS) -Wno-unused-result -thresholds_CFLAGS = $(AM_CFLAGS) -Wno-unused-result +pages_as_heap_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ realloc_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_FREE_NONHEAP_OBJECT@ +thresholds_CFLAGS = $(AM_CFLAGS) -Wno-unused-result diff --git a/massif/tests/alloc-fns-A.post.exp b/massif/tests/alloc-fns-A.post.exp index 3fcb17db4c..5d44e96add 100644 --- a/massif/tests/alloc-fns-A.post.exp +++ b/massif/tests/alloc-fns-A.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./alloc-fns -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/alloc-fns-A.vgtest b/massif/tests/alloc-fns-A.vgtest index fcfaec5085..412e9f1f61 100644 --- a/massif/tests/alloc-fns-A.vgtest +++ b/massif/tests/alloc-fns-A.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/alloc-fns-B.post.exp b/massif/tests/alloc-fns-B.post.exp index dc5679dddc..55f7cf740d 100644 --- a/massif/tests/alloc-fns-B.post.exp +++ b/massif/tests/alloc-fns-B.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./alloc-fns -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --alloc-fn=a4 --alloc-fn=b4 --alloc-fn=b3 --alloc-fn=c4 --alloc-fn=c3 --alloc-fn=c2 --alloc-fn=d4 --alloc-fn=d3 --alloc-fn=d2 --alloc-fn=d1 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --alloc-fn=a4 --alloc-fn=b4 --alloc-fn=b3 --alloc-fn=c4 --alloc-fn=c3 --alloc-fn=c2 --alloc-fn=d4 --alloc-fn=d3 --alloc-fn=d2 --alloc-fn=d1 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/alloc-fns-B.vgtest b/massif/tests/alloc-fns-B.vgtest index 9ec545cadd..3768a2b23f 100644 --- a/massif/tests/alloc-fns-B.vgtest +++ b/massif/tests/alloc-fns-B.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --alloc-fn=a4 --alloc-fn=b4 --a vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/basic.post.exp b/massif/tests/basic.post.exp index 7ffcfb5803..4e0b08ec99 100644 --- a/massif/tests/basic.post.exp +++ b/massif/tests/basic.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./basic -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/basic.vgtest b/massif/tests/basic.vgtest index 2508ad91f0..37316cab79 100644 --- a/massif/tests/basic.vgtest +++ b/massif/tests/basic.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/basic2.post.exp b/massif/tests/basic2.post.exp index 820e7e51bc..257aaec674 100644 --- a/massif/tests/basic2.post.exp +++ b/massif/tests/basic2.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./basic -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --detailed-freq=1 --max-snapshots=10 --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --detailed-freq=1 --max-snapshots=10 --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/basic2.vgtest b/massif/tests/basic2.vgtest index 42c449b9fe..e5a40b6683 100644 --- a/massif/tests/basic2.vgtest +++ b/massif/tests/basic2.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out --detailed-freq=1 vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/big-alloc.post.exp b/massif/tests/big-alloc.post.exp index 6be3a661d0..d880ad9f24 100644 --- a/massif/tests/big-alloc.post.exp +++ b/massif/tests/big-alloc.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./big-alloc -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/big-alloc.post.exp-64bit b/massif/tests/big-alloc.post.exp-64bit index a005c1c603..783ed5d630 100644 --- a/massif/tests/big-alloc.post.exp-64bit +++ b/massif/tests/big-alloc.post.exp-64bit @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./big-alloc -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/big-alloc.post.exp-ppc64 b/massif/tests/big-alloc.post.exp-ppc64 index c33c3a8d26..e85493a5d2 100644 --- a/massif/tests/big-alloc.post.exp-ppc64 +++ b/massif/tests/big-alloc.post.exp-ppc64 @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./big-alloc -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/big-alloc.post.exp-x86-freebsd b/massif/tests/big-alloc.post.exp-x86-freebsd index 7ac5ef1f86..ad1a1ade28 100644 --- a/massif/tests/big-alloc.post.exp-x86-freebsd +++ b/massif/tests/big-alloc.post.exp-x86-freebsd @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./big-alloc -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/big-alloc.vgtest b/massif/tests/big-alloc.vgtest index 58ee5c501e..896a0f8ed4 100644 --- a/massif/tests/big-alloc.vgtest +++ b/massif/tests/big-alloc.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/bug469146.post.exp b/massif/tests/bug469146.post.exp index 2c3db3a79b..c04e97306b 100644 --- a/massif/tests/bug469146.post.exp +++ b/massif/tests/bug469146.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./bug469146 -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 --ignore-fn=call_init --ignore-fn=pool --ignore-fn=filter_function1 --ignore-fn=filter_function2(int) --ignore-fn=filter_function3 +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/bug469146.vgtest b/massif/tests/bug469146.vgtest index 86cc5b7d36..d19816ea73 100644 --- a/massif/tests/bug469146.vgtest +++ b/massif/tests/bug469146.vgtest @@ -4,5 +4,15 @@ vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-f vgopts: --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 vgopts: --ignore-fn=call_init --ignore-fn=pool vgopts: --ignore-fn=filter_function1 --ignore-fn="filter_function2(int)" --ignore-fn=filter_function3 -post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ../../tests/filter_addresses +# macOS allocations +vgopts: --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn=map_images_nolock --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInser --ignore-fn=add_class_to_loadable_list --ignore-fn=NXHashInsert --ignore-fn=class_createInstance --ignore-fn=_xpc_malloc --ignore-fn=strdup --ignore-fn=_xpc_calloc +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/culling1.stderr.exp b/massif/tests/culling1.stderr.exp index 812113d860..0f6c25bfe2 100644 --- a/massif/tests/culling1.stderr.exp +++ b/massif/tests/culling1.stderr.exp @@ -36,6 +36,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:32, hp:16, ex:16, st:0) Massif: alloc S. 2 (t:64, hp:32, ex:32, st:0) diff --git a/massif/tests/culling1.vgtest b/massif/tests/culling1.vgtest index 91f6056124..243e869b52 100644 --- a/massif/tests/culling1.vgtest +++ b/massif/tests/culling1.vgtest @@ -3,5 +3,13 @@ vgopts: -v -v --stats=yes --stacks=no --time-unit=B --heap-admin=16 --massif-out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" stderr_filter: filter_verbose cleanup: rm massif.out diff --git a/massif/tests/culling2.stderr.exp b/massif/tests/culling2.stderr.exp index 07a14e645d..611490d658 100644 --- a/massif/tests/culling2.stderr.exp +++ b/massif/tests/culling2.stderr.exp @@ -36,6 +36,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:16, hp:0, ex:16, st:0) Massif: alloc S. 2 (t:432, hp:400, ex:32, st:0) diff --git a/massif/tests/culling2.vgtest b/massif/tests/culling2.vgtest index 186a41729c..f12329aec6 100644 --- a/massif/tests/culling2.vgtest +++ b/massif/tests/culling2.vgtest @@ -3,5 +3,13 @@ vgopts: -v -v --stats=yes --stacks=no --time-unit=B --heap-admin=16 --massif-out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" stderr_filter: filter_verbose cleanup: rm massif.out diff --git a/massif/tests/custom_alloc.post.exp b/massif/tests/custom_alloc.post.exp index 1c1b014226..e66bef5887 100644 --- a/massif/tests/custom_alloc.post.exp +++ b/massif/tests/custom_alloc.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./custom_alloc -Massif arguments: --stacks=no --time-unit=B --heap-admin=16 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=16 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/custom_alloc.vgtest b/massif/tests/custom_alloc.vgtest index b55c154b7b..4757f41045 100644 --- a/massif/tests/custom_alloc.vgtest +++ b/massif/tests/custom_alloc.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=16 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/deep-A.post.exp b/massif/tests/deep-A.post.exp index 13b90882a6..34f32e878f 100644 --- a/massif/tests/deep-A.post.exp +++ b/massif/tests/deep-A.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./deep -Massif arguments: --stacks=no --time-unit=B --depth=8 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --depth=8 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/deep-A.vgtest b/massif/tests/deep-A.vgtest index 30c01ef3b4..09d8fd3e64 100644 --- a/massif/tests/deep-A.vgtest +++ b/massif/tests/deep-A.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --depth=8 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/deep-B.post.exp b/massif/tests/deep-B.post.exp index 9c6bb699c5..11dddd6c0c 100644 --- a/massif/tests/deep-B.post.exp +++ b/massif/tests/deep-B.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./deep -Massif arguments: --stacks=no --time-unit=B --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --depth=8 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --depth=8 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/deep-B.stderr.exp b/massif/tests/deep-B.stderr.exp index 526f6225ca..0df02a6cb7 100644 --- a/massif/tests/deep-B.stderr.exp +++ b/massif/tests/deep-B.stderr.exp @@ -43,6 +43,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:408, hp:400, ex:8, st:0) Massif: alloc S. 2 (t:816, hp:800, ex:16, st:0) diff --git a/massif/tests/deep-B.vgtest b/massif/tests/deep-B.vgtest index 5405fd7f58..952f71ffb8 100644 --- a/massif/tests/deep-B.vgtest +++ b/massif/tests/deep-B.vgtest @@ -3,6 +3,14 @@ vgopts: --stats=yes --stacks=no --time-unit=B --alloc-fn=a6 --alloc-fn=a7 --allo vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup stderr_filter: filter_verbose -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/deep-C.post.exp b/massif/tests/deep-C.post.exp index 723c11c23d..3ca0b6f07b 100644 --- a/massif/tests/deep-C.post.exp +++ b/massif/tests/deep-C.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./deep -Massif arguments: --stacks=no --time-unit=B --alloc-fn=a3 --alloc-fn=a4 --alloc-fn=a5 --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --depth=8 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --alloc-fn=a3 --alloc-fn=a4 --alloc-fn=a5 --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --depth=8 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/deep-C.stderr.exp b/massif/tests/deep-C.stderr.exp index 53dfc700a8..c86701ca6e 100644 --- a/massif/tests/deep-C.stderr.exp +++ b/massif/tests/deep-C.stderr.exp @@ -46,6 +46,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:408, hp:400, ex:8, st:0) Massif: alloc S. 2 (t:816, hp:800, ex:16, st:0) diff --git a/massif/tests/deep-C.vgtest b/massif/tests/deep-C.vgtest index cebcc682a7..2620a50753 100644 --- a/massif/tests/deep-C.vgtest +++ b/massif/tests/deep-C.vgtest @@ -3,6 +3,14 @@ vgopts: --stacks=no --time-unit=B --alloc-fn=a3 --alloc-fn=a4 --alloc-fn=a5 --al vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" stderr_filter: filter_verbose -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/deep-D.post.exp b/massif/tests/deep-D.post.exp index 5f639422cb..a5d205c619 100644 --- a/massif/tests/deep-D.post.exp +++ b/massif/tests/deep-D.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./deep -Massif arguments: --stacks=no --time-unit=B --alloc-fn=a1 --alloc-fn=a2 --alloc-fn=a3 --alloc-fn=a4 --alloc-fn=a5 --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --alloc-fn=main --depth=20 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --alloc-fn=a1 --alloc-fn=a2 --alloc-fn=a3 --alloc-fn=a4 --alloc-fn=a5 --alloc-fn=a6 --alloc-fn=a7 --alloc-fn=a8 --alloc-fn=a9 --alloc-fn=a10 --alloc-fn=a11 --alloc-fn=a12 --alloc-fn=main --depth=20 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/deep-D.vgtest b/massif/tests/deep-D.vgtest index 2da8ae30e1..652cc25728 100644 --- a/massif/tests/deep-D.vgtest +++ b/massif/tests/deep-D.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --alloc-fn=a1 --alloc-fn=a2 --alloc-fn=a3 --al vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ../../tests/filter_libc +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ../../tests/filter_libc | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/filter_ignore_fn b/massif/tests/filter_ignore_fn new file mode 100755 index 0000000000..a9e4fec117 --- /dev/null +++ b/massif/tests/filter_ignore_fn @@ -0,0 +1,15 @@ +#!/bin/sh + +awk '/Massif arguments/ { + gsub(/ ?unsigned int/, "uint") + gsub(/ ?unsigned long/, "ulong") + gsub(/char const/, "char_const") + gsub(/void const/, "void_const") + gsub(/header_info const/, "header_info_const") + gsub(/ objc/, "_objc") + gsub(/> >/, ">>") + gsub(/, /, ",") + gsub(/int slice/, "int_slice") + gsub(/ --ignore-fn=[^ ]*/, "") +} +{ print }' diff --git a/massif/tests/ignored.post.exp b/massif/tests/ignored.post.exp index 286e9bd7b3..77e5bc17df 100644 --- a/massif/tests/ignored.post.exp +++ b/massif/tests/ignored.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./ignored -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --ignore-fn=ignore1 --ignore-fn=ignore2 --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/ignored.vgtest b/massif/tests/ignored.vgtest index e561194f03..7a5922bb33 100644 --- a/massif/tests/ignored.vgtest +++ b/massif/tests/ignored.vgtest @@ -4,5 +4,13 @@ vgopts: --ignore-fn=ignore1 --ignore-fn=ignore2 vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/ignoring.post.exp b/massif/tests/ignoring.post.exp index 8c884a8e30..cef505e509 100644 --- a/massif/tests/ignoring.post.exp +++ b/massif/tests/ignoring.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./ignoring -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/ignoring.vgtest b/massif/tests/ignoring.vgtest index 29c03fd322..b4fb2101f6 100644 --- a/massif/tests/ignoring.vgtest +++ b/massif/tests/ignoring.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/inlinfomalloc.post.exp b/massif/tests/inlinfomalloc.post.exp index a4da734384..3b3166e1cb 100644 --- a/massif/tests/inlinfomalloc.post.exp +++ b/massif/tests/inlinfomalloc.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./inlinfomalloc -Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --threshold=0 --detailed-freq=6 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element +Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --threshold=0 --detailed-freq=6 --massif-out-file=massif.out ms_print arguments: --threshold=0 massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/inlinfomalloc.stderr.exp b/massif/tests/inlinfomalloc.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/massif/tests/inlinfomalloc.vgtest b/massif/tests/inlinfomalloc.vgtest index 9021b926e5..ca221e66a6 100644 --- a/massif/tests/inlinfomalloc.vgtest +++ b/massif/tests/inlinfomalloc.vgtest @@ -1,6 +1,14 @@ prog: inlinfomalloc vgopts: --stacks=no --heap-admin=0 --time-unit=B --threshold=0 --detailed-freq=6 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element +# macOS allocations +vgopts: --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=map_images_nolock --ignore-fn=NXCreateHashTableFromZone --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=_xpc_malloc --ignore-fn=strdup --ignore-fn=_xpc_calloc +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup stderr_filter: filter_verbose -post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/insig.post.exp b/massif/tests/insig.post.exp index 82f539638c..627dced49e 100644 --- a/massif/tests/insig.post.exp +++ b/massif/tests/insig.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./insig -Massif arguments: --stacks=no --time-unit=B --heap-admin=128 --massif-out-file=massif.out --threshold=0.99 --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=128 --massif-out-file=massif.out --threshold=0.99 --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/insig.vgtest b/massif/tests/insig.vgtest index 35ac4b1a6f..a87b5b16a3 100644 --- a/massif/tests/insig.vgtest +++ b/massif/tests/insig.vgtest @@ -4,5 +4,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=128 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/long-names.post.exp b/massif/tests/long-names.post.exp index a45a3bc497..0bd1eea931 100644 --- a/massif/tests/long-names.post.exp +++ b/massif/tests/long-names.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./long-names -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --detailed-freq=3 --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --detailed-freq=3 --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/long-names.vgtest b/massif/tests/long-names.vgtest index 7860172607..0529a2a625 100644 --- a/massif/tests/long-names.vgtest +++ b/massif/tests/long-names.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out -- vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/long-time.post.exp b/massif/tests/long-time.post.exp index f60595c391..c36e52a7fd 100644 --- a/massif/tests/long-time.post.exp +++ b/massif/tests/long-time.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./long-time -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/long-time.vgtest b/massif/tests/long-time.vgtest index 595ba779fc..d56e872002 100644 --- a/massif/tests/long-time.vgtest +++ b/massif/tests/long-time.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/malloc_usable.stderr.exp b/massif/tests/malloc_usable.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/massif/tests/mmapunmap.stderr.exp b/massif/tests/mmapunmap.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/massif/tests/mmapunmap.vgtest b/massif/tests/mmapunmap.vgtest index 6605299e9c..3d9cc791a7 100644 --- a/massif/tests/mmapunmap.vgtest +++ b/massif/tests/mmapunmap.vgtest @@ -2,5 +2,7 @@ prog: mmapunmap vgopts: --pages-as-heap=yes --threshold=30.0 -q vgopts: --stacks=no --time-unit=B --depth=8 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element -post: grep -A5 -e =peak massif.out | grep -e 'main (mmapunmap.c:16)\|(below main)' | tr -s ' ' | ../../tests/filter_addresses | ../../tests/filter_libc +# macOS 13 ignore functions +vgopts: --ignore-fn='stat$INODE64' --ignore-fn=_kernelrpc_mach_vm_map_trap +post: grep -A5 -e =peak massif.out | grep -e 'main (mmapunmap.c:16)\|(below main)' | tr -s ' ' | ../../tests/filter_addresses | ../../tests/filter_libc | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/new-cpp.post.exp b/massif/tests/new-cpp.post.exp index e23a9f59cc..93c57c2c3b 100644 --- a/massif/tests/new-cpp.post.exp +++ b/massif/tests/new-cpp.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./new-cpp -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 --ignore-fn=call_init --ignore-fn=pool --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/new-cpp.vgtest b/massif/tests/new-cpp.vgtest index 57afa50362..7dda292b47 100644 --- a/massif/tests/new-cpp.vgtest +++ b/massif/tests/new-cpp.vgtest @@ -5,5 +5,13 @@ vgopts: --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_allo vgopts: --ignore-fn=call_init --ignore-fn=pool # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/no-stack-no-heap.post.exp b/massif/tests/no-stack-no-heap.post.exp index 1f3d27ec43..b8caf841a4 100644 --- a/massif/tests/no-stack-no-heap.post.exp +++ b/massif/tests/no-stack-no-heap.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./basic -Massif arguments: --stacks=no --heap=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element +Massif arguments: --stacks=no --heap=no --time-unit=B --massif-out-file=massif.out ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/no-stack-no-heap.vgtest b/massif/tests/no-stack-no-heap.vgtest index b984fc0604..9eee9c60b6 100644 --- a/massif/tests/no-stack-no-heap.vgtest +++ b/massif/tests/no-stack-no-heap.vgtest @@ -1,5 +1,5 @@ prog: basic vgopts: --stacks=no --heap=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/null.post.exp b/massif/tests/null.post.exp index 4e4ae81017..a346a4bb98 100644 --- a/massif/tests/null.post.exp +++ b/massif/tests/null.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./null -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/null.vgtest b/massif/tests/null.vgtest index 73b440f8a1..585d1cb89a 100644 --- a/massif/tests/null.vgtest +++ b/massif/tests/null.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/one.post.exp b/massif/tests/one.post.exp index a0b1908b86..abffae8571 100644 --- a/massif/tests/one.post.exp +++ b/massif/tests/one.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./one -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/one.post.exp2 b/massif/tests/one.post.exp2 index 73edd1a7c3..0455ce5527 100644 --- a/massif/tests/one.post.exp2 +++ b/massif/tests/one.post.exp2 @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./one -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/one.vgtest b/massif/tests/one.vgtest index bb45ac52d5..486ac97fc0 100644 --- a/massif/tests/one.vgtest +++ b/massif/tests/one.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/overloaded-new.post.exp b/massif/tests/overloaded-new.post.exp index eb741e7464..7767dc7be2 100644 --- a/massif/tests/overloaded-new.post.exp +++ b/massif/tests/overloaded-new.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./overloaded-new -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 --ignore-fn=call_init --ignore-fn=pool +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/overloaded-new.post.exp-mips32 b/massif/tests/overloaded-new.post.exp-mips32 index 0812599da7..046971ba96 100644 --- a/massif/tests/overloaded-new.post.exp-mips32 +++ b/massif/tests/overloaded-new.post.exp-mips32 @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./overloaded-new -Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 --ignore-fn=call_init --ignore-fn=pool +Massif arguments: --stacks=no --time-unit=B --massif-out-file=massif.out ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/overloaded-new.vgtest b/massif/tests/overloaded-new.vgtest index 85a839c1db..2a578fc87d 100644 --- a/massif/tests/overloaded-new.vgtest +++ b/massif/tests/overloaded-new.vgtest @@ -4,5 +4,15 @@ vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook vgopts: --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 vgopts: --ignore-fn=call_init --ignore-fn=pool -post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ./filter_new_aligned +# macOS allocations +vgopts: --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn=map_images_nolock --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=_xpc_malloc +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup --ignore-fn="_xpc_calloc" +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ./filter_new_aligned | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/pages_as_heap.vgtest b/massif/tests/pages_as_heap.vgtest index 0ed73ea136..56230ea9aa 100644 --- a/massif/tests/pages_as_heap.vgtest +++ b/massif/tests/pages_as_heap.vgtest @@ -1,7 +1,7 @@ -prereq: test -e ./pages_as_heap +prereq: test -e ./pages_as_heap && ! ../../tests/os_test darwin prog: pages_as_heap vgopts: --stacks=no --time-unit=B --heap-admin=0 --pages-as-heap=yes --massif-out-file=massif.out --detailed-freq=3 vgopts: --ignore-fn=mmap # would be nice to test that pages as heap works properly using -# post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/peak.post.exp b/massif/tests/peak.post.exp index 66c2a0169c..e8c9e8f504 100644 --- a/massif/tests/peak.post.exp +++ b/massif/tests/peak.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./peak -Massif arguments: --stacks=no --time-unit=B --peak-inaccuracy=0 --heap-admin=128 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --peak-inaccuracy=0 --heap-admin=128 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/peak.vgtest b/massif/tests/peak.vgtest index 8011a44665..8164f48ed8 100644 --- a/massif/tests/peak.vgtest +++ b/massif/tests/peak.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --peak-inaccuracy=0 --heap-admin=128 --massif- vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/peak2.post.exp b/massif/tests/peak2.post.exp index 35ad85de35..cc60cf75db 100644 --- a/massif/tests/peak2.post.exp +++ b/massif/tests/peak2.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./peak -Massif arguments: --stacks=no --time-unit=B --peak-inaccuracy=10.0 --heap-admin=128 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --peak-inaccuracy=10.0 --heap-admin=128 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/peak2.stderr.exp b/massif/tests/peak2.stderr.exp index 45ea90f762..1f464e7dd8 100644 --- a/massif/tests/peak2.stderr.exp +++ b/massif/tests/peak2.stderr.exp @@ -36,6 +36,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:1728, hp:1600, ex:128, st:0) Massif: alloc S. 2 (t:1872, hp:1616, ex:256, st:0) diff --git a/massif/tests/peak2.vgtest b/massif/tests/peak2.vgtest index 890e36fe86..808fc252c1 100644 --- a/massif/tests/peak2.vgtest +++ b/massif/tests/peak2.vgtest @@ -3,6 +3,14 @@ vgopts: --stacks=no --time-unit=B -v -v --stats=yes --peak-inaccuracy=10.0 --hea vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" stderr_filter: filter_verbose -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/realloc.post.exp b/massif/tests/realloc.post.exp index ea0ff231ae..1853c43418 100644 --- a/massif/tests/realloc.post.exp +++ b/massif/tests/realloc.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./realloc -Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --threshold=0 --massif-out-file=massif.out --realloc-zero-bytes-frees=yes --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --threshold=0 --massif-out-file=massif.out --realloc-zero-bytes-frees=yes --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: --threshold=0 massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/realloc.stderr.exp b/massif/tests/realloc.stderr.exp index 19e076f517..e8088caa01 100644 --- a/massif/tests/realloc.stderr.exp +++ b/massif/tests/realloc.stderr.exp @@ -36,6 +36,41 @@ Massif: 12: add_class_to_loadable_list Massif: 13: class_createInstance Massif: 14: xpc_string_create Massif: 15: xpc_array_create +Massif: 16: _NXMapRehash(_NXMapTable*) +Massif: 17: arc4_init +Massif: 18: realizeClassWithoutSwift(objc_class*) +Massif: 19: objc_class::setHasCustomRR(bool) +Massif: 20: _objc_flush_caches +Massif: 21: remapClass(objc_class*) +Massif: 22: isEqualPrototype(void const*, void const*, void const*) +Massif: 23: TimeLogger::log(char const*) +Massif: 24: freeBuckets(NXHashTable*, int) +Massif: 25: NXHashGet +Massif: 26: call_load_methods +Massif: 27: objc_msgLookup +Massif: 28: _objc_init +Massif: 29: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int) +Massif: 30: realizeClassWithoutSwift(objc_class*, objc_class*) +Massif: 31: schedule_class_load(objc_class*) +Massif: 32: objc::SafeRanges::add(unsigned long, unsigned long) +Massif: 33: getProtocol(char const*) +Massif: 34: class_setWeakIvarLayout +Massif: 35: NXMapRemove +Massif: 36: int sliceRequiresGC(Arch32::mh_t, FileSlice) +Massif: 37: _mapStrIsEqual(_NXMapTable*, void const*, void const*) +Massif: 38: _NXMapMember(_NXMapTable*, void const*, void**) +Massif: 39: NXMapInsert +Massif: 40: objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int) +Massif: 41: object_setClass +Massif: 42: objc_msgSend_stret +Massif: 43: protocols() +Massif: 44: copySwiftV1MangledName(char const*, bool) +Massif: 45: _getObjc2ProtocolList(header_info const*, unsigned long*) +Massif: 46: _xpc_alloc +Massif: 47: _xpc_strdup +Massif: 48: _vasprintf +Massif: 49: _fetchInitializingClassList(bool) +Massif: 50: cache_t::allocateBuckets(unsigned int) Massif: startup S. 0 (t:0, hp:0, ex:0, st:0) Massif: alloc S. 1 (t:800, hp:800, ex:0, st:0) Massif: realloc S. 2 (t:800, hp:800, ex:0, st:0) diff --git a/massif/tests/realloc.vgtest b/massif/tests/realloc.vgtest index af17aa011a..45fd4296b4 100644 --- a/massif/tests/realloc.vgtest +++ b/massif/tests/realloc.vgtest @@ -4,6 +4,14 @@ vgopts: -v -v --stats=yes --stacks=no --heap-admin=0 --time-unit=B --threshold=0 vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" stderr_filter: filter_verbose -post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/thresholds_0_0.post.exp b/massif/tests/thresholds_0_0.post.exp index 96ccc00199..dd307b6083 100644 --- a/massif/tests/thresholds_0_0.post.exp +++ b/massif/tests/thresholds_0_0.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=0 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_0_0.vgtest b/massif/tests/thresholds_0_0.vgtest index a2528999a4..8c0086eef8 100644 --- a/massif/tests/thresholds_0_0.vgtest +++ b/massif/tests/thresholds_0_0.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/thresholds_0_10.post.exp b/massif/tests/thresholds_0_10.post.exp index bdab025329..b7ab56d731 100644 --- a/massif/tests/thresholds_0_10.post.exp +++ b/massif/tests/thresholds_0_10.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=10 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_0_10.vgtest b/massif/tests/thresholds_0_10.vgtest index b9e4fae426..c9b3579a42 100644 --- a/massif/tests/thresholds_0_10.vgtest +++ b/massif/tests/thresholds_0_10.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=0 --massif-out-file vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/thresholds_10_0.post.exp b/massif/tests/thresholds_10_0.post.exp index e4ae327147..9f461f0cc5 100644 --- a/massif/tests/thresholds_10_0.post.exp +++ b/massif/tests/thresholds_10_0.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=0 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_10_0.vgtest b/massif/tests/thresholds_10_0.vgtest index aaaf53cae3..569278bafa 100644 --- a/massif/tests/thresholds_10_0.vgtest +++ b/massif/tests/thresholds_10_0.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-fil vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/massif/tests/thresholds_10_10.post.exp b/massif/tests/thresholds_10_10.post.exp index 87d94a6d4f..d44615e421 100644 --- a/massif/tests/thresholds_10_10.post.exp +++ b/massif/tests/thresholds_10_10.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=10 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_10_10.vgtest b/massif/tests/thresholds_10_10.vgtest index 1c7c5d2e06..b31aa354dd 100644 --- a/massif/tests/thresholds_10_10.vgtest +++ b/massif/tests/thresholds_10_10.vgtest @@ -3,5 +3,14 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=10 --massif-out-fil vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses | ./filter_ignore_fn + cleanup: rm massif.out diff --git a/massif/tests/thresholds_5_0.post.exp b/massif/tests/thresholds_5_0.post.exp index aaf4952a64..bfc527600e 100644 --- a/massif/tests/thresholds_5_0.post.exp +++ b/massif/tests/thresholds_5_0.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=0 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_5_0.vgtest b/massif/tests/thresholds_5_0.vgtest index c588e82e36..bd984a7e7f 100644 --- a/massif/tests/thresholds_5_0.vgtest +++ b/massif/tests/thresholds_5_0.vgtest @@ -3,5 +3,14 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=0 | ../../tests/filter_addresses | ./filter_ignore_fn + cleanup: rm massif.out diff --git a/massif/tests/thresholds_5_10.post.exp b/massif/tests/thresholds_5_10.post.exp index 058d887ad9..a60e40bc99 100644 --- a/massif/tests/thresholds_5_10.post.exp +++ b/massif/tests/thresholds_5_10.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./thresholds -Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out --threshold=10 -------------------------------------------------------------------------------- diff --git a/massif/tests/thresholds_5_10.vgtest b/massif/tests/thresholds_5_10.vgtest index 0730130822..16f1bc7cd7 100644 --- a/massif/tests/thresholds_5_10.vgtest +++ b/massif/tests/thresholds_5_10.vgtest @@ -3,5 +3,14 @@ vgopts: --stacks=no --time-unit=B --heap-admin=0 --threshold=5 --massif-out-file vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out --threshold=10 | ../../tests/filter_addresses | ./filter_ignore_fn + cleanup: rm massif.out diff --git a/massif/tests/zero1.post.exp b/massif/tests/zero1.post.exp index f54a3f09c8..ddc9a40555 100644 --- a/massif/tests/zero1.post.exp +++ b/massif/tests/zero1.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./zero -Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: --threshold=0 massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/zero1.vgtest b/massif/tests/zero1.vgtest index 9a5511f28b..1753f69320 100644 --- a/massif/tests/zero1.vgtest +++ b/massif/tests/zero1.vgtest @@ -3,5 +3,14 @@ vgopts: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print --threshold=0 massif.out | ../../tests/filter_addresses | ./filter_ignore_fn + cleanup: rm massif.out diff --git a/massif/tests/zero2.post.exp b/massif/tests/zero2.post.exp index 7525a15c62..25256f7153 100644 --- a/massif/tests/zero2.post.exp +++ b/massif/tests/zero2.post.exp @@ -1,6 +1,6 @@ -------------------------------------------------------------------------------- Command: ./zero -Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn=allocBuckets(void*, unsigned int) --ignore-fn=realizeClass(objc_class*) --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create +Massif arguments: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out --alloc-fn=_xpc_malloc --alloc-fn=strdup --alloc-fn=_xpc_calloc ms_print arguments: massif.out -------------------------------------------------------------------------------- diff --git a/massif/tests/zero2.vgtest b/massif/tests/zero2.vgtest index 5e50713dac..8162b2a1d5 100644 --- a/massif/tests/zero2.vgtest +++ b/massif/tests/zero2.vgtest @@ -3,5 +3,13 @@ vgopts: --stacks=no --heap-admin=0 --time-unit=B --massif-out-file=massif.out vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element # Darwin ignore functions, for macOS 10.13 vgopts: --alloc-fn=_xpc_malloc --ignore-fn=_xpc_dictionary_insert --ignore-fn=map_images_nolock --ignore-fn="allocBuckets(void*, unsigned int)" --ignore-fn="realizeClass(objc_class*)" --ignore-fn=_NXHashRehashToCapacity --ignore-fn=NXCreateHashTableFromZone --ignore-fn=NXCreateMapTableFromZone --ignore-fn=NXHashInsert --ignore-fn=add_class_to_loadable_list --ignore-fn=class_createInstance --ignore-fn=xpc_string_create --alloc-fn=strdup --alloc-fn=_xpc_calloc --ignore-fn=xpc_array_create -post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses +# Darwin ignore functions, for macOS 10.14 +vgopts: --ignore-fn="_NXMapRehash(_NXMapTable*)" --ignore-fn=arc4_init --ignore-fn="realizeClassWithoutSwift(objc_class*)" --ignore-fn="objc_class::setHasCustomRR(bool)" --ignore-fn=_objc_flush_caches --ignore-fn="remapClass(objc_class*)" --ignore-fn="isEqualPrototype(void const*, void const*, void const*)" --ignore-fn="TimeLogger::log(char const*)" --ignore-fn="freeBuckets(NXHashTable*, int)" --ignore-fn=NXHashGet --ignore-fn=call_load_methods --ignore-fn=objc_msgLookup +# Darwin ignore functions, for macOS 10.15 +vgopts: --ignore-fn=_objc_init --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseSetPair >::grow(unsigned int)" --ignore-fn="realizeClassWithoutSwift(objc_class*, objc_class*)" --ignore-fn="schedule_class_load(objc_class*)" --ignore-fn="objc::SafeRanges::add(unsigned long, unsigned long)" --ignore-fn="getProtocol(char const*)" --ignore-fn="class_setWeakIvarLayout" --ignore-fn="NXMapRemove" --ignore-fn="int sliceRequiresGC(Arch32::mh_t, FileSlice)" --ignore-fn="_mapStrIsEqual(_NXMapTable*, void const*, void const*)" --ignore-fn="_NXMapMember(_NXMapTable*, void const*, void**)" --ignore-fn=NXMapInsert --ignore-fn="objc::DenseMap, objc::DenseMapInfo, objc::detail::DenseMapPair >::grow(unsigned int)" --ignore-fn="object_setClass" --ignore-fn="objc_msgSend_stret" --ignore-fn="protocols()" --ignore-fn="copySwiftV1MangledName(char const*, bool)" --ignore-fn="_getObjc2ProtocolList(header_info const*, unsigned long*)" +# Darwin ignore functions, for macOS 12 +vgopts: --ignore-fn=_xpc_alloc +# Darwin ignore functions, for macOS 13 +vgopts: --ignore-fn=_xpc_strdup --ignore-fn=_vasprintf --ignore-fn="_fetchInitializingClassList(bool)" --ignore-fn="cache_t::allocateBuckets(unsigned int)" +post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses | ./filter_ignore_fn cleanup: rm massif.out diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index 4eee0bd333..039940d9ee 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -473,8 +473,10 @@ as "silly arguments" and no back-trace was included. The (ab)use or realloc to also do the job of free has been poorly understood for a long time. In the C17 standard -ISO/IEC 9899:2017] the behaviour of realloc when the size argument -is zero is specified as implementation defined. Memcheck warns about +[ISO/IEC 9899:2017] the behaviour of realloc when the size argument +is zero is specified as implementation defined. The C23 standard +[ISO/IEC 9899:2024] has further tightened the requirement on the size +argument, making it undefined behaviour if it is zero. Memcheck warns about the non-portable use or realloc. For example: @@ -487,6 +489,10 @@ the non-portable use or realloc. ==77609== by 0x201978: main (realloczero.c:7) ]]> +The same check on the size argument is performed for other +realloc-style allocation functions, namely reallocarray, +reallocf and malloc_zone_realloc. + ReallocSizeZero\n" ); - emit( " realloc() with size 0\n" ); + emit( " %s() with size 0\n", fn_name ); VG_(pp_ExeContext)( VG_(get_error_where)(err) ); VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.ReallocSizeZero.ai, False); } else { - emit( "realloc() with size 0\n" ); + emit( "%s() with size 0\n", fn_name ); VG_(pp_ExeContext)( VG_(get_error_where)(err) ); VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.ReallocSizeZero.ai, False); } break; + } case Err_BadAlign: if (extra->Err.BadAlign.size) { @@ -1010,6 +1014,15 @@ void MC_(record_realloc_size_zero) ( ThreadId tid, Addr a ) { MC_Error extra; tl_assert(VG_INVALID_THREADID != tid); + /* + * We can't fill the Block as in freemismatch above. + * That's because if realloc size zero frees we literally do that + * and transform the call into a free before bothering to get the + * old MC_Chunk. + * + * See VG_(maybe_record_error) for a description of how this gets + * filled on demand. + */ extra.Err.ReallocSizeZero.ai.tag = Addr_Undescribed; VG_(maybe_record_error)( tid, Err_ReallocSizeZero, a, /*s*/NULL, &extra ); } diff --git a/memcheck/mc_leakcheck.c b/memcheck/mc_leakcheck.c index 586bff448b..b0056b65bd 100644 --- a/memcheck/mc_leakcheck.c +++ b/memcheck/mc_leakcheck.c @@ -1774,16 +1774,17 @@ static void print_results(ThreadId tid, LeakCheckParams* lcp) DBY (MC_(bytes_reachable), old_bytes_reachable), MC_(blocks_reachable), DBL (MC_(blocks_reachable), old_blocks_reachable)); - for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) + for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) { if (old_blocks_heuristically_reachable[i] > 0 || MC_(blocks_heuristically_reachable)[i] > 0) { umsg_or_xml(VG_(clo_xml) ? "" : " of which " "reachable via heuristic:\n"); break; } - for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) - if (old_blocks_heuristically_reachable[i] > 0 - || MC_(blocks_heuristically_reachable)[i] > 0) + } + for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) { + if (old_blocks_heuristically_reachable[i] > 0 + || MC_(blocks_heuristically_reachable)[i] > 0) { umsg_or_xml(VG_(clo_xml) ? " \n" " %ls\n" @@ -1799,7 +1800,9 @@ static void print_results(ThreadId tid, LeakCheckParams* lcp) MC_(blocks_heuristically_reachable)[i], DBL (MC_(blocks_heuristically_reachable)[i], old_blocks_heuristically_reachable[i])); - if (VG_(clo_xml) && MC_(bytes_reachable)) { + } + } + if (VG_(clo_xml)) { umsg_or_xml(" \n"); } umsg_or_xml(VG_(clo_xml) ? diff --git a/memcheck/mc_machine.c b/memcheck/mc_machine.c index 1d5c5c19f6..f798e0e512 100644 --- a/memcheck/mc_machine.c +++ b/memcheck/mc_machine.c @@ -173,7 +173,6 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) if (o == GOF(CTR) && sz == 8) return o; if (o == GOF(CIA) && sz == 8) return -1; - if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */ if (o == GOF(FPROUND) && sz == 1) return -1; if (o == GOF(DFPROUND) && sz == 1) return -1; if (o == GOF(C_FPCC) && sz == 1) return -1; @@ -452,7 +451,6 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) if (o == GOF(CTR) && sz == 4) return o; if (o == GOF(CIA) && sz == 4) return -1; - if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */ if (o == GOF(FPROUND) && sz == 1) return -1; if (o == GOF(DFPROUND) && sz == 1) return -1; if (o == GOF(C_FPCC) && sz == 1) return -1; @@ -646,7 +644,6 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */ if (o == GOF(DFLAG) && sz == 8) return -1; /* slot used for %CH */ if (o == GOF(RIP) && sz == 8) return -1; /* slot unused */ - if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */ if (o == GOF(TLSBASE) && sz == 8) return -1; /* slot unused */ if (o == GOF(IDFLAG) && sz == 8) return -1; /* slot used for %DH */ if (o == GOF(ACFLAG) && sz == 8) return -1; /* slot unused */ @@ -762,7 +759,6 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */ if (o == GOF(DFLAG) && sz == 4) return -1; /* slot used for %CH */ if (o == GOF(EIP) && sz == 4) return -1; /* slot unused */ - if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */ if (o == GOF(IDFLAG) && sz == 4) return -1; /* slot used for %DH */ if (o == GOF(ACFLAG) && sz == 4) return -1; /* slot unused */ if (o == GOF(CMSTART) && sz == 4) return -1; /* slot unused */ @@ -887,7 +883,6 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) if (o == GOF(CMSTART) && sz == 8) return -1; if (o == GOF(CMLEN) && sz == 8) return -1; if (o == GOF(NRADDR) && sz == 8) return -1; - if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; if (o == GOF(fpc) && sz == 4) return -1; if (o == GOF(IA) && sz == 8) return -1; if (o == (GOF(IA) + 4) && sz == 4) return -1; diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 9a14f84360..8e5a22d863 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -1664,6 +1664,18 @@ void mc_STOREVn_slow ( Addr a, SizeT nBits, ULong vbytes, Bool bigendian ) /*--- Setting permissions over address ranges. ---*/ /*------------------------------------------------------------*/ +#if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_11_00 +#if DARWIN_VERS >= DARWIN_26_00 +// The new xzm_main_malloc_zone_create makes a 25GB (0x600000000) map in memory so, no choice but to raise the limit... +# define VA_LARGE_RANGE ( 25UL * 1024 * 1024 * 1024) +# else +// Now that we parse the DSC, we might get mmap which are up to 4GB, put 2GB to be safe for now +# define VA_LARGE_RANGE ( 2UL * 1024 * 1024 * 1024) +#endif +#else +#define VA_LARGE_RANGE 256UL * 1024 * 1024 +#endif + static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits16, UWord dsm_num ) { @@ -1689,8 +1701,8 @@ static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits16, if (lenT == 0) return; - if (lenT > 256 * 1024 * 1024) { - if (VG_(clo_verbosity) > 0 && !VG_(clo_xml)) { + if ((ULong)lenT > VA_LARGE_RANGE) { + if (VG_(clo_verbosity) > 1 && !VG_(clo_xml)) { const HChar* s = "unknown???"; if (vabits16 == VA_BITS16_NOACCESS ) s = "noaccess"; if (vabits16 == VA_BITS16_UNDEFINED) s = "undefined"; @@ -1901,7 +1913,7 @@ static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits16, void MC_(make_mem_noaccess) ( Addr a, SizeT len ) { PROF_EVENT(MCPE_MAKE_MEM_NOACCESS); - DEBUG("MC_(make_mem_noaccess)(%p, %lu)\n", a, len); + DEBUG("MC_(make_mem_noaccess)(%p, %lu)\n", (void*)a, len); set_address_range_perms ( a, len, VA_BITS16_NOACCESS, SM_DIST_NOACCESS ); if (UNLIKELY( MC_(clo_mc_level) == 3 )) ocache_sarp_Clear_Origins ( a, len ); @@ -1910,14 +1922,14 @@ void MC_(make_mem_noaccess) ( Addr a, SizeT len ) static void make_mem_undefined ( Addr a, SizeT len ) { PROF_EVENT(MCPE_MAKE_MEM_UNDEFINED); - DEBUG("make_mem_undefined(%p, %lu)\n", a, len); + DEBUG("make_mem_undefined(%p, %lu)\n", (void*)a, len); set_address_range_perms ( a, len, VA_BITS16_UNDEFINED, SM_DIST_UNDEFINED ); } void MC_(make_mem_undefined_w_otag) ( Addr a, SizeT len, UInt otag ) { PROF_EVENT(MCPE_MAKE_MEM_UNDEFINED_W_OTAG); - DEBUG("MC_(make_mem_undefined)(%p, %lu)\n", a, len); + DEBUG("MC_(make_mem_undefined)(%p, %lu)\n", (void*)a, len); set_address_range_perms ( a, len, VA_BITS16_UNDEFINED, SM_DIST_UNDEFINED ); if (UNLIKELY( MC_(clo_mc_level) == 3 )) ocache_sarp_Set_Origins ( a, len, otag ); @@ -1954,7 +1966,7 @@ void mc_new_mem_w_tid_no_ECU ( Addr a, SizeT len, ThreadId tid ) void MC_(make_mem_defined) ( Addr a, SizeT len ) { PROF_EVENT(MCPE_MAKE_MEM_DEFINED); - DEBUG("MC_(make_mem_defined)(%p, %lu)\n", a, len); + DEBUG("MC_(make_mem_defined)(%p, %lu)\n", (void*)a, len); set_address_range_perms ( a, len, VA_BITS16_DEFINED, SM_DIST_DEFINED ); if (UNLIKELY( MC_(clo_mc_level) == 3 )) ocache_sarp_Clear_Origins ( a, len ); @@ -1974,7 +1986,7 @@ static void make_mem_defined_if_addressable ( Addr a, SizeT len ) { SizeT i; UChar vabits2; - DEBUG("make_mem_defined_if_addressable(%p, %llu)\n", a, (ULong)len); + DEBUG("make_mem_defined_if_addressable(%p, %llu)\n", (void*)a, (ULong)len); for (i = 0; i < len; i++) { vabits2 = get_vabits2( a+i ); if (LIKELY(VA_BITS2_NOACCESS != vabits2)) { @@ -1991,7 +2003,7 @@ static void make_mem_defined_if_noaccess ( Addr a, SizeT len ) { SizeT i; UChar vabits2; - DEBUG("make_mem_defined_if_noaccess(%p, %llu)\n", a, (ULong)len); + DEBUG("make_mem_defined_if_noaccess(%p, %llu)\n", (void*)a, (ULong)len); for (i = 0; i < len; i++) { vabits2 = get_vabits2( a+i ); if (LIKELY(VA_BITS2_NOACCESS == vabits2)) { @@ -8552,7 +8564,7 @@ static void mc_pre_clo_init(void) VG_(details_version) (NULL); VG_(details_description) ("a memory error detector"); VG_(details_copyright_author)( - "Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al."); + "Copyright (C) 2002-2026, and GNU GPL'd, by Julian Seward et al."); VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 640 ); diff --git a/memcheck/mc_malloc_wrappers.c b/memcheck/mc_malloc_wrappers.c index ae50923c49..737837dbba 100644 --- a/memcheck/mc_malloc_wrappers.c +++ b/memcheck/mc_malloc_wrappers.c @@ -782,6 +782,7 @@ static void free_mallocs_in_mempool_block (MC_Mempool* mp, VG_(HT_remove_at_Iter)(MC_(malloc_list)); die_and_free_mem(tid, mc, mp->rzB); + cmalloc_n_frees++; } } } @@ -1014,6 +1015,7 @@ void MC_(mempool_free)(Addr pool, Addr addr) die_and_free_mem ( tid, mc, mp->rzB ); if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp); + cmalloc_n_frees++; } @@ -1073,10 +1075,11 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB) MC_(record_free_error)(tid, (Addr)mc->data); VG_(free)(chunks); if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp); + cmalloc_n_frees++; return; } die_and_free_mem ( tid, mc, mp->rzB ); - + cmalloc_n_frees++; } else { /* The current chunk intersects the trim extent: remove, @@ -1088,6 +1091,7 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB) MC_(record_free_error)(tid, (Addr)mc->data); VG_(free)(chunks); if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp); + cmalloc_n_frees++; return; } @@ -1122,6 +1126,7 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB) mc->data = lo; mc->szB = (UInt) (hi - lo); VG_(HT_add_node)( mp->chunks, mc ); + cmalloc_n_frees++; } #undef EXTENT_CONTAINS diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index 656b943ace..0d4ff4513c 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -558,6 +558,7 @@ void assign ( HChar cat, MCEnv* mce, IRTemp tmp, IRExpr* expr ) { #define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) #define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) #define mkV128(_n) IRExpr_Const(IRConst_V128(_n)) +#define mkV256(_n) IRExpr_Const(IRConst_V256(_n)) #define mkexpr(_tmp) IRExpr_RdTmp((_tmp)) /* Bind the given expression to a new temporary, and return the @@ -923,6 +924,134 @@ static IRAtom* mkImproveORV256 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) vbits) ); } +/* --------- 'WithConst' functions for AND/OR. --------- */ + +/* WithConstAND(data, vatom) = data AND vatom. + The general formula for the resulting vbits of `a1 AND a2' is: + (v1 | v2) & (a1 | v1) & (a2 | v2) + If a2 is a constant, then v2 == 0 (defined), and the formula reduces to: + v1 & (a1 | v1) & a2 + == v1 & a2 +*/ + +static IRAtom* mkWithConstAND1 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I1, binop(Iop_And1, data, vatom)); +} + +static IRAtom* mkWithConstAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I8, binop(Iop_And8, data, vatom)); +} + +static IRAtom* mkWithConstAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I16, binop(Iop_And16, data, vatom)); +} + +static IRAtom* mkWithConstAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I32, binop(Iop_And32, data, vatom)); +} + +static IRAtom* mkWithConstAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I64, binop(Iop_And64, data, vatom)); +} + +static IRAtom* mkWithConstANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_V128, binop(Iop_AndV128, data, vatom)); +} + +static IRAtom* mkWithConstANDV256 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_V256, binop(Iop_AndV256, data, vatom)); +} + +/* WithConstOR(data, vatom) = ~data AND vatom. + The general formula for the resulting vbits of `a1 OR a2' is: + (v1 | v2) & (~a1 | v1) & (~a2 | v2) + If a2 is a constant, then v2 == 0 (defined), and the formula reduces to: + v1 & (~a1 | v1) & ~a2 + == v1 & ~a2 + */ + +static IRAtom* mkWithConstOR1 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I1, + binop(Iop_And1, vatom, mkU1(!data->Iex.Const.con->Ico.U1))); +} + +static IRAtom* mkWithConstOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew('V', mce, Ity_I8, + binop(Iop_And8, vatom, mkU8(~data->Iex.Const.con->Ico.U8))); +} + +static IRAtom* mkWithConstOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew( + 'V', mce, Ity_I16, + binop(Iop_And16, vatom, mkU16(~data->Iex.Const.con->Ico.U16))); +} + +static IRAtom* mkWithConstOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew( + 'V', mce, Ity_I32, + binop(Iop_And32, vatom, mkU32(~data->Iex.Const.con->Ico.U32))); +} + +static IRAtom* mkWithConstOR64 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew( + 'V', mce, Ity_I64, + binop(Iop_And64, vatom, mkU64(~data->Iex.Const.con->Ico.U64))); +} + +static IRAtom* mkWithConstORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew( + 'V', mce, Ity_V128, + binop(Iop_AndV128, vatom, mkV128(~data->Iex.Const.con->Ico.V128))); +} + +static IRAtom* mkWithConstORV256 ( MCEnv* mce, IRAtom* data, IRAtom* vatom ) +{ + tl_assert(data->tag == Iex_Const); + tl_assert(isShadowAtom(mce, vatom)); + return assignNew( + 'V', mce, Ity_V256, + binop(Iop_AndV256, vatom, mkV256(~data->Iex.Const.con->Ico.V256))); +} + /* --------- Pessimising casts. --------- */ /* The function returns an expression of type DST_TY. If any of the VBITS @@ -1733,10 +1862,8 @@ static void complainIfUndefined ( MCEnv* mce, IRAtom* atom, IRExpr *guard ) /* If the complaint is to be issued under a guard condition, AND that into the guard condition for the helper call. */ if (guard) { - IRAtom *g1 = assignNew('V', mce, Ity_I32, unop(Iop_1Uto32, di->guard)); - IRAtom *g2 = assignNew('V', mce, Ity_I32, unop(Iop_1Uto32, guard)); - IRAtom *e = assignNew('V', mce, Ity_I32, binop(Iop_And32, g1, g2)); - di->guard = assignNew('V', mce, Ity_I1, unop(Iop_32to1, e)); + di->guard = + assignNew('V', mce, Ity_I1, binop(Iop_And1, di->guard, guard)); } setHelperAnns( mce, di ); @@ -3630,6 +3757,7 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce, IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*) = NULL; IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*) = NULL; IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*) = NULL; + IRAtom* (*wconst) (MCEnv*, IRAtom*, IRAtom*) = NULL; IRAtom* vatom1 = expr2vbits( mce, atom1, HuOth ); IRAtom* vatom2 = expr2vbits( mce, atom2, HuOth ); @@ -4900,50 +5028,57 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce, return scalarShift( mce, Ity_I8, op, vatom1,vatom2, atom1,atom2 ); case Iop_AndV256: - uifu = mkUifUV256; difd = mkDifDV256; + uifu = mkUifUV256; difd = mkDifDV256; wconst = mkWithConstANDV256; and_or_ty = Ity_V256; improve = mkImproveANDV256; goto do_And_Or; case Iop_AndV128: - uifu = mkUifUV128; difd = mkDifDV128; + uifu = mkUifUV128; difd = mkDifDV128; wconst = mkWithConstANDV128; and_or_ty = Ity_V128; improve = mkImproveANDV128; goto do_And_Or; case Iop_And64: - uifu = mkUifU64; difd = mkDifD64; + uifu = mkUifU64; difd = mkDifD64; wconst = mkWithConstAND64; and_or_ty = Ity_I64; improve = mkImproveAND64; goto do_And_Or; case Iop_And32: - uifu = mkUifU32; difd = mkDifD32; + uifu = mkUifU32; difd = mkDifD32; wconst = mkWithConstAND32; and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or; case Iop_And16: - uifu = mkUifU16; difd = mkDifD16; + uifu = mkUifU16; difd = mkDifD16; wconst = mkWithConstAND16; and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or; case Iop_And8: - uifu = mkUifU8; difd = mkDifD8; + uifu = mkUifU8; difd = mkDifD8; wconst = mkWithConstAND8; and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or; case Iop_And1: - uifu = mkUifU1; difd = mkDifD1; + uifu = mkUifU1; difd = mkDifD1; wconst = mkWithConstAND1; and_or_ty = Ity_I1; improve = mkImproveAND1; goto do_And_Or; case Iop_OrV256: - uifu = mkUifUV256; difd = mkDifDV256; + uifu = mkUifUV256; difd = mkDifDV256; wconst = mkWithConstORV256; and_or_ty = Ity_V256; improve = mkImproveORV256; goto do_And_Or; case Iop_OrV128: - uifu = mkUifUV128; difd = mkDifDV128; + uifu = mkUifUV128; difd = mkDifDV128; wconst = mkWithConstORV128; and_or_ty = Ity_V128; improve = mkImproveORV128; goto do_And_Or; case Iop_Or64: - uifu = mkUifU64; difd = mkDifD64; + uifu = mkUifU64; difd = mkDifD64; wconst = mkWithConstOR64; and_or_ty = Ity_I64; improve = mkImproveOR64; goto do_And_Or; case Iop_Or32: - uifu = mkUifU32; difd = mkDifD32; + uifu = mkUifU32; difd = mkDifD32; wconst = mkWithConstOR32; and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or; case Iop_Or16: - uifu = mkUifU16; difd = mkDifD16; + uifu = mkUifU16; difd = mkDifD16; wconst = mkWithConstOR16; and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or; case Iop_Or8: - uifu = mkUifU8; difd = mkDifD8; + uifu = mkUifU8; difd = mkDifD8; wconst = mkWithConstOR8; and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or; case Iop_Or1: - uifu = mkUifU1; difd = mkDifD1; + uifu = mkUifU1; difd = mkDifD1; wconst = mkWithConstOR1; and_or_ty = Ity_I1; improve = mkImproveOR1; goto do_And_Or; do_And_Or: + /* Yield simpler IR when one of the operands is a constant */ + if (atom1->tag == Iex_Const) { + return wconst(mce, atom1, vatom2); + } + if (atom2->tag == Iex_Const) { + return wconst(mce, atom2, vatom1); + } return assignNew('V', mce, and_or_ty, difd(mce, uifu(mce, vatom1, vatom2), difd(mce, improve(mce, atom1, vatom1), diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 920f262a68..1ce689bc77 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -95,7 +95,9 @@ dist_noinst_SCRIPTS = \ filter_stanza \ filter_stanza.awk \ filter_used_supp \ - filter_stanza_and_size_t + filter_stanza_and_size_t \ + filter_malloc_zone \ + run_descr_belowsp_test noinst_SCRIPTS = \ filter_dw4 \ @@ -108,7 +110,7 @@ noinst_HEADERS = leak.h EXTRA_DIST = \ accounting.stderr.exp accounting.vgtest \ addressable.stderr.exp addressable.stdout.exp addressable.vgtest \ - atomic_incs.stderr.exp atomic_incs.vgtest \ + atomic_incs.vgtest \ atomic_incs.stdout.exp-32bit atomic_incs.stdout.exp-64bit \ atomic_incs.stdout.exp-64bit-and-128bit \ badaddrvalue.stderr.exp \ @@ -129,13 +131,13 @@ EXTRA_DIST = \ buflen_check.stderr.exp-kfail \ bug155125.stderr.exp bug155125.vgtest \ bug287260.stderr.exp bug287260.vgtest \ - bug340392.stderr.exp bug340392.vgtest \ + bug340392.vgtest \ bug445235_ada_demangle.stderr.exp bug445235_ada_demangle.vgtest \ - bug401284.stderr.exp bug401284.stdout.exp bug401284.vgtest \ + bug401284.stdout.exp bug401284.vgtest \ bug464969_d_demangle.stderr.exp bug464969_d_demangle.vgtest \ bug464969_d_demangle.stdout.exp \ - bug472219.stderr.exp bug472219.vgtest \ - bug484002.stderr.exp bug484002.stdout.exp bug484002.vgtest \ + bug472219.vgtest \ + bug484002.stdout.exp bug484002.vgtest \ calloc-overflow.stderr.exp calloc-overflow.vgtest\ cdebug_zstd.vgtest cdebug_zstd.stderr.exp \ cdebug_zlib.stderr.exp cdebug_zlib.vgtest \ @@ -150,10 +152,10 @@ EXTRA_DIST = \ clo_redzone_default.stderr.exp clo_redzone_128.stderr.exp \ close_range.vgtest close_range.stderr.exp \ close_range.stderr.exp.linux \ - cond_ld.vgtest cond_ld.stdout.exp cond_ld.stderr.exp-arm \ + cond_ld.vgtest cond_ld.stderr.exp-arm \ cond_ld.stderr.exp-64bit-non-arm \ cond_ld.stderr.exp-32bit-non-arm \ - cond_st.vgtest cond_st.stdout.exp cond_st.stderr.exp-arm \ + cond_st.vgtest cond_st.stderr.exp-arm \ cond_st.stderr.exp-64bit-non-arm \ cond_st.stderr.exp-32bit-non-arm \ leak_cpp_interior.stderr.exp leak_cpp_interior.stderr.exp-64bit leak_cpp_interior.vgtest libstdc++.supp \ @@ -161,12 +163,14 @@ EXTRA_DIST = \ leak_cpp_interior.stderr.exp-arm \ custom_alloc.stderr.exp custom_alloc.vgtest \ custom_alloc.stderr.exp-s390x-mvc \ - custom-overlap.stderr.exp custom-overlap.vgtest \ + custom-overlap.vgtest \ cxx17_aligned_new.stderr.exp cxx17_aligned_new.vgtest \ cxx17_aligned_new.stderr.exp_32 \ - cxx17_aligned_new.stdout.exp \ + darwin.supp \ duplicate_align_size_errors.stderr.exp \ duplicate_align_size_errors.stderr.exp-memalign \ + duplicate_align_size_errors.stderr.exp-darwin \ + duplicate_align_size_errors.stderr.exp-darwin2 \ duplicate_align_size_errors.vgtest \ sized_aligned_new_delete_args.stderr.exp \ sized_aligned_new_delete_args.vgtest \ @@ -202,13 +206,15 @@ EXTRA_DIST = \ new_delete_mismatch_size_supp.stderr.exp-32 \ new_delete_mismatch_size_supp.vgtest \ new_delete_mismatch_size_supp.supp \ + num_callers_1.stderr.exp num_callers_1.vgtest \ deep-backtrace.vgtest deep-backtrace.stderr.exp \ demangle.stderr.exp demangle.vgtest \ - big_debuginfo_symbol.stderr.exp big_debuginfo_symbol.vgtest \ + big_debuginfo_symbol.vgtest \ describe-block.stderr.exp describe-block.vgtest \ descr_belowsp.vgtest descr_belowsp.stderr.exp \ doublefree.stderr.exp doublefree.vgtest \ - dw4.vgtest dw4.stderr.exp dw4.stderr.exp-solaris dw4.stdout.exp \ + dw4.vgtest dw4.stderr.exp dw4.stderr.exp-solaris \ + dw4.stderr.exp-darwin \ err_disable1.vgtest err_disable1.stderr.exp \ err_disable2.vgtest err_disable2.stderr.exp \ err_disable3.vgtest err_disable3.stderr.exp \ @@ -230,16 +236,14 @@ EXTRA_DIST = \ fprw.stderr.exp-freebsd-x86 \ fwrite.stderr.exp fwrite.vgtest fwrite.stderr.exp-kfail \ gone_abrt_xml.vgtest gone_abrt_xml.stderr.exp gone_abrt_xml.stderr.exp-solaris \ - gone_abrt_xml.stderr.exp-freebsd \ - holey_buffer_too_small.vgtest holey_buffer_too_small.stdout.exp \ - holey_buffer_too_small.stderr.exp \ + gone_abrt_xml.stderr.exp-freebsd gone_abrt_xml.stderr.exp-darwin \ + holey_buffer_too_small.vgtest holey_buffer_too_small.stderr.exp \ inits.stderr.exp inits.vgtest \ inline.stderr.exp inline.stdout.exp inline.vgtest \ - inlinfo.stderr.exp inlinfo.stdout.exp inlinfo.vgtest \ - inlinfosupp.stderr.exp inlinfosupp.stdout.exp inlinfosupp.supp inlinfosupp.vgtest \ - inlinfosuppobj.stderr.exp inlinfosuppobj.stdout.exp inlinfosuppobj.supp inlinfosuppobj.vgtest \ - inltemplate.stderr.exp inltemplate.stdout.exp inltemplate.vgtest \ - inltemplate.stderr.exp-old-gcc \ + inlinfo.stderr.exp inlinfo.vgtest \ + inlinfosupp.supp inlinfosupp.vgtest \ + inlinfosuppobj.stderr.exp inlinfosuppobj.supp inlinfosuppobj.vgtest \ + inltemplate.vgtest inltemplate.stderr.exp inltemplate.stderr.exp-old-gcc \ leak-0.vgtest leak-0.stderr.exp \ leak-cases-exit-on-definite.vgtest leak-cases-exit-on-definite.stderr.exp \ leak-cases-full.vgtest leak-cases-full.stderr.exp \ @@ -262,15 +266,15 @@ EXTRA_DIST = \ leak-autofreepool-5.stderr.exp-freebsd \ leak-tree.vgtest leak-tree.stderr.exp \ leak-segv-jmp.vgtest leak-segv-jmp.stderr.exp \ - lks.vgtest lks.stdout.exp lks.supp lks.stderr.exp \ + lks.vgtest lks.supp lks.stderr.exp \ long_namespace_xml.vgtest long_namespace_xml.stdout.exp \ long_namespace_xml.stderr.exp long_namespace_xml.stderr.exp-freebsd \ - long-supps.vgtest long-supps.stderr.exp long-supps.supp \ + long-supps.vgtest long-supps.supp \ mallinfo.stderr.exp mallinfo.vgtest \ mallinfo2.stderr.exp mallinfo2.vgtest \ malloc_free_fill.vgtest \ malloc_free_fill.stderr.exp \ - malloc_usable.stderr.exp malloc_usable.vgtest \ + malloc_usable.vgtest \ malloc1.stderr.exp malloc1.vgtest \ malloc1_ks_none.stderr.exp malloc1_ks_none.vgtest \ malloc1_ks_alloc.stderr.exp malloc1_ks_alloc.vgtest \ @@ -282,17 +286,19 @@ EXTRA_DIST = \ manuel2.stderr.exp manuel2.stderr.exp64 manuel2.stdout.exp \ manuel2.vgtest \ manuel3.stderr.exp manuel3.vgtest \ - match-overrun.stderr.exp match-overrun.vgtest match-overrun.supp \ + match-overrun.vgtest match-overrun.supp \ memalign_test.stderr.exp memalign_test.vgtest \ memalign_args.vgtest memalign_args.stderr.exp \ memalign_args.stderr.exp-glibc \ memalign_args.stderr.exp-darwin \ + memalign_args.stderr.exp-darwin2 \ + memalign_args.stderr.exp-darwin3 \ memalign_args.stderr.exp-solaris \ - memccpy1.stderr.exp memccpy1.stdout.exp memccpy1.vgtest \ + memccpy1.stdout.exp memccpy1.vgtest \ memccpy2.stderr.exp memccpy2.vgtest \ memcmptest.stderr.exp \ memcmptest.stdout.exp memcmptest.vgtest \ - memmem.stderr.exp memmem.vgtest \ + memmem.vgtest \ mempool.stderr.exp mempool.vgtest \ mempool2.stderr.exp mempool2.vgtest \ metadata.stderr.exp metadata.stdout.exp metadata.vgtest \ @@ -300,24 +306,22 @@ EXTRA_DIST = \ mismatches.stderr.exp2 \ mismatches_xml.stderr.exp mismatches_xml.vgtest \ mismatches_xml.stderr.exp2 \ - mmaptest.stderr.exp mmaptest.vgtest \ - nanoleak_supp.stderr.exp nanoleak_supp.vgtest nanoleak.supp \ - nanoleak_dynsupp.stderr.exp nanoleak_dynsupp.vgtest \ - nanoleak2.stderr.exp nanoleak2.vgtest \ - new_nothrow.stderr.exp new_nothrow.vgtest \ + mmaptest.vgtest \ + nanoleak_supp.vgtest nanoleak.supp \ + nanoleak_dynsupp.vgtest \ + nanoleak2.vgtest \ + new_nothrow.vgtest \ new_override.stderr.exp new_override.stdout.exp new_override.vgtest \ - noisy_child.vgtest noisy_child.stderr.exp noisy_child.stdout.exp \ - null_socket.stderr.exp null_socket.vgtest \ - origin1-yes.vgtest origin1-yes.stdout.exp origin1-yes.stderr.exp \ + noisy_child.vgtest noisy_child.stderr.exp \ + nothing_xml.vgtest \ + null_socket.vgtest \ + origin1-yes.vgtest origin1-yes.stderr.exp \ origin1-yes.stderr.exp-freebsd \ - origin2-not-quite.vgtest origin2-not-quite.stdout.exp \ - origin2-not-quite.stderr.exp \ + origin2-not-quite.vgtest origin2-not-quite.stderr.exp \ origin2-not-quite.stderr.exp-freebsd \ - origin3-no.vgtest origin3-no.stdout.exp \ + origin3-no.vgtest origin3-no.stderr.exp \ origin3-no.stderr.exp-freebsd \ - origin3-no.stderr.exp \ - origin4-many.vgtest origin4-many.stdout.exp \ - origin4-many.stderr.exp \ + origin4-many.vgtest origin4-many.stderr.exp \ origin5-bz2.vgtest origin5-bz2.stdout.exp \ origin5-bz2.stderr.exp-glibc25-x86 \ origin5-bz2.stderr.exp-glibc25-amd64 \ @@ -328,7 +332,7 @@ EXTRA_DIST = \ origin5-bz2.stderr.exp-glibc234-s390x \ origin5-bz2.stderr.exp-glibc218-mips32 \ origin5-bz2.stderr.exp-glibc236-arm \ - origin6-fp.vgtest origin6-fp.stdout.exp \ + origin6-fp.vgtest \ origin6-fp.stderr.exp-glibc25-amd64 \ origin6-fp.stderr.exp-glibc27-ppc64 \ overlap.stderr.exp overlap.stdout.exp overlap.vgtest \ @@ -345,9 +349,9 @@ EXTRA_DIST = \ partial_load_dflt.stderr.exp64 \ partial_load_dflt.stderr.exp-ppc64 \ partial_load_dflt.stderr.expr-s390x-mvc \ - pdb-realloc.stderr.exp pdb-realloc.vgtest \ - pdb-realloc2.stderr.exp pdb-realloc2.stdout.exp pdb-realloc2.vgtest \ - pipe.stderr.exp pipe.vgtest \ + pdb-realloc.vgtest \ + pdb-realloc2.stdout.exp pdb-realloc2.vgtest \ + pipe.vgtest \ pointer-trace.vgtest \ pointer-trace.stderr.exp \ posix_memalign.stderr.exp posix_memalign.vgtest \ @@ -369,33 +373,32 @@ EXTRA_DIST = \ realloc_size_zero_yes.stderr.exp realloc_size_zero_yes.stdout.exp \ realloc_size_zero_yes.vgtest \ realloc_size_zero_again_yes.stderr.exp \ - realloc_size_zero_again_yes.stdout.exp \ realloc_size_zero_again_yes.vgtest \ realloc_size_zero_no.stderr.exp realloc_size_zero_no.stdout.exp \ realloc_size_zero_no.vgtest \ realloc_size_zero_again_no.stderr.exp \ - realloc_size_zero_again_no.stdout.exp \ realloc_size_zero_again_no.vgtest \ - realloc_size_zero_off.stderr.exp realloc_size_zero_off.stdout.exp \ + realloc_size_zero_off.stdout.exp \ realloc_size_zero_off.vgtest \ realloc_size_zero_mismatch.stderr.exp \ realloc_size_zero_mismatch.stdout.exp \ realloc_size_zero_mismatch.vgtest \ - realloc_size_zero_supp.stderr.exp realloc_size_zero_supp.stdout.exp \ + realloc_size_zero_supp.stdout.exp \ realloc_size_zero_supp.vgtest \ realloc_size_zero.supp \ - realloc1.stderr.exp realloc1.vgtest \ - realloc2.stderr.exp realloc2.vgtest \ + realloc1.vgtest \ + realloc2.vgtest \ realloc3.stderr.exp realloc3.vgtest \ recursive-merge.stderr.exp recursive-merge.vgtest \ + replaces_malloc_client_req.stdout.exp replaces_malloc_client_req.vgtest \ resvn_stack.stderr.exp resvn_stack.vgtest \ demangle-rust.vgtest demangle-rust.stderr.exp \ sbfragment.stdout.exp sbfragment.stderr.exp sbfragment.vgtest \ - sem.stderr.exp sem.vgtest \ + sem.vgtest \ sendmsg.stderr.exp sendmsg.stderr.exp-solaris sendmsg.vgtest \ sendmsg.stderr.exp-freebsd \ sh-mem.stderr.exp sh-mem.vgtest \ - sh-mem-random.stderr.exp sh-mem-random.stdout.exp64 \ + sh-mem-random.stdout.exp64 \ sh-mem-random.stdout.exp sh-mem-random.vgtest \ sigaltstack.stderr.exp sigaltstack.vgtest \ sigkill.stderr.exp sigkill.stderr.exp-darwin sigkill.stderr.exp-freebsd sigkill.stderr.exp-mips32 \ @@ -403,81 +406,81 @@ EXTRA_DIST = \ sigkill.stderr.exp-glibc-2.28 sigkill.vgtest \ signal2.stderr.exp signal2.stdout.exp signal2.vgtest \ sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \ + simple_leak_xml.vgtest simple_reachable_xml.vgtest \ sized_delete.stderr.exp sized_delete.stderr.exp-x86 sized_delete.vgtest \ static_malloc.stderr.exp static_malloc.vgtest \ - stpncpy.vgtest stpncpy.stderr.exp stpncpy.stdout.exp \ + stpncpy.vgtest stpncpy.stderr.exp \ strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp3 strchr.vgtest \ - str_tester.stderr.exp str_tester.vgtest \ + str_tester.vgtest \ supp-dir.vgtest supp-dir.stderr.exp \ supp_unknown.stderr.exp supp_unknown.vgtest supp_unknown.supp \ supp_unknown.stderr.exp-kfail \ - supp1.stderr.exp supp1.vgtest \ - supp2.stderr.exp supp2.vgtest \ + supp1.vgtest \ + supp2.vgtest \ supp.supp \ suppfree.stderr.exp suppfree.supp suppfree.vgtest \ - suppfreecollision.stderr.exp suppfreecollision.supp suppfreecollision.vgtest \ + suppfreecollision.supp suppfreecollision.vgtest \ supponlyobj.stderr.exp supponlyobj.supp supponlyobj.vgtest \ - suppsrc_lineno.stderr.exp suppsrc_lineno.stdout.exp suppsrc_lineno.vgtest \ + suppsrc_lineno.stderr.exp suppsrc_lineno.vgtest \ suppsrc_lineno.supp \ - suppsrc_sanlineno.stderr.exp suppsrc_sanlineno.stdout.exp suppsrc_sanlineno.vgtest \ + suppsrc_sanlineno.vgtest \ suppsrc_sanlineno.supp \ suppvarinfo5.stderr.exp suppvarinfo5.supp suppvarinfo5.vgtest \ - test-plo-no.vgtest test-plo-no.stdout.exp \ + test-plo-no.vgtest \ test-plo-no.stderr.exp-le64 test-plo-no.stderr.exp-le32 \ test-plo-no.stderr.exp-le32-freebsd test-plo-no.stderr.exp-le64-freebsd \ - test-plo-no.stderr.exp-le32-freebsd-clang \ - test-plo-yes.vgtest test-plo-yes.stdout.exp \ + test-plo-yes.vgtest \ test-plo-yes.stderr.exp-le64 test-plo-yes.stderr.exp-le32 \ test-plo-no.stderr.exp-s390x-mvc \ - thread_alloca.stderr.exp thread_alloca.vgtest \ + thread_alloca.vgtest \ threadname.vgtest threadname.stderr.exp \ threadname_xml.vgtest threadname_xml.stderr.exp \ trivialleak.stderr.exp trivialleak.vgtest trivialleak.stderr.exp2 \ undef_malloc_args.stderr.exp undef_malloc_args.vgtest \ - unit_libcbase.stderr.exp unit_libcbase.vgtest \ - unit_oset.stderr.exp unit_oset.stdout.exp unit_oset.vgtest \ - varinfo1.vgtest varinfo1.stdout.exp varinfo1.stderr.exp \ + unit_libcbase.vgtest \ + unit_oset.stdout.exp unit_oset.vgtest \ + varinfo1.vgtest varinfo1.stderr.exp \ varinfo1.stderr.exp-ppc64 \ varinfo1.stderr.exp-freebsd \ - varinfo2.vgtest varinfo2.stdout.exp varinfo2.stderr.exp \ + varinfo2.vgtest varinfo2.stderr.exp \ varinfo2.stderr.exp-ppc64 \ - varinfo3.vgtest varinfo3.stdout.exp varinfo3.stderr.exp \ + varinfo3.vgtest varinfo3.stderr.exp \ varinfo3.stderr.exp-ppc64 \ varinfo3.stderr.exp-freebsd \ varinfo4.vgtest varinfo4.stdout.exp varinfo4.stderr.exp \ varinfo4.stderr.exp-ppc64 \ varinfo4.stderr.exp-freebsd \ - varinfo5.vgtest varinfo5.stdout.exp varinfo5.stderr.exp \ + varinfo5.vgtest varinfo5.stderr.exp \ varinfo5.stderr.exp-ppc64 \ varinfo5.stderr.exp-freebsd \ varinfo5.stderr.exp-freebsd2 \ varinfo6.vgtest varinfo6.stdout.exp varinfo6.stderr.exp \ varinfo6.stderr.exp-ppc64 \ varinforestrict.vgtest varinforestrict.stderr.exp \ - vcpu_bz2.stdout.exp vcpu_bz2.stderr.exp vcpu_bz2.vgtest \ - vcpu_fbench.stdout.exp vcpu_fbench.stderr.exp vcpu_fbench.vgtest \ + vcpu_bz2.stdout.exp vcpu_bz2.vgtest \ + vcpu_fbench.stdout.exp vcpu_fbench.vgtest \ vcpu_fnfns.stdout.exp vcpu_fnfns.stdout.exp-glibc28-amd64 \ vcpu_fnfns.stdout.exp-darwin vcpu_fnfns.stdout.exp-solaris \ vcpu_fnfns.stdout.exp-illumos \ - vcpu_fnfns.stderr.exp vcpu_fnfns.vgtest \ - wcpncpy.stderr.exp wcpncpy.vgtest \ - wcs.vgtest wcs.stderr.exp wcs.stdout.exp \ - wcscat.vgtest wcscat.stderr.exp wcscat.stdout.exp \ - wcsncpy.vgtest wcsncpy.stderr.exp \ - wmemcmp.vgtest wmemcmp.stderr.exp \ - wrap1.vgtest wrap1.stdout.exp wrap1.stderr.exp \ - wrap2.vgtest wrap2.stdout.exp wrap2.stderr.exp \ - wrap3.vgtest wrap3.stdout.exp wrap3.stderr.exp \ - wrap4.vgtest wrap4.stdout.exp wrap4.stderr.exp \ - wrap5.vgtest wrap5.stdout.exp wrap5.stderr.exp \ - wrap6.vgtest wrap6.stdout.exp wrap6.stderr.exp \ - wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \ + vcpu_fnfns.vgtest \ + wcpncpy1.stderr.exp wcpncpy1.vgtest \ + wcs.vgtest wcs.stderr.exp \ + wcscat.vgtest wcscat.stdout.exp \ + wcsncpy.vgtest \ + wmemcmp.vgtest \ + wrap1.vgtest wrap1.stdout.exp \ + wrap2.vgtest wrap2.stdout.exp \ + wrap3.vgtest wrap3.stdout.exp \ + wrap4.vgtest wrap4.stdout.exp \ + wrap5.vgtest wrap5.stdout.exp \ + wrap6.vgtest wrap6.stdout.exp \ + wrap7.vgtest wrap7.stdout.exp \ wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \ wrap8.stdout.exp-ppc64 wrap8.stderr.exp-ppc64 \ - wrapmalloc.vgtest wrapmalloc.stdout.exp wrapmalloc.stderr.exp \ + wrapmalloc.vgtest wrapmalloc.stdout.exp \ wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \ - wrapmallocstatic.stderr.exp \ writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \ + xmas_tree_xml.vgtest xmas_tree_xml.supp \ xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc check_PROGRAMS = \ @@ -494,7 +497,7 @@ check_PROGRAMS = \ bug287260 \ bug340392 \ bug401284 \ - bug445235_ada_demangle \ + bug445235_ada_demangle \ bug464969_d_demangle \ bug472219 \ calloc-overflow \ @@ -539,6 +542,7 @@ check_PROGRAMS = \ mismatches new_override metadata \ nanoleak_supp nanoleak2 new_nothrow \ noisy_child \ + nothing \ null_socket \ origin1-yes origin2-not-quite origin3-no \ origin4-many origin5-bz2 origin6-fp \ @@ -552,11 +556,14 @@ check_PROGRAMS = \ realloc_size_zero_again \ realloc1 realloc2 realloc3 \ recursive-merge \ + replaces_malloc_client_req \ resvn_stack \ sbfragment \ sendmsg \ sh-mem sh-mem-random \ - sigaltstack signal2 sigprocmask static_malloc sigkill \ + sigaltstack signal2 sigprocmask \ + simple_leak simple_reachable \ + static_malloc sigkill \ strchr \ str_tester \ supp_unknown supp1 supp2 suppfree \ @@ -624,6 +631,9 @@ check_PROGRAMS += cxx17_aligned_new sized_aligned_new_delete_args \ sized_aligned_new_delete_misaligned1 \ sized_aligned_new_delete_misaligned2 \ sized_aligned_new_delete_misaligned3 +if HAVE_FSIZED_DEALLOCATION +check_PROGRAMS += xmas_tree +endif endif if HAVE_CLOSE_RANGE @@ -655,7 +665,7 @@ check_PROGRAMS += threadname endif if HAVE_WCPNCPY -check_PROGRAMS += wcpncpy +check_PROGRAMS += wcpncpy1 endif # are there still pre-C99 C compilers? @@ -689,19 +699,20 @@ leak_cpp_interior_SOURCES = leak_cpp_interior.cpp # Suppress various gcc warnings which are correct, but for things # we are actually testing for at runtime. -accounting_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ +accounting_CFLAGS = $(AM_CFLAGS) @FLAG_W_ALLOC_SIZE_LARGER_THAN@ badfree_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_FREE_NONHEAP_OBJECT@ -bug155125_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNUSED_RESULT@ @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ +brk2_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +bug155125_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNUSED_RESULT@ @FLAG_W_ALLOC_SIZE_LARGER_THAN@ bug472219_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ -calloc_overflow_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ +calloc_overflow_CFLAGS = ${AM_CFLAGS} @FLAG_W_ALLOC_SIZE_LARGER_THAN@ malloc_usable_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_MAYBE_UNINITIALIZED@ @FLAG_W_NO_UNINITIALIZED@ -mallinfo_CFLAGS = $(AM_CFLAGS) -Wno-deprecated-declarations +mallinfo_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_DEPRECATED_DECLARATIONS@ if VGCONF_OS_IS_SOLARIS mallinfo_LDADD = -lmalloc endif -mallinfo2_CFLAGS = $(AM_CFLAGS) -Wno-deprecated-declarations -malloc3_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ @FLAG_W_NO_ALLOC_SIZE@ -sbfragment_CFLAGS = $(AM_CFLAGS) -Wno-deprecated-declarations +mallinfo2_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_DEPRECATED_DECLARATIONS@ +malloc3_CFLAGS = $(AM_CFLAGS) @FLAG_W_ALLOC_SIZE_LARGER_THAN@ @FLAG_W_NO_ALLOC_SIZE@ +sbfragment_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_DEPRECATED_DECLARATIONS@ if VGCONF_OS_IS_SOLARIS sbfragment_LDADD = -lmalloc endif @@ -741,7 +752,7 @@ endif demangle_SOURCES = demangle.cpp demangle_rust_SOURCES = demangle-rust.c demangle_rust_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_USE_AFTER_FREE@ -dw4_CFLAGS = $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section +dw4_CFLAGS = $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section @FLAG_W_NO_DEPRECATED_DECLARATIONS@ descr_belowsp_LDADD = -lpthread err_disable3_LDADD = -lpthread @@ -812,7 +823,13 @@ origin4_many_CFLAGS = $(AM_CFLAGS) -O @FLAG_W_NO_USE_AFTER_FREE@ @FLAG_W_NO_UNIN # Apply -O so as to run in reasonable time. origin5_bz2_CFLAGS = $(AM_CFLAGS) -O -Wno-inline +if VGCONF_OS_IS_DARWIN +origin5_bz2_CFLAGS += -fno-inline +endif origin6_fp_CFLAGS = $(AM_CFLAGS) -O +if VGCONF_OS_IS_DARWIN +origin6_fp_CFLAGS += -fno-inline +endif # Don't allow GCC to inline memcpy() and strcpy(), # because then we can't intercept it @@ -874,11 +891,27 @@ wrap6_CFLAGS = $(AM_CFLAGS) -O2 # To make it a bit more realistic, have some optimisation enabled # for the varinfo tests. We still expect sane results. varinfo1_CFLAGS = $(AM_CFLAGS) -O @FLAG_W_NO_MAYBE_UNINITIALIZED@ +if VGCONF_OS_IS_DARWIN +varinfo1_CFLAGS += -fno-inline +endif varinfo2_CFLAGS = $(AM_CFLAGS) -O -Wno-shadow @FLAG_W_NO_MAYBE_UNINITIALIZED@ +if VGCONF_OS_IS_DARWIN +varinfo2_CFLAGS += -fno-inline +endif varinfo3_CFLAGS = $(AM_CFLAGS) -O @FLAG_W_NO_MAYBE_UNINITIALIZED@ +if VGCONF_OS_IS_DARWIN +varinfo3_CFLAGS += -fno-inline +endif varinfo4_CFLAGS = $(AM_CFLAGS) -O @FLAG_W_NO_MAYBE_UNINITIALIZED@ +if VGCONF_OS_IS_DARWIN +varinfo4_CFLAGS += -fno-inline +endif varinfo5_CFLAGS = $(AM_CFLAGS) -O varinfo6_CFLAGS = $(AM_CFLAGS) -O @FLAG_W_NO_MAYBE_UNINITIALIZED@ +if VGCONF_OS_IS_DARWIN +varinfo6_CFLAGS += -fno-inline +endif + # Build shared object for varinfo5 varinfo5_SOURCES = varinfo5.c @@ -950,3 +983,5 @@ endif writev1_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_STRINGOP_OVERFLOW@ @FLAG_W_NO_STRINGOP_OVERREAD@ xml1_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@ +xmas_tree_SOURCES = xmas_tree.cpp +xmas_tree_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_MISMATCHED_NEW_DELETE@ @FLAG_W_ALLOC_SIZE_LARGER_THAN@ @FLAG_FSIZED_DEALLOCATION@ diff --git a/memcheck/tests/amd64-freebsd/Makefile.am b/memcheck/tests/amd64-freebsd/Makefile.am index 378446d4cf..1eff95fce3 100644 --- a/memcheck/tests/amd64-freebsd/Makefile.am +++ b/memcheck/tests/amd64-freebsd/Makefile.am @@ -24,5 +24,5 @@ AM_CCASFLAGS += @FLAG_M64@ posix_fallocate_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ posix_fadvise_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ -reallocarray_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ +reallocarray_CFLAGS = ${AM_CFLAGS} @FLAG_W_ALLOC_SIZE_LARGER_THAN@ diff --git a/memcheck/tests/amd64-freebsd/reallocarray.c b/memcheck/tests/amd64-freebsd/reallocarray.c index ee3a94d879..5735383a3f 100644 --- a/memcheck/tests/amd64-freebsd/reallocarray.c +++ b/memcheck/tests/amd64-freebsd/reallocarray.c @@ -2,29 +2,46 @@ #include #include #include +#include #include "../../memcheck.h" int main(void) { int *pi = NULL; + int *newpi; VALGRIND_DO_LEAK_CHECK; + /* should succeed */ pi = reallocarray(pi, 10U, sizeof(int)); + assert(pi); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_ADDED_LEAK_CHECK; + /* on FreeBSD this does not free pi */ pi = reallocarray(pi, 0U, sizeof(int)); + assert(pi); + fprintf(stderr, "Added leak check, expect 1 byte still reachable\n"); VALGRIND_DO_ADDED_LEAK_CHECK; pi = reallocarray(pi, 10U, 0U); + assert(pi); free(pi); + fprintf(stderr, "Added leak check, expect all blocks freed\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; pi = NULL; pi = reallocarray(pi, 10U, sizeof(int)); + assert(pi); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_ADDED_LEAK_CHECK; errno = 0; - pi = reallocarray(pi, 1UL << 49, 1U); - assert(!pi); + /* this will fail in the malloc lib, not enough memory */ + newpi = reallocarray(pi, 1UL << 49, 1U); + assert(!newpi); assert(errno == ENOMEM); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; - pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); - assert(!pi); + /* this will fail the reallocarray precondition */ + newpi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); + assert(!newpi); assert(errno == ENOMEM); + free(pi); + fprintf(stderr, "Added leak check, expect all blocks freed\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; } diff --git a/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp b/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp index 2550709ab6..f82bb92adc 100644 --- a/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp +++ b/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp @@ -1,6 +1,7 @@ All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable LEAK SUMMARY: definitely lost: 0 (+0) bytes in 0 (+0) blocks indirectly lost: 0 (+0) bytes in 0 (+0) blocks @@ -10,13 +11,14 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -realloc() with size 0 +reallocarray() with size 0 at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:13) + by 0x........: main (reallocarray.c:19) Address 0x........ is 0 bytes inside a block of size 40 alloc'd at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:11) + by 0x........: main (reallocarray.c:14) +Added leak check, expect 1 byte still reachable LEAK SUMMARY: definitely lost: 0 (+0) bytes in 0 (+0) blocks indirectly lost: 0 (+0) bytes in 0 (+0) blocks @@ -26,15 +28,17 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -realloc() with size 0 +reallocarray() with size 0 at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:15) + by 0x........: main (reallocarray.c:23) Address 0x........ is 0 bytes inside a block of size 1 alloc'd at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:13) + by 0x........: main (reallocarray.c:19) +Added leak check, expect all blocks freed All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable LEAK SUMMARY: definitely lost: 0 (+0) bytes in 0 (+0) blocks indirectly lost: 0 (+0) bytes in 0 (+0) blocks @@ -44,8 +48,17 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+0) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all +Added leak check, expect all blocks freed All heap blocks were freed -- no leaks are possible diff --git a/memcheck/tests/amd64-freebsd/reallocf.stderr.exp b/memcheck/tests/amd64-freebsd/reallocf.stderr.exp index 4ec2f2ef01..b240c7807e 100644 --- a/memcheck/tests/amd64-freebsd/reallocf.stderr.exp +++ b/memcheck/tests/amd64-freebsd/reallocf.stderr.exp @@ -10,7 +10,7 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -realloc() with size 0 +reallocf() with size 0 at 0x........: reallocf (vg_replace_malloc.c:...) by 0x........: main (reallocf.c:12) Address 0x........ is 0 bytes inside a block of size 40 alloc'd diff --git a/memcheck/tests/amd64-freebsd/scalar_arg_check.c b/memcheck/tests/amd64-freebsd/scalar_arg_check.c index cfa6d4ea08..0a847d64f0 100644 --- a/memcheck/tests/amd64-freebsd/scalar_arg_check.c +++ b/memcheck/tests/amd64-freebsd/scalar_arg_check.c @@ -4,5 +4,6 @@ int main(void) { /* sendfile uses 7 args */ SY(SYS_sendfile, 101, 102, 103, 104, 105, 106, 107); + x0 = 0; } diff --git a/memcheck/tests/amd64-linux/Makefile.am b/memcheck/tests/amd64-linux/Makefile.am index a3b5df5a67..c7baef9a85 100644 --- a/memcheck/tests/amd64-linux/Makefile.am +++ b/memcheck/tests/amd64-linux/Makefile.am @@ -7,12 +7,10 @@ dist_noinst_SCRIPTS = \ noinst_HEADERS = scalar.h EXTRA_DIST = \ - access_below_sp_1.vgtest \ - access_below_sp_1.stderr.exp access_below_sp_1.stdout.exp \ - access_below_sp_2.vgtest \ - access_below_sp_2.stderr.exp access_below_sp_2.stdout.exp \ + access_below_sp_1.vgtest access_below_sp_1.stderr.exp \ + access_below_sp_2.vgtest access_below_sp_2.stderr.exp \ defcfaexpr.vgtest defcfaexpr.stderr.exp \ - int3-amd64.vgtest int3-amd64.stderr.exp int3-amd64.stdout.exp \ + int3-amd64.vgtest int3-amd64.stdout.exp \ scalar.stderr.exp scalar.vgtest \ reallocarray.vgtest reallocarray.stderr.exp @@ -31,6 +29,9 @@ AM_CXXFLAGS += @FLAG_M64@ AM_CCASFLAGS += @FLAG_M64@ defcfaexpr_SOURCES = defcfaexpr.S -defcfaexpr_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ -reallocarray_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@ +defcfaexpr_LDFLAGS = @LDFLAG_NO_PIE@ +reallocarray_CFLAGS = $(AM_CFLAGS) @FLAG_W_ALLOC_SIZE_LARGER_THAN@ scalar_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ + +# Avoid linker warnings +int3_amd64_LDFLAGS = @LDFLAG_NO_PIE@ diff --git a/memcheck/tests/amd64-linux/access_below_sp_1.stdout.exp b/memcheck/tests/amd64-linux/access_below_sp_1.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-linux/access_below_sp_2.stdout.exp b/memcheck/tests/amd64-linux/access_below_sp_2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-linux/int3-amd64.stderr.exp b/memcheck/tests/amd64-linux/int3-amd64.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-linux/reallocarray.c b/memcheck/tests/amd64-linux/reallocarray.c index ce63b80100..138f1da069 100644 --- a/memcheck/tests/amd64-linux/reallocarray.c +++ b/memcheck/tests/amd64-linux/reallocarray.c @@ -8,24 +8,41 @@ int main(void) { int *pi = NULL; + int *newpi; VALGRIND_DO_LEAK_CHECK; + /* should succeed */ pi = reallocarray(pi, 10U, sizeof(int)); + assert(pi); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_ADDED_LEAK_CHECK; + /* on Linux this does free pi */ pi = reallocarray(pi, 0U, sizeof(int)); + assert(!pi); + fprintf(stderr, "Added leak check, expect all blocks freed\n"); VALGRIND_DO_ADDED_LEAK_CHECK; pi = malloc(10U); + assert(pi); pi = reallocarray(pi, 10U, 0U); + assert(!pi); + fprintf(stderr, "Added leak check, expect all blocks freed\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; pi = NULL; pi = reallocarray(pi, 10U, sizeof(int)); + assert(pi); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_ADDED_LEAK_CHECK; errno = 0; - pi = reallocarray(pi, 1UL << 49, 1U); - assert(!pi); + /* this will fail in the malloc lib, not enough memory */ + newpi = reallocarray(pi, 1UL << 49, 1U); + assert(!newpi); assert(errno == ENOMEM); + fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; - pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); - assert(!pi); + /* this will fail the reallocarray precondition */ + newpi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); + assert(!newpi); assert(errno == ENOMEM); + free(pi); + fprintf(stderr, "Added leak check, expect all blocks freed\n"); VALGRIND_DO_CHANGED_LEAK_CHECK; } diff --git a/memcheck/tests/amd64-linux/reallocarray.stderr.exp b/memcheck/tests/amd64-linux/reallocarray.stderr.exp index 20a1c4e8b4..5805fc7a92 100644 --- a/memcheck/tests/amd64-linux/reallocarray.stderr.exp +++ b/memcheck/tests/amd64-linux/reallocarray.stderr.exp @@ -1,6 +1,7 @@ All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable LEAK SUMMARY: definitely lost: 0 (+0) bytes in 0 (+0) blocks indirectly lost: 0 (+0) bytes in 0 (+0) blocks @@ -10,24 +11,27 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -realloc() with size 0 +reallocarray() with size 0 at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:14) + by 0x........: main (reallocarray.c:19) Address 0x........ is 0 bytes inside a block of size 40 alloc'd at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:12) + by 0x........: main (reallocarray.c:14) +Added leak check, expect all blocks freed All heap blocks were freed -- no leaks are possible -realloc() with size 0 +reallocarray() with size 0 at 0x........: reallocarray (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:17) + by 0x........: main (reallocarray.c:25) Address 0x........ is 0 bytes inside a block of size 10 alloc'd at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (reallocarray.c:16) + by 0x........: main (reallocarray.c:23) +Added leak check, expect all blocks freed All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable LEAK SUMMARY: definitely lost: 0 (+0) bytes in 0 (+0) blocks indirectly lost: 0 (+0) bytes in 0 (+0) blocks @@ -37,8 +41,17 @@ LEAK SUMMARY: Reachable blocks (those to which a pointer was found) are not shown. To see them, rerun with: --leak-check=full --show-leak-kinds=all -All heap blocks were freed -- no leaks are possible +Added leak check, expect 40 bytes still reachable +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+0) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all +Added leak check, expect all blocks freed All heap blocks were freed -- no leaks are possible diff --git a/memcheck/tests/amd64-solaris/Makefile.am b/memcheck/tests/amd64-solaris/Makefile.am index 940706e22b..ec6863dbec 100644 --- a/memcheck/tests/amd64-solaris/Makefile.am +++ b/memcheck/tests/amd64-solaris/Makefile.am @@ -6,11 +6,11 @@ dist_noinst_SCRIPTS = filter_stderr EXTRA_DIST = \ context_fpu.stderr.exp context_fpu.stdout.exp context_fpu.vgtest \ context_gpr.stderr.exp context_gpr.stdout.exp context_gpr.vgtest \ - context_rflags.stderr.exp context_rflags.stdout.exp context_rflags.vgtest \ - context_rflags2.stderr.exp context_rflags2.stdout.exp context_rflags2.vgtest \ + context_rflags.stdout.exp context_rflags.vgtest \ + context_rflags2.stderr.exp context_rflags2.vgtest \ context_sse.stderr.exp context_sse.stdout.exp context_sse.vgtest \ - ldsoexec.stderr.exp ldsoexec.vgtest \ - scalar.stderr.exp scalar.stdout.exp scalar.vgtest + ldsoexec.vgtest \ + scalar.stderr.exp scalar.vgtest check_PROGRAMS = \ context_fpu \ diff --git a/memcheck/tests/amd64-solaris/context_rflags.stderr.exp b/memcheck/tests/amd64-solaris/context_rflags.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-solaris/context_rflags2.stdout.exp b/memcheck/tests/amd64-solaris/context_rflags2.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-solaris/ldsoexec.stderr.exp b/memcheck/tests/amd64-solaris/ldsoexec.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64-solaris/scalar.stdout.exp b/memcheck/tests/amd64-solaris/scalar.stdout.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64/Makefile.am b/memcheck/tests/amd64/Makefile.am index 98f3f78fa1..91cfa2df5d 100644 --- a/memcheck/tests/amd64/Makefile.am +++ b/memcheck/tests/amd64/Makefile.am @@ -1,53 +1,47 @@ include $(top_srcdir)/Makefile.tool-tests.am -dist_noinst_SCRIPTS = filter_stderr +dist_noinst_SCRIPTS = filter_stderr filter_malloc_zone filter_pcmpgt INSN_TESTS = insn_basic insn_mmx insn_sse insn_sse2 insn_fpu EXTRA_DIST = \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ $(addsuffix .stdout.exp,$(INSN_TESTS)) \ $(addsuffix .vgtest,$(INSN_TESTS)) \ - bt_everything.stderr.exp bt_everything.stdout.exp \ - bt_everything.vgtest \ - bug132146.vgtest bug132146.stderr.exp bug132146.stdout.exp \ - bug279698.vgtest bug279698.stderr.exp bug279698.stdout.exp \ + bt_everything.stdout.exp bt_everything.vgtest \ + bug132146.vgtest bug132146.stdout.exp \ + bug279698.vgtest bug279698.stdout.exp \ + bug406674.vgtest \ bug492210_1.vgtest bug492210_1.stderr.exp \ - bug492210_2.vgtest bug492210_2.stderr.exp \ - fxsave-amd64.vgtest fxsave-amd64.stdout.exp fxsave-amd64.stderr.exp \ + bug492210_2.vgtest \ + fxsave-amd64.vgtest fxsave-amd64.stdout.exp \ insn-bsfl.vgtest insn-bsfl.stdout.exp insn-bsfl.stderr.exp \ insn-pcmpistri.vgtest insn-pcmpistri.stdout.exp insn-pcmpistri.stderr.exp \ insn-pmovmskb.vgtest insn-pmovmskb.stdout.exp insn-pmovmskb.stderr.exp \ insn-pmovmskb.stderr.exp-clang \ - more_x87_fp.stderr.exp more_x87_fp.stdout.exp more_x87_fp.vgtest \ + more_x87_fp.stdout.exp more_x87_fp.vgtest \ pcmpgt.stderr.exp pcmpgt.vgtest \ - rh2257546_128.vgtest \ - rh2257546_128.stderr.exp rh2257546_128.stdout.exp \ - rh2257546_256.vgtest \ - rh2257546_256.stderr.exp rh2257546_256.stdout.exp \ + rh2257546_128.vgtest rh2257546_128.stdout.exp \ + rh2257546_256.vgtest rh2257546_256.stdout.exp \ sh-mem-vec128-plo-no.vgtest \ sh-mem-vec128-plo-no.stderr.exp \ - sh-mem-vec128-plo-no.stdout.exp \ sh-mem-vec128-plo-yes.vgtest \ sh-mem-vec128-plo-yes.stderr.exp \ - sh-mem-vec128-plo-yes.stdout.exp \ sh-mem-vec256-plo-no.vgtest \ sh-mem-vec256-plo-no.stderr.exp \ - sh-mem-vec256-plo-no.stdout.exp \ sh-mem-vec256-plo-yes.vgtest \ sh-mem-vec256-plo-yes.stderr.exp \ - sh-mem-vec256-plo-yes.stdout.exp \ - shr_edx.stderr.exp shr_edx.stdout.exp shr_edx.vgtest \ - sse_memory.stderr.exp sse_memory.stdout.exp sse_memory.vgtest \ + shr_edx.stdout.exp shr_edx.vgtest \ + sse_memory.stdout.exp sse_memory.vgtest \ xor-undef-amd64.stderr.exp xor-undef-amd64.stdout.exp \ xor-undef-amd64.stderr.exp-freebsd xor-undef-amd64.vgtest \ - xsave-avx.vgtest xsave-avx.stdout.exp xsave-avx.stderr.exp + xsave-avx.vgtest xsave-avx.stderr.exp check_PROGRAMS = \ bt_everything \ bug132146 \ bug279698 \ + bug406674 \ fxsave-amd64 \ insn-bsfl \ insn-pmovmskb \ @@ -65,8 +59,7 @@ if HAVE_ASM_CONSTRAINT_P endif # clang 3.5.0 barfs about -mfancy-math-387 if !COMPILER_IS_CLANG - check_PROGRAMS += \ - more_x87_fp + check_PROGRAMS += more_x87_fp endif # initially this was a "not clang" test @@ -81,11 +74,14 @@ AM_CFLAGS += @FLAG_M64@ AM_CXXFLAGS += @FLAG_M64@ AM_CCASFLAGS += @FLAG_M64@ -bug492210_CFLAGS = ${AM_CFLAGS} @FLAG_NO_PIE@ @FLAG_W_NO_UNINITIALIZED@ -fxsave_amd64_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ +bug406674_SOURCES = bug406674.cpp +bug492210_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_UNINITIALIZED@ +bug492210_LDFLAGS = @LDFLAG_NO_PIE@ +fxsave_amd64_LDFLAGS = @LDFLAG_NO_PIE@ insn_pcmpistri_CFLAGS = $(AM_CFLAGS) more_x87_fp_CFLAGS = $(AM_CFLAGS) -O -ffast-math -mfpmath=387 \ -mfancy-math-387 more_x87_fp_LDADD = -lm pcmpgt_SOURCES = pcmpgt.cpp -shr_edx_CFLAGS = $(AM_CFLAGS) @FLAG_NO_PIE@ @FLAG_W_NO_UNINITIALIZED@ +shr_edx_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ +shr_edx_LDFLAGS = @LDFLAG_NO_PIE@ diff --git a/memcheck/tests/amd64/bt_everything.stderr.exp b/memcheck/tests/amd64/bt_everything.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64/bug132146.stderr.exp b/memcheck/tests/amd64/bug132146.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64/bug279698.stderr.exp b/memcheck/tests/amd64/bug279698.stderr.exp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/memcheck/tests/amd64/bug406674.cpp b/memcheck/tests/amd64/bug406674.cpp new file mode 100644 index 0000000000..7157c722f9 --- /dev/null +++ b/memcheck/tests/amd64/bug406674.cpp @@ -0,0 +1,84 @@ +// Reproducer for https://bugs.kde.org/show_bug.cgi?id=406674 +// +// BACKGROUND +// ---------- +// Valgrind's memcheck has a false positive triggered by the x86-64 sequence: +// +// shlb $0x4, %al ; 8-bit left shift +// je