You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
1
|
2
|
3
(1) |
4
(1) |
5
|
6
(1) |
7
|
|
8
|
9
(1) |
10
(4) |
11
(3) |
12
(6) |
13
(13) |
14
(1) |
|
15
(1) |
16
(3) |
17
|
18
(1) |
19
(3) |
20
(7) |
21
(5) |
|
22
|
23
(1) |
24
|
25
(3) |
26
|
27
(3) |
28
|
|
29
(1) |
30
(1) |
31
(5) |
|
|
|
|
|
From: Roland M. <rol...@nr...> - 2017-01-12 12:37:11
|
On Thu, Jan 12, 2017 at 1:31 PM, Petar Jovanovic <mip...@gm...> wrote: > On Wed, Jan 4, 2017 at 3:21 PM, Philippe Waroquiers > <phi...@sk...> wrote: >> No sign of any tilegx user or developer activity since something like >> one year. >> No reply received for question in >> https://sourceforge.net/p/valgrind/mailman/message/35566192/ >> >> Is there any tilegx user or developer still active ? >> Should we consider this platform as dead ? >> > I have exchanged a few emails with Tilera/Mellanox compiler enigneers, > and they say they cannot take care of TileGx port in Valgrind for the > time being. Is there any emulator or other way we can use to test changes ? I don't like seeing such a port just disappear... ---- Bye, Roland -- __ . . __ (o.\ \/ /.o) rol...@nr... \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer /O /==\ O\ TEL +49 641 3992797 (;O/ \/ \O;) |
|
From: Petar J. <mip...@gm...> - 2017-01-12 12:32:04
|
On Wed, Jan 4, 2017 at 3:21 PM, Philippe Waroquiers <phi...@sk...> wrote: > No sign of any tilegx user or developer activity since something like > one year. > No reply received for question in > https://sourceforge.net/p/valgrind/mailman/message/35566192/ > > Is there any tilegx user or developer still active ? > Should we consider this platform as dead ? > I have exchanged a few emails with Tilera/Mellanox compiler enigneers, and they say they cannot take care of TileGx port in Valgrind for the time being. Petar |
|
From: <sv...@va...> - 2017-01-12 11:28:30
|
Author: iraisr
Date: Thu Jan 12 11:28:20 2017
New Revision: 16200
Log:
Fix a bug when --log-file output isn't split when a program forks.
Patch loosely based on idea by Timur Iskhodzhanov <tim...@go...>.
Fixes BZ#162848
Modified:
trunk/NEWS
trunk/coregrind/m_coredump/coredump-elf.c
trunk/coregrind/m_coredump/coredump-solaris.c
trunk/coregrind/m_libcprint.c
trunk/coregrind/m_main.c
trunk/coregrind/m_options.c
trunk/coregrind/m_syswrap/syswrap-generic.c
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/coregrind/m_syswrap/syswrap-solaris.c
trunk/coregrind/pub_core_libcprint.h
trunk/coregrind/pub_core_options.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Jan 12 11:28:20 2017
@@ -81,6 +81,7 @@
https://bugs.kde.org/show_bug.cgi?id=XXXXXX
where XXXXXX is the bug number as listed below.
+162848 --log-file output isn't split when a program forks
342040 Valgrind mishandles clone with CLONE_VFORK | CLONE_VM that clones
to a different stack.
348616 Wine/valgrind: noted but unhandled ioctl 0x5390 [..] (DVD_READ_STRUCT)
Modified: trunk/coregrind/m_coredump/coredump-elf.c
==============================================================================
--- trunk/coregrind/m_coredump/coredump-elf.c (original)
+++ trunk/coregrind/m_coredump/coredump-elf.c Thu Jan 12 11:28:20 2017
@@ -597,10 +597,10 @@
Addr *seg_starts;
Int n_seg_starts;
- if (VG_(clo_log_fname_expanded) != NULL) {
+ if (VG_(clo_log_fname_unexpanded) != NULL) {
coreext = ".core";
basename = VG_(expand_file_name)("--log-file",
- VG_(clo_log_fname_expanded));
+ VG_(clo_log_fname_unexpanded));
}
vg_assert(coreext);
Modified: trunk/coregrind/m_coredump/coredump-solaris.c
==============================================================================
--- trunk/coregrind/m_coredump/coredump-solaris.c (original)
+++ trunk/coregrind/m_coredump/coredump-solaris.c Thu Jan 12 11:28:20 2017
@@ -866,10 +866,10 @@
const HChar *coreext = "";
Int core_fd;
- if (VG_(clo_log_fname_expanded) != NULL) {
+ if (VG_(clo_log_fname_unexpanded) != NULL) {
coreext = ".core";
basename = VG_(expand_file_name)("--log-file",
- VG_(clo_log_fname_expanded));
+ VG_(clo_log_fname_unexpanded));
}
vg_assert(coreext != NULL);
Modified: trunk/coregrind/m_libcprint.c
==============================================================================
--- trunk/coregrind/m_libcprint.c (original)
+++ trunk/coregrind/m_libcprint.c Thu Jan 12 11:28:20 2017
@@ -31,6 +31,7 @@
#include "pub_core_basics.h"
#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
#include "pub_core_debuglog.h"
#include "pub_core_gdbserver.h" // VG_(gdb_printf)
#include "pub_core_libcbase.h"
@@ -39,9 +40,275 @@
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h" // VG_(getpid)(), VG_(read_millisecond_timer()
#include "pub_core_mallocfree.h" // VG_(malloc)
+#include "pub_core_machine.h" // VG_(machine_get_VexArchInfo)
#include "pub_core_options.h"
#include "pub_core_clreq.h" // For RUNNING_ON_VALGRIND
+#include "pub_core_clientstate.h"
+#include "pub_core_syscall.h" // VG_(strerror)
+#include "pub_core_tooliface.h" // VG_(details)
+
+
+/*====================================================================*/
+/*=== Printing the preamble ===*/
+/*====================================================================*/
+
+// Print the argument, escaping any chars that require it.
+static void umsg_arg(const HChar *arg)
+{
+ SizeT len = VG_(strlen)(arg);
+ const HChar *special = " \\<>";
+ for (UInt i = 0; i < len; i++) {
+ if (VG_(strchr)(special, arg[i])) {
+ VG_(umsg)("\\"); // escape with a backslash if necessary
+ }
+ VG_(umsg)("%c", arg[i]);
+ }
+}
+// Send output to the XML-stream and escape any XML meta-characters.
+static void xml_arg(const HChar *arg)
+{
+ VG_(printf_xml)("%pS", arg);
+}
+
+// Write the name and value of log file qualifiers to the xml file.
+// We can safely assume here that the format string is well-formed.
+// It has been checked earlier in VG_(expand_file_name) when processing
+// command line options.
+static void print_file_vars(const HChar *format)
+{
+ UInt i = 0;
+
+ while (format[i]) {
+ if (format[i] == '%') {
+ // We saw a '%'. What's next...
+ i++;
+ if ('q' == format[i]) {
+ i++;
+ if ('{' == format[i]) {
+ // Get the env var name, print its contents.
+ UInt begin_qualname = ++i;
+ while (True) {
+ if ('}' == format[i]) {
+ UInt qualname_len = i - begin_qualname;
+ HChar qualname[qualname_len + 1];
+ VG_(strncpy)(qualname, format + begin_qualname,
+ qualname_len);
+ qualname[qualname_len] = '\0';
+ HChar *qual = VG_(getenv)(qualname);
+ i++;
+ VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
+ "<value>%pS</value> </logfilequalifier>\n",
+ qualname, qual);
+ break;
+ }
+ i++;
+ }
+ }
+ }
+ } else {
+ i++;
+ }
+ }
+}
+
+/* Ok, the logging sink is running now. Print a suitable preamble.
+ If logging to file or a socket, write details of parent PID and
+ command line args, to help people trying to interpret the
+ results of a run which encompasses multiple processes. */
+void VG_(print_preamble)(Bool logging_to_fd)
+{
+ const HChar *xpre = VG_(clo_xml) ? " <line>" : "";
+ const HChar *xpost = VG_(clo_xml) ? "</line>" : "";
+ UInt (*umsg_or_xml)( const HChar *, ... )
+ = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
+ void (*umsg_or_xml_arg)( const HChar *) = VG_(clo_xml) ? xml_arg : umsg_arg;
+
+ vg_assert( VG_(args_for_client) );
+ vg_assert( VG_(args_for_valgrind) );
+ vg_assert( VG_(clo_toolname) );
+
+ if (VG_(clo_xml)) {
+ VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<valgrindoutput>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
+ VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", VG_(clo_toolname));
+ VG_(printf_xml)("\n");
+ }
+
+ if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("<preamble>\n");
+
+ /* Tool details */
+ umsg_or_xml(VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
+ xpre,
+ VG_(details).name,
+ NULL == VG_(details).version ? "" : "-",
+ NULL == VG_(details).version ? "" : VG_(details).version,
+ VG_(details).description,
+ xpost);
+
+ if (VG_(strlen)(VG_(clo_toolname)) >= 4 &&
+ VG_STREQN(4, VG_(clo_toolname), "exp-")) {
+ umsg_or_xml("%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
+ xpre, xpost);
+ }
+
+ umsg_or_xml(VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
+ xpre, VG_(details).copyright_author, xpost);
+
+ /* Core details */
+ umsg_or_xml(
+ "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
+ xpre, VERSION, xpost);
+
+ // Print the command line. At one point we wrapped at 80 chars and
+ // printed a '\' as a line joiner, but that makes it hard to cut and
+ // paste the command line (because of the "==pid==" prefixes), so we now
+ // favour utility and simplicity over aesthetics.
+ umsg_or_xml("%sCommand: ", xpre);
+ umsg_or_xml_arg(VG_(args_the_exename));
+
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client)); i++) {
+ HChar *s = *(HChar **)VG_(indexXA)( VG_(args_for_client), i);
+ umsg_or_xml(" ");
+ umsg_or_xml_arg(s);
+ }
+ umsg_or_xml("%s\n", xpost);
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("</preamble>\n");
+ }
+
+ // Print the parent PID, and other stuff, if necessary.
+ if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
+ VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
+ } else if (VG_(clo_xml)) {
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
+ VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
+ VG_(printf_xml)("<tool>%pS</tool>\n", VG_(clo_toolname));
+ if (VG_(clo_xml_fname_unexpanded) != NULL)
+ print_file_vars(VG_(clo_xml_fname_unexpanded));
+ if (VG_(clo_xml_user_comment)) {
+ /* Note: the user comment itself is XML and is therefore to
+ be passed through verbatim (%s) rather than escaped (%pS). */
+ VG_(printf_xml)("<usercomment>%s</usercomment>\n",
+ VG_(clo_xml_user_comment));
+ }
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<args>\n");
+
+ VG_(printf_xml)(" <vargv>\n");
+ if (VG_(name_of_launcher))
+ VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(name_of_launcher));
+ else
+ VG_(printf_xml)(" <exe>%pS</exe>\n", "(launcher name unknown)");
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
+ VG_(printf_xml)(
+ " <arg>%pS</arg>\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
+ }
+ VG_(printf_xml)(" </vargv>\n");
+
+ VG_(printf_xml)(" <argv>\n");
+ VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(args_the_exename));
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
+ VG_(printf_xml)(
+ " <arg>%pS</arg>\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_client), i));
+ }
+ VG_(printf_xml)(" </argv>\n");
+
+ VG_(printf_xml)("</args>\n");
+ }
+
+ // Last thing in the preamble is a blank line.
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
+ else if (VG_(clo_verbosity) > 0)
+ VG_(umsg)("\n");
+
+ if (VG_(clo_verbosity) > 1) {
+# if defined(VGO_linux)
+ SysRes fd;
+# endif
+ VexArch vex_arch;
+ VexArchInfo vex_archinfo;
+ if (!logging_to_fd)
+ VG_(message)(Vg_DebugMsg, "\n");
+ VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
+ VG_(message)(Vg_DebugMsg,
+ " %s\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
+ }
+
+# if defined(VGO_linux)
+ VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
+ fd = VG_(open)("/proc/version", VKI_O_RDONLY, 0);
+ if (sr_isError(fd)) {
+ VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
+ } else {
+ const SizeT bufsiz = 255;
+ HChar version_buf[bufsiz+1];
+ VG_(message)(Vg_DebugMsg, " ");
+ Int n, fdno = sr_Res(fd);
+ do {
+ n = VG_(read)(fdno, version_buf, bufsiz);
+ if (n < 0) {
+ VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
+ break;
+ }
+ version_buf[n] = '\0';
+ VG_(message)(Vg_DebugMsg, "%s", version_buf);
+ } while (n == bufsiz);
+ VG_(message)(Vg_DebugMsg, "\n");
+ VG_(close)(fdno);
+ }
+# elif defined(VGO_darwin)
+ VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
+ /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
+ however that syscall is OS X 10.10+ only. */
+ Int mib[] = {CTL_KERN, KERN_VERSION};
+ SizeT len;
+ VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
+ HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
+ VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
+ VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
+ VG_(free)( kernelVersion );
+# elif defined(VGO_solaris)
+ /* There is no /proc/version file on Solaris so we try to get some
+ system information using the uname(2) syscall. */
+ struct vki_utsname uts;
+ VG_(message)(Vg_DebugMsg, "System information:\n");
+ SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
+ if (sr_isError(res))
+ VG_(message)(Vg_DebugMsg, " uname() failed\n");
+ else
+ VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
+ uts.sysname, uts.release, uts.version, uts.machine);
+# endif
+
+ VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
+ VG_(message)(
+ Vg_DebugMsg,
+ "Arch and hwcaps: %s, %s, %s\n",
+ LibVEX_ppVexArch ( vex_arch ),
+ LibVEX_ppVexEndness ( vex_archinfo.endness ),
+ LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
+ );
+ VG_(message)(Vg_DebugMsg,
+ "Page sizes: currently %u, max supported %u\n",
+ (UInt) VKI_PAGE_SIZE, (UInt) VKI_MAX_PAGE_SIZE);
+ VG_(message)(Vg_DebugMsg,
+ "Valgrind library directory: %s\n", VG_(libdir));
+ }
+}
/* ---------------------------------------------------------------------
Writing to file or a socket
@@ -54,19 +321,260 @@
After startup, the gdbserver monitor command might temporarily
set the fd of log_output_sink to -2 to indicate that output is
to be given to gdb rather than output to the startup fd */
-OutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */
-OutputSink VG_(xml_output_sink) = { -1, False }; /* disabled */
-
+OutputSink VG_(log_output_sink) = { 2, VgLogTo_Fd, NULL }; /* 2 = stderr */
+OutputSink VG_(xml_output_sink) = { -1, VgLogTo_Fd, NULL }; /* disabled */
+
+static void revert_sink_to_stderr ( OutputSink *sink )
+{
+ sink->fd = 2; /* stderr */
+ sink->type = VgLogTo_Fd;
+ VG_(free)(sink->fsname_expanded);
+ sink->fsname_expanded = NULL;
+}
+
+static Int prepare_sink_fd(const HChar *clo_fname_unexpanded, OutputSink *sink,
+ Bool is_xml)
+{
+ vg_assert(clo_fname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
+
+ // Nb: we overwrite an existing file of this name without asking
+ // any questions.
+ HChar *logfilename = VG_(expand_file_name)(
+ (is_xml) ? "--xml-file" : "--log-file",
+ clo_fname_unexpanded);
+ SysRes sres = VG_(open)(logfilename,
+ VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
+ VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
+ if (!sr_isError(sres)) {
+ Int fd = sr_Res(sres);
+ sink->fsname_expanded = logfilename;
+ sink->type = VgLogTo_File;
+ return fd;
+ } else {
+ VG_(fmsg)("Cannot create %s file '%s': %s\n",
+ (is_xml) ? "XML" : "log", logfilename,
+ VG_(strerror)(sr_Err(sres)));
+ VG_(exit)(1);
+ /*NOTREACHED*/
+ }
+}
+
+static Int prepare_sink_socket(const HChar *clo_fname_unexpanded,
+ OutputSink *sink, Bool is_xml)
+{
+ vg_assert(clo_fname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
+
+ Int fd = VG_(connect_via_socket)(clo_fname_unexpanded);
+ if (fd == -1) {
+ VG_(fmsg)("Invalid %s spec of '%s'\n",
+ (is_xml) ? "--xml-socket" : "--log-socket",
+ clo_fname_unexpanded);
+ VG_(exit)(1);
+ /*NOTREACHED*/
+ }
+ if (fd == -2) {
+ VG_(umsg)("Failed to connect to %slogging server '%s'.\n"
+ "%s will be sent to stderr instead.\n",
+ (is_xml) ? "XML " : "",
+ (is_xml) ? "XML output" : "Logging messages",
+ clo_fname_unexpanded);
+ /* We don't change anything here. */
+ vg_assert(sink->fd == 2);
+ vg_assert(sink->type == VgLogTo_Fd);
+ return 2;
+ } else {
+ vg_assert(fd > 0);
+ sink->type = VgLogTo_Socket;
+ return fd;
+ }
+}
+
+static void finalize_sink_fd(OutputSink *sink, Int new_fd, Bool is_xml)
+{
+ // Move new_fd into the safe range, so it doesn't conflict with any app fds.
+ Int safe_fd = VG_(fcntl)(new_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
+ if (safe_fd < 0) {
+ VG_(message)(Vg_UserMsg, "Valgrind: failed to move %s file descriptor "
+ "into safe range, using stderr\n",
+ (is_xml) ? "XML" : "log");
+ revert_sink_to_stderr(sink);
+ } else {
+ VG_(fcntl)(safe_fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
+ sink->fd = safe_fd;
+ }
+}
+
+/* Re-opens an output file sink when exanded file name differs from what we
+ have now. Returns 'True' if the sink was reopened */
+static Bool reopen_sink_if_needed(const HChar *clo_fname_unexpanded,
+ OutputSink *sink, Bool is_xml)
+{
+ if (sink->type == VgLogTo_File) {
+ /* Try to expand --log|xml-file again and see if it differs from what
+ we have now. */
+ HChar *logfilename = VG_(expand_file_name)(
+ (is_xml) ? "--xml-file" : "--log-file",
+ clo_fname_unexpanded);
+ if (VG_(strcmp)(logfilename, sink->fsname_expanded) != 0) {
+ Int fd = prepare_sink_fd(clo_fname_unexpanded, sink, is_xml);
+ finalize_sink_fd(sink, fd, is_xml);
+ return True;
+ }
+ VG_(free)(logfilename);
+ }
+
+ return False;
+}
+
+void VG_(logging_atfork_child)(ThreadId tid)
+{
+ /* If --child-silent-after-fork=yes was specified, set the output file
+ descriptors to 'impossible' values. This is noticed by
+ send_bytes_to_logging_sink(), which duly stops writing any further
+ output. */
+ if (VG_(clo_child_silent_after_fork)) {
+ if (VG_(log_output_sink).type != VgLogTo_Socket) {
+ VG_(log_output_sink).fd = -1;
+ VG_(log_output_sink).type = VgLogTo_Fd;
+ }
+ if (VG_(xml_output_sink).type != VgLogTo_Socket) {
+ VG_(xml_output_sink).fd = -1;
+ VG_(xml_output_sink).type = VgLogTo_Fd;
+ }
+ } else {
+ if (reopen_sink_if_needed(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False) ||
+ reopen_sink_if_needed(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True)) {
+ VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
+ }
+ }
+}
+
+/* Initializes normal log and xml sinks (of type fd, file, or socket).
+ Any problem encountered is considered a hard error and causes V. to exit.
+
+ Comments on how the logging options are handled:
+
+ User can specify:
+ --log-fd= for a fd to write to (default setting, fd = 2)
+ --log-file= for a file name to write to
+ --log-socket= for a socket to write to
+
+ As a result of examining these and doing relevant socket/file
+ opening, a final fd is established. This is stored in
+ VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
+ specified, then it is stored in VG_(clo_log_fname_unexpanded), in m_options.
+ And then STR, after expansion of %p and %q templates within
+ it, is stored in VG_(log_output_sink), just in case anybody wants to know
+ what it is.
+
+ When printing, VG_(log_output_sink) is consulted to find the
+ fd to send output to.
+
+ Exactly analogous actions are undertaken for the XML output
+ channel, with the one difference that the default fd is -1, meaning
+ the channel is disabled by default. */
+void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
+ Int /*initial*/log_fd, Int /*initial*/xml_fd)
+{
+ // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
+ // and we cannot change it until we know what we are changing it to is ok.
+
+ /* Start setting up logging now. After this is done, VG_(log_output_sink)
+ and (if relevant) VG_(xml_output_sink) should be connected to whatever
+ sink has been selected, and we indiscriminately chuck stuff into it
+ without worrying what the nature of it is.
+ Oh the wonder of Unix streams. */
+
+ vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
+ vg_assert(VG_(log_output_sink).type == VgLogTo_Fd);
+ vg_assert(VG_(log_output_sink).fsname_expanded == NULL);
+
+ vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
+ vg_assert(VG_(xml_output_sink).type == VgLogTo_Fd);
+ vg_assert(VG_(xml_output_sink).fsname_expanded == NULL);
+
+ /* --- set up the normal text output channel --- */
+ switch (log_to) {
+ case VgLogTo_Fd:
+ vg_assert(VG_(clo_log_fname_unexpanded) == NULL);
+ break;
+
+ case VgLogTo_File:
+ log_fd = prepare_sink_fd(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False);
+ break;
+
+ case VgLogTo_Socket:
+ log_fd = prepare_sink_socket(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False);
+ break;
+ }
+
+ /* --- set up the XML output channel --- */
+ switch (xml_to) {
+ case VgLogTo_Fd:
+ vg_assert(VG_(clo_xml_fname_unexpanded) == NULL);
+ break;
+
+ case VgLogTo_File:
+ xml_fd = prepare_sink_fd(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True);
+ break;
+
+ case VgLogTo_Socket:
+ log_fd = prepare_sink_socket(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True);
+ break;
+ }
+
+ /* If we've got this far, and XML mode was requested, but no XML
+ output channel appears to have been specified, just stop. We
+ could continue, and XML output will simply vanish into nowhere,
+ but that is likely to confuse the hell out of users, which is
+ distinctly Ungood. */
+ if (VG_(clo_xml) && xml_fd == -1) {
+ VG_(fmsg_bad_option)(
+ "--xml=yes, but no XML destination specified",
+ "--xml=yes has been specified, but there is no XML output\n"
+ "destination. You must specify an XML output destination\n"
+ "using --xml-fd, --xml-file or --xml-socket.\n"
+ );
+ }
+
+ // Finalise the output fds: the log fd ..
+ if (log_fd >= 0) {
+ finalize_sink_fd(&VG_(log_output_sink), log_fd, False);
+ } else {
+ // If they said --log-fd=-1, don't print anything. Plausible for use in
+ // regression testing suites that use client requests to count errors.
+ VG_(log_output_sink).fd = -1;
+ VG_(log_output_sink).type = VgLogTo_Fd;
+ }
+
+ // Finalise the output fds: and the XML fd ..
+ if (xml_fd >= 0) {
+ finalize_sink_fd(&VG_(xml_output_sink), xml_fd, True);
+ } else {
+ // If they said --xml-fd=-1, don't print anything. Plausible for use in
+ // regression testing suites that use client requests to count errors.
+ VG_(xml_output_sink).fd = -1;
+ VG_(xml_output_sink).type = VgLogTo_Fd;
+ }
+}
+
/* Do the low-level send of a message to the logging sink. */
static
void send_bytes_to_logging_sink ( OutputSink* sink, const HChar* msg, Int nbytes )
{
- if (sink->is_socket) {
+ if (sink->type == VgLogTo_Socket) {
Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
if (rc == -1) {
// For example, the listener process died. Switch back to stderr.
- sink->is_socket = False;
- sink->fd = 2;
+ revert_sink_to_stderr(sink);
VG_(write)( sink->fd, msg, nbytes );
}
} else {
@@ -557,8 +1065,7 @@
static void revert_to_stderr ( void )
{
- VG_(log_output_sink).fd = 2; /* stderr */
- VG_(log_output_sink).is_socket = False;
+ revert_sink_to_stderr(&VG_(log_output_sink));
}
/* VG_(message) variants with hardwired first argument. */
Modified: trunk/coregrind/m_main.c
==============================================================================
--- trunk/coregrind/m_main.c (original)
+++ trunk/coregrind/m_main.c Thu Jan 12 11:28:20 2017
@@ -31,7 +31,6 @@
#include "vgversion.h"
#include "pub_core_basics.h"
#include "pub_core_vki.h"
-#include "pub_core_vkiscnums.h"
#include "pub_core_threadstate.h"
#include "pub_core_xarray.h"
#include "pub_core_clientstate.h"
@@ -51,7 +50,6 @@
#include "pub_core_libcproc.h"
#include "pub_core_libcsignal.h"
#include "pub_core_sbprofile.h"
-#include "pub_core_syscall.h" // VG_(strerror)
#include "pub_core_mach.h"
#include "pub_core_machine.h"
#include "pub_core_mallocfree.h"
@@ -314,7 +312,7 @@
// Ensure the message goes to stdout
VG_(log_output_sink).fd = 1;
- VG_(log_output_sink).is_socket = False;
+ VG_(log_output_sink).type = VgLogTo_Fd;
if (VG_(needs).malloc_replacement) {
VG_(sprintf)(default_alignment, "%d", VG_MIN_MALLOC_SZB);
@@ -363,7 +361,7 @@
- show the version string, if requested (-v)
- extract any request for help (--help, -h, --help-debug)
- - get the toolname (--tool=)
+ - set VG_(toolname) (--tool=)
- set VG_(clo_max_stackframe) (--max-stackframe=)
- set VG_(clo_main_stacksize) (--main-stacksize=)
- set VG_(clo_sim_hints) (--sim-hints=)
@@ -374,8 +372,7 @@
main_process_cmd_line_options has to handle but ignore the ones we
have handled here.
*/
-static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
- /*OUT*/const HChar** tool )
+static void early_process_cmd_line_options ( /*OUT*/Int* need_help )
{
UInt i;
HChar* str;
@@ -403,7 +400,7 @@
// The tool has already been determined, but we need to know the name
// here.
- else if VG_STR_CLO(str, "--tool", *tool) {}
+ else if VG_STR_CLO(str, "--tool", VG_(clo_toolname)) {}
// Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
// These are needed by VG_(ii_create_image), which happens
@@ -427,7 +424,7 @@
if (need_version) {
// Nb: the version string goes to stdout.
VG_(log_output_sink).fd = 1;
- VG_(log_output_sink).is_socket = False;
+ VG_(log_output_sink).type = VgLogTo_Fd;
if (VG_(clo_verbosity) <= 1)
VG_(printf)("valgrind-" VERSION "\n");
else
@@ -440,53 +437,13 @@
}
/* The main processing for command line options. See comments above
- on early_process_cmd_line_options.
-
- Comments on how the logging options are handled:
-
- User can specify:
- --log-fd= for a fd to write to (default setting, fd = 2)
- --log-file= for a file name to write to
- --log-socket= for a socket to write to
-
- As a result of examining these and doing relevant socket/file
- opening, a final fd is established. This is stored in
- VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
- specified, then STR, after expansion of %p and %q templates within
- it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
- case anybody wants to know what it is.
-
- When printing, VG_(log_output_sink) is consulted to find the
- fd to send output to.
-
- Exactly analogous actions are undertaken for the XML output
- channel, with the one difference that the default fd is -1, meaning
- the channel is disabled by default.
-*/
+ on early_process_cmd_line_options. */
static
-void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
- /*OUT*/const HChar** xml_fname_unexpanded,
- const HChar* toolname )
-{
- // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
- // and we cannot change it until we know what we are changing it to is
- // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
- SysRes sres;
- Int i, tmp_log_fd, tmp_xml_fd;
- Int toolname_len = VG_(strlen)(toolname);
+void main_process_cmd_line_options( void )
+{
+ Int i;
+ Int toolname_len = VG_(strlen)(VG_(clo_toolname));
const HChar* tmp_str; // Used in a couple of places.
- enum {
- VgLogTo_Fd,
- VgLogTo_File,
- VgLogTo_Socket
- } log_to = VgLogTo_Fd, // Where is logging output to be sent?
- xml_to = VgLogTo_Fd; // Where is XML output to be sent?
-
- /* Temporarily holds the string STR specified with
- --{log,xml}-{name,socket}=STR. 'fs' stands for
- file-or-socket. */
- const HChar* log_fsname_unexpanded = NULL;
- const HChar* xml_fsname_unexpanded = NULL;
/* Whether the user has explicitly provided --sigill-diagnostics.
If not explicitly given depends on general verbosity setting. */
@@ -494,9 +451,11 @@
/* Log to stderr by default, but usage message goes to stdout. XML
output is initially disabled. */
- tmp_log_fd = 2;
- tmp_xml_fd = -1;
-
+ VgLogTo log_to = VgLogTo_Fd; // Where is logging output to be sent?
+ VgLogTo xml_to = VgLogTo_Fd; // Where is XML output to be sent?
+ Int tmp_log_fd = 2;
+ Int tmp_xml_fd = -1;
+
/* Check for sane path in ./configure --prefix=... */
if (VG_LIBDIR[0] != '/')
VG_(err_config_error)("Please use absolute paths in "
@@ -536,7 +495,7 @@
// eg. "--memcheck:verbose".
if (*colon == ':') {
if (VG_STREQN(2, arg, "--") &&
- VG_STREQN(toolname_len, arg+2, toolname) &&
+ VG_STREQN(toolname_len, arg+2, VG_(clo_toolname)) &&
VG_STREQN(1, arg+2+toolname_len, ":"))
{
// Prefix matches, convert "--toolname:foo" to "--foo".
@@ -780,24 +739,24 @@
else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
log_to = VgLogTo_Fd;
- log_fsname_unexpanded = NULL;
+ VG_(clo_log_fname_unexpanded) = NULL;
}
else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
xml_to = VgLogTo_Fd;
- xml_fsname_unexpanded = NULL;
+ VG_(clo_xml_fname_unexpanded) = NULL;
}
- else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_fname_unexpanded)) {
log_to = VgLogTo_File;
}
- else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--xml-file", VG_(clo_xml_fname_unexpanded)) {
xml_to = VgLogTo_File;
}
- else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_fname_unexpanded)) {
log_to = VgLogTo_Socket;
}
- else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--xml-socket", VG_(clo_xml_fname_unexpanded)) {
xml_to = VgLogTo_Socket;
}
@@ -1031,197 +990,13 @@
have to generate any other command-line-related error messages.
(So far we should be still attached to stderr, so we can show on
the terminal any problems to do with processing command line
- opts.)
-
- So set up logging now. After this is done, VG_(log_output_sink)
- and (if relevant) VG_(xml_output_sink) should be connected to
- whatever sink has been selected, and we indiscriminately chuck
- stuff into it without worrying what the nature of it is. Oh the
- wonder of Unix streams. */
-
- vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
- vg_assert(VG_(log_output_sink).is_socket == False);
- vg_assert(VG_(clo_log_fname_expanded) == NULL);
-
- vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
- vg_assert(VG_(xml_output_sink).is_socket == False);
- vg_assert(VG_(clo_xml_fname_expanded) == NULL);
-
- /* --- set up the normal text output channel --- */
+ opts.) */
+ VG_(init_log_xml_sinks)(log_to, xml_to, tmp_log_fd, tmp_xml_fd);
- switch (log_to) {
-
- case VgLogTo_Fd:
- vg_assert(log_fsname_unexpanded == NULL);
- break;
-
- case VgLogTo_File: {
- HChar* logfilename;
-
- vg_assert(log_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
-
- // Nb: we overwrite an existing file of this name without asking
- // any questions.
- logfilename = VG_(expand_file_name)("--log-file",
- log_fsname_unexpanded);
- sres = VG_(open)(logfilename,
- VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
- VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
- if (!sr_isError(sres)) {
- tmp_log_fd = sr_Res(sres);
- VG_(clo_log_fname_expanded) = logfilename;
- } else {
- VG_(fmsg)("can't create log file '%s': %s\n",
- logfilename, VG_(strerror)(sr_Err(sres)));
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- break;
- }
-
- case VgLogTo_Socket: {
- vg_assert(log_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
- tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
- if (tmp_log_fd == -1) {
- VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
- log_fsname_unexpanded);
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- if (tmp_log_fd == -2) {
- VG_(umsg)("failed to connect to logging server '%s'.\n"
- "Log messages will sent to stderr instead.\n",
- log_fsname_unexpanded );
-
- /* We don't change anything here. */
- vg_assert(VG_(log_output_sink).fd == 2);
- tmp_log_fd = 2;
- } else {
- vg_assert(tmp_log_fd > 0);
- VG_(log_output_sink).is_socket = True;
- }
- break;
- }
- }
-
- /* --- set up the XML output channel --- */
-
- switch (xml_to) {
-
- case VgLogTo_Fd:
- vg_assert(xml_fsname_unexpanded == NULL);
- break;
-
- case VgLogTo_File: {
- HChar* xmlfilename;
-
- vg_assert(xml_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
-
- // Nb: we overwrite an existing file of this name without asking
- // any questions.
- xmlfilename = VG_(expand_file_name)("--xml-file",
- xml_fsname_unexpanded);
- sres = VG_(open)(xmlfilename,
- VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
- VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
- if (!sr_isError(sres)) {
- tmp_xml_fd = sr_Res(sres);
- VG_(clo_xml_fname_expanded) = xmlfilename;
- *xml_fname_unexpanded = xml_fsname_unexpanded;
- } else {
- VG_(fmsg)("can't create XML file '%s': %s\n",
- xmlfilename, VG_(strerror)(sr_Err(sres)));
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- break;
- }
-
- case VgLogTo_Socket: {
- vg_assert(xml_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
- tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
- if (tmp_xml_fd == -1) {
- VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
- xml_fsname_unexpanded );
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- if (tmp_xml_fd == -2) {
- VG_(umsg)("failed to connect to XML logging server '%s'.\n"
- "XML output will sent to stderr instead.\n",
- xml_fsname_unexpanded);
- /* We don't change anything here. */
- vg_assert(VG_(xml_output_sink).fd == 2);
- tmp_xml_fd = 2;
- } else {
- vg_assert(tmp_xml_fd > 0);
- VG_(xml_output_sink).is_socket = True;
- }
- break;
- }
- }
-
- /* If we've got this far, and XML mode was requested, but no XML
- output channel appears to have been specified, just stop. We
- could continue, and XML output will simply vanish into nowhere,
- but that is likely to confuse the hell out of users, which is
- distinctly Ungood. */
- if (VG_(clo_xml) && tmp_xml_fd == -1) {
- VG_(fmsg_bad_option)(
- "--xml=yes, but no XML destination specified",
- "--xml=yes has been specified, but there is no XML output\n"
- "destination. You must specify an XML output destination\n"
- "using --xml-fd, --xml-file or --xml-socket.\n"
- );
- }
-
- // Finalise the output fds: the log fd ..
-
- if (tmp_log_fd >= 0) {
- // Move log_fd into the safe range, so it doesn't conflict with
- // any app fds.
- tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
- if (tmp_log_fd < 0) {
- VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
- "into safe range, using stderr\n");
- VG_(log_output_sink).fd = 2; // stderr
- VG_(log_output_sink).is_socket = False;
- } else {
- VG_(log_output_sink).fd = tmp_log_fd;
- VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
- }
- } else {
- // If they said --log-fd=-1, don't print anything. Plausible for use in
- // regression testing suites that use client requests to count errors.
- VG_(log_output_sink).fd = -1;
- VG_(log_output_sink).is_socket = False;
- }
-
- // Finalise the output fds: and the XML fd ..
-
- if (tmp_xml_fd >= 0) {
- // Move xml_fd into the safe range, so it doesn't conflict with
- // any app fds.
- tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
- if (tmp_xml_fd < 0) {
- VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
- "into safe range, using stderr\n");
- VG_(xml_output_sink).fd = 2; // stderr
- VG_(xml_output_sink).is_socket = False;
- } else {
- VG_(xml_output_sink).fd = tmp_xml_fd;
- VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
- }
- } else {
- // If they said --xml-fd=-1, don't print anything. Plausible for use in
- // regression testing suites that use client requests to count errors.
- VG_(xml_output_sink).fd = -1;
- VG_(xml_output_sink).is_socket = False;
- }
+ /* Register child at-fork handler which will take care of handling
+ --child-silent-after-fork clo and also reopening output sinks for forked
+ children, if requested via --log|xml-file= options. */
+ VG_(atfork)(NULL, NULL, VG_(logging_atfork_child));
// Suppressions related stuff
@@ -1235,294 +1010,6 @@
VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
VG_(addToXA)(VG_(clo_suppressions), &buf);
}
-
- *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
-}
-
-// Write the name and value of log file qualifiers to the xml file.
-// We can safely assume here that the format string is well-formed.
-// It has been checked earlier in VG_(expand_file_name) when processing
-// command line options.
-static void print_file_vars(const HChar* format)
-{
- Int i = 0;
-
- while (format[i]) {
- if (format[i] == '%') {
- // We saw a '%'. What's next...
- i++;
- if ('q' == format[i]) {
- i++;
- if ('{' == format[i]) {
- // Get the env var name, print its contents.
- HChar* qual;
- Int begin_qualname = ++i;
- while (True) {
- if ('}' == format[i]) {
- Int qualname_len = i - begin_qualname;
- HChar qualname[qualname_len + 1];
- VG_(strncpy)(qualname, format + begin_qualname,
- qualname_len);
- qualname[qualname_len] = '\0';
- qual = VG_(getenv)(qualname);
- i++;
- VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
- "<value>%pS</value> </logfilequalifier>\n",
- qualname, qual);
- break;
- }
- i++;
- }
- }
- }
- } else {
- i++;
- }
- }
-}
-
-
-/*====================================================================*/
-/*=== Printing the preamble ===*/
-/*====================================================================*/
-
-// Print the argument, escaping any chars that require it.
-static void umsg_arg(const HChar* arg)
-{
- SizeT len = VG_(strlen)(arg);
- const HChar* special = " \\<>";
- Int i;
- for (i = 0; i < len; i++) {
- if (VG_(strchr)(special, arg[i])) {
- VG_(umsg)("\\"); // escape with a backslash if necessary
- }
- VG_(umsg)("%c", arg[i]);
- }
-}
-
-// Send output to the XML-stream and escape any XML meta-characters.
-static void xml_arg(const HChar* arg)
-{
- VG_(printf_xml)("%pS", arg);
-}
-
-/* Ok, the logging sink is running now. Print a suitable preamble.
- If logging to file or a socket, write details of parent PID and
- command line args, to help people trying to interpret the
- results of a run which encompasses multiple processes. */
-static void print_preamble ( Bool logging_to_fd,
- const HChar* xml_fname_unexpanded,
- const HChar* toolname )
-{
- Int i;
- const HChar* xpre = VG_(clo_xml) ? " <line>" : "";
- const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
- UInt (*umsg_or_xml)( const HChar*, ... )
- = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
-
- void (*umsg_or_xml_arg)( const HChar* )
- = VG_(clo_xml) ? xml_arg : umsg_arg;
-
- vg_assert( VG_(args_for_client) );
- vg_assert( VG_(args_for_valgrind) );
- vg_assert( toolname );
-
- if (VG_(clo_xml)) {
- VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<valgrindoutput>\n");
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
- VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
- VG_(printf_xml)("\n");
- }
-
- if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
-
- if (VG_(clo_xml))
- VG_(printf_xml)("<preamble>\n");
-
- /* Tool details */
- umsg_or_xml( VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
- xpre,
- VG_(details).name,
- NULL == VG_(details).version ? "" : "-",
- NULL == VG_(details).version
- ? "" : VG_(details).version,
- VG_(details).description,
- xpost );
-
- if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
- umsg_or_xml(
- "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
- xpre, xpost
- );
- }
-
- umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
- xpre, VG_(details).copyright_author, xpost );
-
- /* Core details */
- umsg_or_xml(
- "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
- xpre, VERSION, xpost
- );
-
- // Print the command line. At one point we wrapped at 80 chars and
- // printed a '\' as a line joiner, but that makes it hard to cut and
- // paste the command line (because of the "==pid==" prefixes), so we now
- // favour utility and simplicity over aesthetics.
- umsg_or_xml("%sCommand: ", xpre);
- umsg_or_xml_arg(VG_(args_the_exename));
-
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
- HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
- umsg_or_xml(" ");
- umsg_or_xml_arg(s);
- }
- umsg_or_xml("%s\n", xpost);
-
- if (VG_(clo_xml))
- VG_(printf_xml)("</preamble>\n");
- }
-
- // Print the parent PID, and other stuff, if necessary.
- if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
- VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
- }
- else
- if (VG_(clo_xml)) {
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
- VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
- VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
- if (xml_fname_unexpanded)
- print_file_vars(xml_fname_unexpanded);
- if (VG_(clo_xml_user_comment)) {
- /* Note: the user comment itself is XML and is therefore to
- be passed through verbatim (%s) rather than escaped
- (%pS). */
- VG_(printf_xml)("<usercomment>%s</usercomment>\n",
- VG_(clo_xml_user_comment));
- }
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<args>\n");
-
- VG_(printf_xml)(" <vargv>\n");
- if (VG_(name_of_launcher))
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- VG_(name_of_launcher));
- else
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- "(launcher name unknown)");
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
- VG_(printf_xml)(
- " <arg>%pS</arg>\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
- );
- }
- VG_(printf_xml)(" </vargv>\n");
-
- VG_(printf_xml)(" <argv>\n");
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- VG_(args_the_exename));
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
- VG_(printf_xml)(
- " <arg>%pS</arg>\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
- );
- }
- VG_(printf_xml)(" </argv>\n");
-
- VG_(printf_xml)("</args>\n");
- }
-
- // Last thing in the preamble is a blank line.
- if (VG_(clo_xml))
- VG_(printf_xml)("\n");
- else if (VG_(clo_verbosity) > 0)
- VG_(umsg)("\n");
-
- if (VG_(clo_verbosity) > 1) {
-# if defined(VGO_linux)
- SysRes fd;
-# endif
- VexArch vex_arch;
- VexArchInfo vex_archinfo;
- if (!logging_to_fd)
- VG_(message)(Vg_DebugMsg, "\n");
- VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
- VG_(message)(Vg_DebugMsg,
- " %s\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
- }
-
-# if defined(VGO_linux)
- VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
- fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
- if (sr_isError(fd)) {
- VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
- } else {
- const SizeT bufsiz = 255;
- HChar version_buf[bufsiz+1];
- VG_(message)(Vg_DebugMsg, " ");
- Int n, fdno = sr_Res(fd);
- do {
- n = VG_(read)(fdno, version_buf, bufsiz);
- if (n < 0) {
- VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
- break;
- }
- version_buf[n] = '\0';
- VG_(message)(Vg_DebugMsg, "%s", version_buf);
- } while (n == bufsiz);
- VG_(message)(Vg_DebugMsg, "\n");
- VG_(close)(fdno);
- }
-# elif defined(VGO_darwin)
- VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
- /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
- however that syscall is OS X 10.10+ only. */
- Int mib[] = {CTL_KERN, KERN_VERSION};
- SizeT len;
- VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
- HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
- VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
- VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
- VG_(free)( kernelVersion );
-# elif defined(VGO_solaris)
- /* There is no /proc/version file on Solaris so we try to get some
- system information using the uname(2) syscall. */
- {
- struct vki_utsname uts;
-
- VG_(message)(Vg_DebugMsg, "System information:\n");
- SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
- if (sr_isError(res))
- VG_(message)(Vg_DebugMsg, " uname() failed\n");
- else
- VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
- uts.sysname, uts.release, uts.version, uts.machine);
- }
-# endif
-
- VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
- VG_(message)(
- Vg_DebugMsg,
- "Arch and hwcaps: %s, %s, %s\n",
- LibVEX_ppVexArch ( vex_arch ),
- LibVEX_ppVexEndness ( vex_archinfo.endness ),
- LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
- );
- VG_(message)(
- Vg_DebugMsg,
- "Page sizes: currently %d, max supported %d\n",
- (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
- );
- VG_(message)(Vg_DebugMsg,
- "Valgrind library directory: %s\n", VG_(libdir));
- }
}
@@ -1643,11 +1130,8 @@
static
Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
{
- const HChar* toolname = "memcheck"; // default to Memcheck
Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
ThreadId tid_main = VG_INVALID_THREADID;
- Bool logging_to_fd = False;
- const HChar* xml_fname_unexpanded = NULL;
Int loglevel, i;
XArray* addr2dihandle = NULL;
@@ -1914,15 +1398,15 @@
//--------------------------------------------------------------
VG_(debugLog)(1, "main",
"(early_) Process Valgrind's command line options\n");
- early_process_cmd_line_options(&need_help, &toolname);
+ early_process_cmd_line_options(&need_help);
// BEGIN HACK
- vg_assert(toolname != NULL);
+ vg_assert(VG_(clo_toolname) != NULL);
vg_assert(VG_(clo_read_inline_info) == False);
# if !defined(VGO_darwin)
- if (0 == VG_(strcmp)(toolname, "memcheck")
- || 0 == VG_(strcmp)(toolname, "helgrind")
- || 0 == VG_(strcmp)(toolname, "drd")) {
+ if (0 == VG_(strcmp)(VG_(clo_toolname), "memcheck")
+ || 0 == VG_(strcmp)(VG_(clo_toolname), "helgrind")
+ || 0 == VG_(strcmp)(VG_(clo_toolname), "drd")) {
/* Change the default setting. Later on (just below)
main_process_cmd_line_options should pick up any
user-supplied setting for it and will override the default
@@ -1944,7 +1428,7 @@
//
// Set up client's environment
// p: set-libdir [for VG_(libdir)]
- // p: early_process_cmd_line_options [for toolname]
+ // p: early_process_cmd_line_options [for VG_(clo_toolname)]
//
// Setup client stack, eip, and VG_(client_arg[cv])
// p: load_client() [for 'info']
@@ -1963,7 +1447,7 @@
# if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
the_iicii.argv = argv;
the_iicii.envp = envp;
- the_iicii.toolname = toolname;
+ the_iicii.toolname = VG_(clo_toolname);
# else
# error "Unknown platform"
# endif
@@ -2120,8 +1604,7 @@
VG_(debugLog)(1, "main",
"(main_) Process Valgrind's command line options, "
"setup logging\n");
- main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
- toolname );
+ main_process_cmd_line_options();
//--------------------------------------------------------------
// Zeroise the millisecond counter by doing a first read of it.
@@ -2133,11 +1616,10 @@
// Print the preamble
// p: tl_pre_clo_init [for 'VG_(details).name' and friends]
// p: main_process_cmd_line_options()
- // [for VG_(clo_verbosity), VG_(clo_xml),
- // logging_to_fd, xml_fname_unexpanded]
+ // [for VG_(clo_verbosity), VG_(clo_xml)]
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Print the preamble...\n");
- print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
+ VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
VG_(debugLog)(1, "main", "...finished the preamble\n");
//--------------------------------------------------------------
Modified: trunk/coregrind/m_options.c
==============================================================================
--- trunk/coregrind/m_options.c (original)
+++ trunk/coregrind/m_options.c Thu Jan 12 11:28:20 2017
@@ -45,6 +45,7 @@
/* Define, and set defaults. */
+const HChar *VG_(clo_toolname) = "memcheck"; // default to Memcheck
VexControl VG_(clo_vex_control);
VexRegisterUpdates VG_(clo_px_file_backed) = VexRegUpd_INVALID;
@@ -79,8 +80,8 @@
const HChar* VG_(clo_trace_children_skip) = NULL;
const HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
Bool VG_(clo_child_silent_after_fork) = False;
-const HChar* VG_(clo_log_fname_expanded) = NULL;
-const HChar* VG_(clo_xml_fname_expanded) = NULL;
+const HChar *VG_(clo_log_fname_unexpanded) = NULL;
+const HChar *VG_(clo_xml_fname_unexpanded) = NULL;
Bool VG_(clo_time_stamp) = False;
Int VG_(clo_input_fd) = 0; /* stdin */
Bool VG_(clo_default_supp) = True;
Modified: trunk/coregrind/m_syswrap/syswrap-generic.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-generic.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-generic.c Thu Jan 12 11:28:20 2017
@@ -3301,18 +3301,6 @@
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-
- /* If --child-silent-after-fork=yes was specified, set the
- output file descriptors to 'impossible' values. This is
- noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
-
} else {
VG_(do_atfork_parent)(tid);
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Thu Jan 12 11:28:20 2017
@@ -788,17 +788,6 @@
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-
- /* If --child-silent-after-fork=yes was specified, set the
- output file descriptors to 'impossible' values. This is
- noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
}
else
if (!sr_isError(res) && sr_Res(res) > 0) {
Modified: trunk/coregrind/m_syswrap/syswrap-solaris.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-solaris.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-solaris.c Thu Jan 12 11:28:20 2017
@@ -6624,17 +6624,6 @@
if (RESHI) {
VG_(do_atfork_child)(tid);
- /* If --child-silent-after-fork=yes was specified, set the output file
- descriptors to 'impossible' values. This is noticed by
- send_bytes_to_logging_sink() in m_libcprint.c, which duly stops
- writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
-
/* vfork */
if (ARG1 == 2)
VG_(close)(fds[1]);
Modified: trunk/coregrind/pub_core_libcprint.h
==============================================================================
--- trunk/coregrind/pub_core_libcprint.h (original)
+++ trunk/coregrind/pub_core_libcprint.h Thu Jan 12 11:28:20 2017
@@ -38,16 +38,36 @@
#include "pub_tool_libcprint.h"
-/* An output file descriptor wrapped up with a Bool indicating whether
- or not the fd is a socket. */
typedef
- struct { Int fd; Bool is_socket; }
+ enum {
+ VgLogTo_Fd,
+ VgLogTo_File,
+ VgLogTo_Socket
+ }
+ VgLogTo;
+
+/* An output file descriptor wrapped up with its type and expanded name. */
+typedef
+ struct {
+ Int fd;
+ VgLogTo type;
+ HChar *fsname_expanded; // 'fs' stands for file or socket
+ }
OutputSink;
/* And the destinations for normal and XML output. */
extern OutputSink VG_(log_output_sink);
extern OutputSink VG_(xml_output_sink);
+/* Initializes normal log and xml sinks (of type fd, file, or socket).
+ Any problem encountered is considered a hard error and causes V. to exit. */
+extern void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
+ Int /*initial*/log_fd, Int /*initial*/xml_fd);
+
+extern void VG_(print_preamble)(Bool logging_to_fd);
+
+extern void VG_(logging_atfork_child)(ThreadId tid);
+
/* Get the elapsed wallclock time since startup into buf which has size
bufsize. The function will assert if bufsize is not large enough.
Upon return, buf will contain the zero-terminated wallclock time as
Modified: trunk/coregrind/pub_core_options.h
==============================================================================
--- trunk/coregrind/pub_core_options.h (original)
+++ trunk/coregrind/pub_core_options.h Thu Jan 12 11:28:20 2017
@@ -39,6 +39,9 @@
#include "pub_tool_options.h"
#include "pub_core_xarray.h"
+/* Valgrind tool name. Defaults to "memcheck". */
+extern const HChar *VG_(clo_toolname);
+
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
/* Alternative exit code to hand to parent if errors were found.
@@ -117,9 +120,9 @@
extern Bool VG_(clo_child_silent_after_fork);
/* If the user specified --log-file=STR and/or --xml-file=STR, these
- hold STR after expansion of the %p and %q templates. */
-extern const HChar* VG_(clo_log_fname_expanded);
-extern const HChar* VG_(clo_xml_fname_expanded);
+ hold STR before expansion. */
+extern const HChar *VG_(clo_log_fname_unexpanded);
+extern const HChar *VG_(clo_xml_fname_unexpanded);
/* Add timestamps to log messages? default: NO */
extern Bool VG_(clo_time_stamp);
|
|
From: <sv...@va...> - 2017-01-12 11:21:16
|
Author: sewardj
Date: Thu Jan 12 11:21:08 2017
New Revision: 3290
Log:
Implement ARMv8 VSEL<c>.F64 d_d_d, VSEL<c>.F32 s_s_s.
Modified:
trunk/priv/guest_arm_toIR.c
Modified: trunk/priv/guest_arm_toIR.c
==============================================================================
--- trunk/priv/guest_arm_toIR.c (original)
+++ trunk/priv/guest_arm_toIR.c Thu Jan 12 11:21:08 2017
@@ -13462,6 +13462,54 @@
/* else fall through */
}
+ /* ----------- VSEL<c>.F64 d_d_d, VSEL<c>.F32 s_s_s ----------- */
+ /* 31 27 22 21 19 15 11 8 7 6 5 4 3
+ T1/A1: 1111 11100 D cc n d 101 1 N 0 M 0 m VSEL<c>.F64 Dd, Dn, Dm
+ T1/A1: 1111 11100 D cc n d 101 0 N 0 M 0 m VSEL<c>.F32 Sd, Sn, Sm
+
+ ARM encoding is in NV space.
+ In Thumb mode, we must not be in an IT block.
+ */
+ if (INSN(31,23) == BITS9(1,1,1,1,1,1,1,0,0) && INSN(11,9) == BITS3(1,0,1)
+ && INSN(6,6) == 0 && INSN(4,4) == 0) {
+ UInt bit_D = INSN(22,22);
+ UInt fld_cc = INSN(21,20);
+ UInt fld_n = INSN(19,16);
+ UInt fld_d = INSN(15,12);
+ Bool isF64 = INSN(8,8) == 1;
+ UInt bit_N = INSN(7,7);
+ UInt bit_M = INSN(5,5);
+ UInt fld_m = INSN(3,0);
+
+ UInt dd = isF64 ? ((bit_D << 4) | fld_d) : ((fld_d << 1) | bit_D);
+ UInt nn = isF64 ? ((bit_N << 4) | fld_n) : ((fld_n << 1) | bit_N);
+ UInt mm = isF64 ? ((bit_M << 4) | fld_m) : ((fld_m << 1) | bit_M);
+
+ UInt cc_1 = (fld_cc >> 1) & 1;
+ UInt cc_0 = (fld_cc >> 0) & 1;
+ UInt cond = (fld_cc << 2) | ((cc_1 ^ cc_0) << 1) | 0;
+
+ if (isT) {
+ gen_SIGILL_T_if_in_ITBlock(old_itstate, new_itstate);
+ }
+ /* In ARM mode, this is statically unconditional. In Thumb mode,
+ this must be dynamically unconditional, and we've SIGILLd if not.
+ In either case we can create unconditional IR. */
+
+ IRTemp guard = newTemp(Ity_I32);
+ assign(guard, mk_armg_calculate_condition(cond));
+ IRExpr* srcN = (isF64 ? llGetDReg : llGetFReg)(nn);
+ IRExpr* srcM = (isF64 ? llGetDReg : llGetFReg)(mm);
+ IRExpr* res = IRExpr_ITE(unop(Iop_32to1, mkexpr(guard)), srcN, srcM);
+ (isF64 ? llPutDReg : llPutFReg)(dd, res);
+
+ UChar rch = isF64 ? 'd' : 'f';
+ DIP("vsel%s.%s %c%u, %c%u, %c%u\n",
+ nCC(cond), isF64 ? "f64" : "f32", rch, dd, rch, nn, rch, mm);
+ return True;
+ }
+ /* fall through */
+
/* ---------- Doesn't match anything. ---------- */
return False;
|
|
From: <sv...@va...> - 2017-01-11 22:13:58
|
Author: philippe
Date: Wed Jan 11 22:13:52 2017
New Revision: 16199
Log:
Do not capture the free stacktrace in memcheck, unless we have
either to keep the free stacktrace and/or to compute full xtree memory.
Also, properly compute avg nr of IP per execontext: the avg must
be computed using the real nr of execontext stored, not the hash
table size.
Modified:
trunk/coregrind/m_execontext.c
trunk/memcheck/mc_malloc_wrappers.c
Modified: trunk/coregrind/m_execontext.c
==============================================================================
--- trunk/coregrind/m_execontext.c (original)
+++ trunk/coregrind/m_execontext.c Wed Jan 11 22:13:52 2017
@@ -186,7 +186,7 @@
" exectx: %'lu lists, %'llu contexts (avg %3.2f per list)"
" (avg %3.2f IP per context)\n",
ec_htab_size, ec_totstored, (Double)ec_totstored / (Double)ec_htab_size,
- (Double)total_n_ips / (Double)ec_htab_size
+ (Double)total_n_ips / (Double)ec_totstored
);
VG_(message)(Vg_DebugMsg,
" exectx: %'llu searches, %'llu full compares (%'llu per 1000)\n",
Modified: trunk/memcheck/mc_malloc_wrappers.c
==============================================================================
--- trunk/memcheck/mc_malloc_wrappers.c (original)
+++ trunk/memcheck/mc_malloc_wrappers.c Wed Jan 11 22:13:52 2017
@@ -318,7 +318,11 @@
switch (MC_(clo_keep_stacktraces)) {
case KS_none: return;
- case KS_alloc: pos = -1; break;
+ case KS_alloc:
+ if (LIKELY(VG_(clo_xtree_memory)
+ != Vg_XTMemory_Full))
+ return;
+ pos = -1; break;
case KS_free: pos = 0; break;
case KS_alloc_then_free: pos = 0; break;
case KS_alloc_and_free: pos = 1; break;
@@ -332,7 +336,7 @@
ec_free = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
if (UNLIKELY(VG_(clo_xtree_memory) == Vg_XTMemory_Full))
VG_(XTMemory_Full_free)(mc->szB, mc->where[0], ec_free);
- if (pos >= 0)
+ if (LIKELY(pos >= 0))
mc->where[pos] = ec_free;
}
|
|
From: <sv...@va...> - 2017-01-11 21:49:47
|
Author: sewardj
Date: Wed Jan 11 21:49:40 2017
New Revision: 16198
Log:
Make this compile for both ARM and Thumb encodings,
and make it produce identical results for both encodings.
Modified:
trunk/none/tests/arm/v8fpsimd_a.c
Modified: trunk/none/tests/arm/v8fpsimd_a.c
==============================================================================
--- trunk/none/tests/arm/v8fpsimd_a.c (original)
+++ trunk/none/tests/arm/v8fpsimd_a.c Wed Jan 11 21:49:40 2017
@@ -1,7 +1,10 @@
/*
gcc -o v8fpsimd_a v8fpsimd_a.c -march=armv8-a -mfpu=crypto-neon-fp-armv8 \
- -I../../.. -Wall -g -marm
+ -I../../.. -Wall -g -marm
+
+gcc -o v8fpsimd_t v8fpsimd_a.c -march=armv8-a -mfpu=crypto-neon-fp-armv8 \
+ -I../../.. -Wall -g
*/
#include <stdio.h>
@@ -140,6 +143,20 @@
} while (0)
+/* Are we compiling for thumb or arm encodings? This has a bearing
+ on the inline assembly syntax needed below. */
+
+#if defined(__thumb__) || defined(__thumb2__)
+# define IT_EQ "it eq ; "
+# define IT_NE "it ne ; "
+# define IT_AL /* */
+#else
+# define IT_EQ /* */
+# define IT_NE /* */
+# define IT_AL /* */
+#endif
+
+
/* Generate a test that involves two vector regs,
with no bias as towards which is input or output.
It's OK to use r8 as scratch.
@@ -164,8 +181,20 @@
so a Q value of 8 or above is definitely invalid for a S register.
None of this is checked, though, so be careful when creating the
Q numbers.
+
+ It would be clearer and easier to write the Q numbers using integer
+ division. For example, in
+
+ GEN_TWOVEC_QDS_TEST(vcvtn_s32_f64, "vcvtn.s32.f64 s27, d5", 6,2)
+
+ instead of writing "6, 2" at the end, write "(27/4), (5/2)". This
+ would make clear the connection between the register numbers and
+ the Q numbers. Unfortunately those expressions need to expanded to
+ single digits at C-preprocessing time, and cpp won't do that. So
+ we have to do it the hard and error-prone way.
*/
-#define GEN_TWOVEC_QDS_TEST(TESTNAME,INSN,QVECREG1NO,QVECREG2NO) \
+#define GEN_TWOVEC_QDS_TEST(TESTNAME,INSN_PRE,INSN, \
+ QVECREG1NO,QVECREG2NO) \
__attribute__((noinline)) \
static void test_##TESTNAME ( LaneTy ty ) { \
Int i; \
@@ -180,15 +209,18 @@
randV128(&block[3], ty); \
__asm__ __volatile__( \
"mov r9, #0 ; vmsr fpscr, r9 ; " \
+ "msr apsr_nzcvq, r9 ; " \
"add r9, %0, #0 ; vld1.8 { q"#QVECREG1NO" }, [r9] ; " \
"add r9, %0, #16 ; vld1.8 { q"#QVECREG2NO" }, [r9] ; " \
- INSN " ; " \
+ INSN_PRE INSN " ; " \
"add r9, %0, #32 ; vst1.8 { q"#QVECREG1NO" }, [r9] ; " \
"add r9, %0, #48 ; vst1.8 { q"#QVECREG2NO" }, [r9] ; " \
"vmrs r9, fpscr ; str r9, [%0, #64] " \
: : "r"(&block[0]) \
: "cc", "memory", "q"#QVECREG1NO, "q"#QVECREG2NO, "r8", "r9" \
); \
+ /* Don't use INSN_PRE in printing, since that differs */ \
+ /* between ARM and Thumb and hence makes their outputs differ. */ \
printf(INSN " "); \
UInt fpscr = 0xFFFFFFFF & block[4].u32[0]; \
showV128(&block[0]); printf(" "); \
@@ -202,7 +234,8 @@
/* Generate a test that involves three vector regs,
with no bias as towards which is input or output. It's also OK
to use r8 as scratch. */
-#define GEN_THREEVEC_QDS_TEST(TESTNAME,INSN,QVECREG1NO,QVECREG2NO,QVECREG3NO) \
+#define GEN_THREEVEC_QDS_TEST(TESTNAME,INSN_PRE, \
+ INSN,QVECREG1NO,QVECREG2NO,QVECREG3NO) \
__attribute__((noinline)) \
static void test_##TESTNAME ( LaneTy ty ) { \
Int i; \
@@ -220,10 +253,11 @@
randV128(&block[5], ty); \
__asm__ __volatile__( \
"mov r9, #0 ; vmsr fpscr, r9 ; " \
+ "msr apsr_nzcvq, r9 ; " \
"add r9, %0, #0 ; vld1.8 { q"#QVECREG1NO" }, [r9] ; " \
"add r9, %0, #16 ; vld1.8 { q"#QVECREG2NO" }, [r9] ; " \
"add r9, %0, #32 ; vld1.8 { q"#QVECREG3NO" }, [r9] ; " \
- INSN " ; " \
+ INSN_PRE INSN " ; " \
"add r9, %0, #48 ; vst1.8 { q"#QVECREG1NO" }, [r9] ; " \
"add r9, %0, #64 ; vst1.8 { q"#QVECREG2NO" }, [r9] ; " \
"add r9, %0, #80 ; vst1.8 { q"#QVECREG3NO" }, [r9] ; " \
@@ -232,6 +266,8 @@
: "cc", "memory", "q"#QVECREG1NO, "q"#QVECREG2NO, "q"#QVECREG3NO, \
"r8", "r9" \
); \
+ /* Don't use INSN_PRE in printing, since that differs */ \
+ /* between ARM and Thumb and hence makes their outputs differ. */ \
printf(INSN " "); \
UInt fpscr = 0xFFFFFFFF & block[6].u32[0]; \
showV128(&block[0]); printf(" "); \
@@ -243,123 +279,155 @@
} \
}
-GEN_THREEVEC_QDS_TEST(vselge_f32, "vselge.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vselge_f64, "vselge.f64 d7, d8, d10", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselge_f32, IT_AL, "vselge.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselge_f64, IT_AL, "vselge.f64 d7, d8, d10", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vselgt_f32, "vselgt.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vselgt_f64, "vselgt.f64 d7, d8, d10", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselgt_f32, IT_AL, "vselgt.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselgt_f64, IT_AL, "vselgt.f64 d7, d8, d10", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vseleq_f32, "vseleq.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vseleq_f64, "vseleq.f64 d7, d8, d10", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vseleq_f32, IT_AL, "vseleq.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vseleq_f64, IT_AL, "vseleq.f64 d7, d8, d10", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vselvs_f32, "vselvs.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vselvs_f64, "vselvs.f64 d7, d8, d10", 3,4,5)
-
-GEN_THREEVEC_QDS_TEST(vmaxnm_f32, "vmaxnm.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vmaxnm_f64, "vmaxnm.f64 d7, d8, d10", 3,4,5)
-
-GEN_THREEVEC_QDS_TEST(vminnm_f32, "vminnm.f32 s15,s16,s20", 3,4,5)
-GEN_THREEVEC_QDS_TEST(vminnm_f64, "vminnm.f64 d7, d8, d10", 3,4,5)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_s32_f64, "vcvtn.s32.f64 s27, d5", 6,2)
-GEN_TWOVEC_QDS_TEST(vcvta_s32_f64, "vcvta.s32.f64 s4, d20", 1,10)
-GEN_TWOVEC_QDS_TEST(vcvtp_s32_f64, "vcvtp.s32.f64 s7, d31", 1,15)
-GEN_TWOVEC_QDS_TEST(vcvtm_s32_f64, "vcvtm.s32.f64 s1, d0", 0,0)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32, "vcvtn.s32.f32 s27, s5", 6,1)
-GEN_TWOVEC_QDS_TEST(vcvta_s32_f32, "vcvta.s32.f32 s4, s20", 1,5)
-GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32, "vcvtp.s32.f32 s7, s31", 1,7)
-GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32, "vcvtm.s32.f32 s1, s0", 0,0)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_u32_f64, "vcvtn.u32.f64 s27, d5", 6,2)
-GEN_TWOVEC_QDS_TEST(vcvta_u32_f64, "vcvta.u32.f64 s4, d20", 1,10)
-GEN_TWOVEC_QDS_TEST(vcvtp_u32_f64, "vcvtp.u32.f64 s7, d31", 1,15)
-GEN_TWOVEC_QDS_TEST(vcvtm_u32_f64, "vcvtm.u32.f64 s1, d0", 0,0)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32, "vcvtn.u32.f32 s27, s5", 6,1)
-GEN_TWOVEC_QDS_TEST(vcvta_u32_f32, "vcvta.u32.f32 s4, s20", 1,5)
-GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32, "vcvtp.u32.f32 s7, s31", 1,7)
-GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32, "vcvtm.u32.f32 s1, s0", 0,0)
-
-GEN_TWOVEC_QDS_TEST(vcvtb_f64_f16, "vcvtb.f64.f16 d27, s18", 13, 4)
-GEN_TWOVEC_QDS_TEST(vcvtt_f64_f16, "vcvtt.f64.f16 d28, s17", 14, 4)
-
-GEN_TWOVEC_QDS_TEST(vcvtb_f16_f64, "vcvtb.f16.f64 s9, d17", 2, 8)
-GEN_TWOVEC_QDS_TEST(vcvtt_f16_f64, "vcvtt.f16.f64 s8, d27", 2, 13)
-
-GEN_TWOVEC_QDS_TEST(vrintzeq_f64_f64, "vrintzeq.f64.f64 d0, d9", 0, 4)
-GEN_TWOVEC_QDS_TEST(vrintzne_f64_f64, "vrintzne.f64.f64 d1, d10", 0, 5)
-GEN_TWOVEC_QDS_TEST(vrintzal_f64_f64, "vrintzal.f64.f64 d2, d11", 1, 5)
-
-GEN_TWOVEC_QDS_TEST(vrintreq_f64_f64, "vrintreq.f64.f64 d3, d12", 1, 6)
-GEN_TWOVEC_QDS_TEST(vrintrne_f64_f64, "vrintrne.f64.f64 d4, d13", 2, 6)
-GEN_TWOVEC_QDS_TEST(vrintral_f64_f64, "vrintral.f64.f64 d5, d14", 2, 7)
-
-GEN_TWOVEC_QDS_TEST(vrintxeq_f64_f64, "vrintxeq.f64.f64 d6, d15", 3, 7)
-GEN_TWOVEC_QDS_TEST(vrintxne_f64_f64, "vrintxne.f64.f64 d7, d16", 3, 8)
-GEN_TWOVEC_QDS_TEST(vrintxal_f64_f64, "vrintxal.f64.f64 d8, d8", 4, 4)
-
-GEN_TWOVEC_QDS_TEST(vrintzeq_f32_f32, "vrintzeq.f32.f32 s0, s9", 0, 2)
-GEN_TWOVEC_QDS_TEST(vrintzne_f32_f32, "vrintzne.f32.f32 s1, s10", 0, 2)
-GEN_TWOVEC_QDS_TEST(vrintzal_f32_f32, "vrintzal.f32.f32 s2, s11", 0, 2)
-
-GEN_TWOVEC_QDS_TEST(vrintreq_f32_f32, "vrintreq.f32.f32 s3, s12", 0, 3)
-GEN_TWOVEC_QDS_TEST(vrintrne_f32_f32, "vrintrne.f32.f32 s4, s13", 1, 3)
-GEN_TWOVEC_QDS_TEST(vrintral_f32_f32, "vrintral.f32.f32 s5, s14", 1, 3)
-
-GEN_TWOVEC_QDS_TEST(vrintxeq_f32_f32, "vrintxeq.f32.f32 s6, s15", 1, 3)
-GEN_TWOVEC_QDS_TEST(vrintxne_f32_f32, "vrintxne.f32.f32 s7, s16", 1, 4)
-GEN_TWOVEC_QDS_TEST(vrintxal_f32_f32, "vrintxal.f32.f32 s8, s8", 2, 2)
-
-GEN_TWOVEC_QDS_TEST(vrintn_f64_f64, "vrintn.f64.f64 d3, d15", 1, 7)
-GEN_TWOVEC_QDS_TEST(vrinta_f64_f64, "vrinta.f64.f64 d6, d18", 3, 9)
-GEN_TWOVEC_QDS_TEST(vrintp_f64_f64, "vrintp.f64.f64 d9, d21", 4, 10)
-GEN_TWOVEC_QDS_TEST(vrintm_f64_f64, "vrintm.f64.f64 d12, d12", 6, 6)
-
-GEN_TWOVEC_QDS_TEST(vrintn_f32_f32, "vrintn.f32.f32 s3, s15", 0, 3)
-GEN_TWOVEC_QDS_TEST(vrinta_f32_f32, "vrinta.f32.f32 s6, s18", 1, 4)
-GEN_TWOVEC_QDS_TEST(vrintp_f32_f32, "vrintp.f32.f32 s9, s21", 2, 5)
-GEN_TWOVEC_QDS_TEST(vrintm_f32_f32, "vrintm.f32.f32 s12, s12", 3, 3)
-
-GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec64, "vmaxnm.f32 d15,d16,d20", 7,8,10)
-GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec128, "vmaxnm.f32 q7, q8, q10", 7,8,10)
-
-GEN_THREEVEC_QDS_TEST(vminnm_f32_vec64, "vminnm.f32 d15,d16,d20", 7,8,10)
-GEN_THREEVEC_QDS_TEST(vminnm_f32_vec128, "vminnm.f32 q7, q8, q10", 7,8,10)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec64, "vcvtn.s32.f32 d0, d20", 0, 10)
-GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec64, "vcvta.s32.f32 d5, d25", 2, 12)
-GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec64, "vcvtp.s32.f32 d10, d30", 5, 15)
-GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec64, "vcvtm.s32.f32 d15, d15", 7, 7)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec128, "vcvtn.s32.f32 q15, q0", 15, 0)
-GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec128, "vcvta.s32.f32 q14, q1", 14, 1)
-GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec128, "vcvtp.s32.f32 q13, q2", 13, 2)
-GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec128, "vcvtm.s32.f32 q12, q3", 12, 3)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec64, "vcvtn.u32.f32 d0, d20", 0, 10)
-GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec64, "vcvta.u32.f32 d5, d25", 2, 12)
-GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec64, "vcvtp.u32.f32 d10, d30", 5, 15)
-GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec64, "vcvtm.u32.f32 d15, d15", 7, 7)
-
-GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec128, "vcvtn.u32.f32 q15, q0", 15, 0)
-GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec128, "vcvta.u32.f32 q14, q1", 14, 1)
-GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec128, "vcvtp.u32.f32 q13, q2", 13, 2)
-GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec128, "vcvtm.u32.f32 q12, q3", 12, 3)
-
-GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec64, "vrintn.f32.f32 d0, d18", 0, 9)
-GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec64, "vrinta.f32.f32 d3, d21", 1, 10)
-GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec64, "vrintp.f32.f32 d6, d24", 3, 12)
-GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec64, "vrintm.f32.f32 d9, d27", 4, 13)
-GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec64, "vrintz.f32.f32 d12, d30", 6, 15)
-GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec64, "vrintx.f32.f32 d15, d15", 7, 7)
-
-GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec128, "vrintn.f32.f32 q0, q2", 0, 2)
-GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec128, "vrinta.f32.f32 q3, q5", 3, 5)
-GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec128, "vrintp.f32.f32 q6, q8", 6, 8)
-GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec128, "vrintm.f32.f32 q9, q11", 9, 11)
-GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec128, "vrintz.f32.f32 q12, q14", 12, 14)
-GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec128, "vrintx.f32.f32 q15, q15", 15, 15)
+GEN_THREEVEC_QDS_TEST(vselvs_f32, IT_AL, "vselvs.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselvs_f64, IT_AL, "vselvs.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32, IT_AL, "vmaxnm.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vmaxnm_f64, IT_AL, "vmaxnm.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vminnm_f32, IT_AL, "vminnm.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vminnm_f64, IT_AL, "vminnm.f64 d7, d8, d10", 3,4,5)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f64, IT_AL, "vcvtn.s32.f64 s27, d5", 6,2)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f64, IT_AL, "vcvta.s32.f64 s4, d20", 1,10)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f64, IT_AL, "vcvtp.s32.f64 s7, d31", 1,15)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f64, IT_AL, "vcvtm.s32.f64 s1, d0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32, IT_AL, "vcvtn.s32.f32 s27, s5", 6,1)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32, IT_AL, "vcvta.s32.f32 s4, s20", 1,5)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32, IT_AL, "vcvtp.s32.f32 s7, s31", 1,7)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32, IT_AL, "vcvtm.s32.f32 s1, s0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f64, IT_AL, "vcvtn.u32.f64 s27, d5", 6,2)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f64, IT_AL, "vcvta.u32.f64 s4, d20", 1,10)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f64, IT_AL, "vcvtp.u32.f64 s7, d31", 1,15)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f64, IT_AL, "vcvtm.u32.f64 s1, d0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32, IT_AL, "vcvtn.u32.f32 s27, s5", 6,1)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32, IT_AL, "vcvta.u32.f32 s4, s20", 1,5)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32, IT_AL, "vcvtp.u32.f32 s7, s31", 1,7)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32, IT_AL, "vcvtm.u32.f32 s1, s0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtb_f64_f16, IT_AL, "vcvtb.f64.f16 d27, s18", 13, 4)
+GEN_TWOVEC_QDS_TEST(vcvtt_f64_f16, IT_AL, "vcvtt.f64.f16 d28, s17", 14, 4)
+
+GEN_TWOVEC_QDS_TEST(vcvtb_f16_f64, IT_AL, "vcvtb.f16.f64 s9, d17", 2, 8)
+GEN_TWOVEC_QDS_TEST(vcvtt_f16_f64, IT_AL, "vcvtt.f16.f64 s8, d27", 2, 13)
+
+GEN_TWOVEC_QDS_TEST(vrintzeq_f64_f64, IT_EQ, "vrintzeq.f64.f64 d0, d9", 0, 4)
+GEN_TWOVEC_QDS_TEST(vrintzne_f64_f64, IT_NE, "vrintzne.f64.f64 d1, d10", 0, 5)
+GEN_TWOVEC_QDS_TEST(vrintzal_f64_f64, IT_AL, "vrintz.f64.f64 d2, d11", 1, 5)
+
+GEN_TWOVEC_QDS_TEST(vrintreq_f64_f64, IT_EQ, "vrintreq.f64.f64 d3, d12", 1, 6)
+GEN_TWOVEC_QDS_TEST(vrintrne_f64_f64, IT_NE, "vrintrne.f64.f64 d4, d13", 2, 6)
+GEN_TWOVEC_QDS_TEST(vrintral_f64_f64, IT_AL, "vrintr.f64.f64 d5, d14", 2, 7)
+
+GEN_TWOVEC_QDS_TEST(vrintxeq_f64_f64, IT_EQ, "vrintxeq.f64.f64 d6, d15", 3, 7)
+GEN_TWOVEC_QDS_TEST(vrintxne_f64_f64, IT_NE, "vrintxne.f64.f64 d7, d16", 3, 8)
+GEN_TWOVEC_QDS_TEST(vrintxal_f64_f64, IT_AL, "vrintx.f64.f64 d8, d8", 4, 4)
+
+GEN_TWOVEC_QDS_TEST(vrintzeq_f32_f32, IT_EQ, "vrintzeq.f32.f32 s0, s9", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrintzne_f32_f32, IT_NE, "vrintzne.f32.f32 s1, s10", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrintzal_f32_f32, IT_AL, "vrintz.f32.f32 s2, s11", 0, 2)
+
+GEN_TWOVEC_QDS_TEST(vrintreq_f32_f32, IT_EQ, "vrintreq.f32.f32 s3, s12", 0, 3)
+GEN_TWOVEC_QDS_TEST(vrintrne_f32_f32, IT_NE, "vrintrne.f32.f32 s4, s13", 1, 3)
+GEN_TWOVEC_QDS_TEST(vrintral_f32_f32, IT_AL, "vrintr.f32.f32 s5, s14", 1, 3)
+
+GEN_TWOVEC_QDS_TEST(vrintxeq_f32_f32, IT_EQ, "vrintxeq.f32.f32 s6, s15", 1, 3)
+GEN_TWOVEC_QDS_TEST(vrintxne_f32_f32, IT_NE, "vrintxne.f32.f32 s7, s16", 1, 4)
+GEN_TWOVEC_QDS_TEST(vrintxal_f32_f32, IT_AL, "vrintx.f32.f32 s8, s8", 2, 2)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f64_f64, IT_AL, "vrintn.f64.f64 d3, d15", 1, 7)
+GEN_TWOVEC_QDS_TEST(vrinta_f64_f64, IT_AL, "vrinta.f64.f64 d6, d18", 3, 9)
+GEN_TWOVEC_QDS_TEST(vrintp_f64_f64, IT_AL, "vrintp.f64.f64 d9, d21", 4, 10)
+GEN_TWOVEC_QDS_TEST(vrintm_f64_f64, IT_AL, "vrintm.f64.f64 d12, d12", 6, 6)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32, IT_AL, "vrintn.f32.f32 s3, s15", 0, 3)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32, IT_AL, "vrinta.f32.f32 s6, s18", 1, 4)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32, IT_AL, "vrintp.f32.f32 s9, s21", 2, 5)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32, IT_AL, "vrintm.f32.f32 s12, s12", 3, 3)
+
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec64,
+ IT_AL, "vmaxnm.f32 d15,d16,d20", 7,8,10)
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec128,
+ IT_AL, "vmaxnm.f32 q7, q8, q10", 7,8,10)
+
+GEN_THREEVEC_QDS_TEST(vminnm_f32_vec64,
+ IT_AL, "vminnm.f32 d15,d16,d20", 7,8,10)
+GEN_THREEVEC_QDS_TEST(vminnm_f32_vec128,
+ IT_AL, "vminnm.f32 q7, q8, q10", 7,8,10)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec64,
+ IT_AL, "vcvtn.s32.f32 d0, d20", 0, 10)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec64,
+ IT_AL, "vcvta.s32.f32 d5, d25", 2, 12)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec64,
+ IT_AL, "vcvtp.s32.f32 d10, d30", 5, 15)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec64,
+ IT_AL, "vcvtm.s32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec128,
+ IT_AL, "vcvtn.s32.f32 q15, q0", 15, 0)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec128,
+ IT_AL, "vcvta.s32.f32 q14, q1", 14, 1)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec128,
+ IT_AL, "vcvtp.s32.f32 q13, q2", 13, 2)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec128,
+ IT_AL, "vcvtm.s32.f32 q12, q3", 12, 3)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec64,
+ IT_AL, "vcvtn.u32.f32 d0, d20", 0, 10)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec64,
+ IT_AL, "vcvta.u32.f32 d5, d25", 2, 12)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec64,
+ IT_AL, "vcvtp.u32.f32 d10, d30", 5, 15)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec64,
+ IT_AL, "vcvtm.u32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec128,
+ IT_AL, "vcvtn.u32.f32 q15, q0", 15, 0)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec128,
+ IT_AL, "vcvta.u32.f32 q14, q1", 14, 1)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec128,
+ IT_AL, "vcvtp.u32.f32 q13, q2", 13, 2)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec128,
+ IT_AL, "vcvtm.u32.f32 q12, q3", 12, 3)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec64,
+ IT_AL, "vrintn.f32.f32 d0, d18", 0, 9)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec64,
+ IT_AL, "vrinta.f32.f32 d3, d21", 1, 10)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec64,
+ IT_AL, "vrintp.f32.f32 d6, d24", 3, 12)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec64,
+ IT_AL, "vrintm.f32.f32 d9, d27", 4, 13)
+GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec64,
+ IT_AL, "vrintz.f32.f32 d12, d30", 6, 15)
+GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec64,
+ IT_AL, "vrintx.f32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec128,
+ IT_AL, "vrintn.f32.f32 q0, q2", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec128,
+ IT_AL, "vrinta.f32.f32 q3, q5", 3, 5)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec128,
+ IT_AL, "vrintp.f32.f32 q6, q8", 6, 8)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec128,
+ IT_AL, "vrintm.f32.f32 q9, q11", 9, 11)
+GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec128,
+ IT_AL, "vrintz.f32.f32 q12, q14", 12, 14)
+GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec128,
+ IT_AL, "vrintx.f32.f32 q15, q15", 15, 15)
int main ( void )
{
|
|
From: <sv...@va...> - 2017-01-11 21:17:49
|
Author: iraisr
Date: Wed Jan 11 21:17:42 2017
New Revision: 16197
Log:
Fix comments in m_trampoline.S for amd64/Solaris redirs.
Modified:
trunk/coregrind/m_trampoline.S
Modified: trunk/coregrind/m_trampoline.S
==============================================================================
--- trunk/coregrind/m_trampoline.S (original)
+++ trunk/coregrind/m_trampoline.S Wed Jan 11 21:17:42 2017
@@ -1527,7 +1527,7 @@
movq %rdi, %rdx /* copy s1 */
1:
movzbl (%rsi), %eax /* load one input character */
- movb %al, (%rdx) /* copy to output/s2 */
+ movb %al, (%rdx) /* copy to output/s1 */
incq %rsi /* skip to the next output character */
incq %rdx /* skip to the next input character */
testb %al, %al /* is the copied character null? */
@@ -1548,7 +1548,7 @@
testq %rdx, %rdx /* is the remaining size zero? */
jz 3f /* yes, all done */
movzbl (%rsi), %eax /* load one input character */
- movb %al, (%rcx) /* copy to output/s2 */
+ movb %al, (%rcx) /* copy to output/s1 */
decq %rdx /* decrement the remaining size */
incq %rsi /* skip to the next output character */
incq %rcx /* skip to the next input character */
|
|
From: <sv...@va...> - 2017-01-10 20:21:29
|
Author: weidendo
Date: Tue Jan 10 20:21:21 2017
New Revision: 16196
Log:
Add a format marker to callgrind files
KCachegrind currently uses a quick format detection before
actually loading a file, and checks for a line starting with
"events:" in the first 2kB for that. This obviously is fragile,
as shown by an internal bug report by Philippe: before the
"events" line, Callgrind puts a "cmd:" line with the command
line. If this is very long, the detection fails and the file
does not get loaded at all.
While KCachegrind would not need to have this quick format
check at all, it is useful if multiple input format filters
get supported at some point, to automatically select the
correct filter.
Further, for the "file" command, for file managers and
desktop environments, having an unique way to detect a
file format is important.
It is not too late to fix this issue for the callgrind format.
Modified:
trunk/NEWS
trunk/callgrind/docs/cl-format.xml
trunk/callgrind/dump.c
trunk/coregrind/m_xtree.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Tue Jan 10 20:21:21 2017
@@ -63,6 +63,11 @@
are caused by the inner guest program (such as an inner regtest).
See README_DEVELOPERS for more info.
+* To allow fast detection of callgrind files in desktop environments
+ and file managers, the format was extended to have an optional
+ first line uniquely identifying the format ("# callgrind format").
+ Callgrind creates this line now (also the new xtree functionality).
+
* ==================== FIXED BUGS ====================
The following bugs have been fixed or resolved. Note that "n-i-bz"
Modified: trunk/callgrind/docs/cl-format.xml
==============================================================================
--- trunk/callgrind/docs/cl-format.xml (original)
+++ trunk/callgrind/docs/cl-format.xml Tue Jan 10 20:21:21 2017
@@ -6,10 +6,7 @@
<chapter id="cl-format" xreflabel="Callgrind Format Specification">
<title>Callgrind Format Specification</title>
-<para>This chapter describes the Callgrind Profile Format, Version 1.</para>
-
-<para>A synonymous name is "Calltree Profile Format". These names actually mean
-the same since Callgrind was previously named Calltree.</para>
+<para>This chapter describes the Callgrind Format, Version 1.</para>
<para>The format description is meant for the user to be able to understand the
file contents; but more important, it is given for authors of measurement or
@@ -29,6 +26,10 @@
<sect2 id="cl-format.overview.basics" xreflabel="Basic Structure">
<title>Basic Structure</title>
+<para>To uniquely specify that a file is a callgrind profile, it
+should add "# callgrind format" as first line. This is optional but
+recommended for easy format detection.</para>
+
<para>Each file has a header part of an arbitrary number of lines of the
format "key: value". After the header, lines specifying profile costs
follow. Everywhere, comments on own lines starting with '#' are allowed.
@@ -58,7 +59,8 @@
However, any profiling tool could use the format described in this chapter.</para>
<para>
-<screen>events: Cycles Instructions Flops
+<screen># callgrind format
+events: Cycles Instructions Flops
fl=file.f
fn=main
15 90 14 2
@@ -130,7 +132,9 @@
<function>main</function> calls <function>func1</function> once and
<function>func2</function> 3 times. <function>func1</function> calls
<function>func2</function> 2 times.
-<screen>events: Instructions
+
+<screen># callgrind format
+events: Instructions
fl=file1.c
fn=main
@@ -186,8 +190,9 @@
mapping. There is a separate ID mapping for each position specification,
i.e. you can use ID 1 for both a file name and a symbol name.</para>
-<para>With string compression, the example from 1.4 looks like this:
-<screen>events: Instructions
+<para>With string compression, the example from above looks like this:
+<screen># callgrind format
+events: Instructions
fl=(1) file1.c
fn=(1) main
@@ -216,7 +221,8 @@
everywhere in the file without any negative consequence. Especially, you can
define name compression mappings directly after the header, and before any cost
lines. Thus, the above example can also be written as
-<screen>events: Instructions
+<screen># callgrind format
+events: Instructions
# define file ID mapping
fl=(1) file1.c
@@ -256,7 +262,8 @@
absolute and relative subposition specifications can be mixed freely.
Assume the following example (subpositions can always be specified
as hexadecimal numbers, beginning with "0x"):
-<screen>positions: instr line
+<screen># callgrind format
+positions: instr line
events: ticks
fn=func
@@ -265,7 +272,8 @@
0x80001238 91 6</screen></para>
<para>With subposition compression, this looks like
-<screen>positions: instr line
+<screen># callgrind format
+positions: instr line
events: ticks
fn=func
@@ -326,7 +334,8 @@
<title>Grammar</title>
<para>
-<screen>ProfileDataFile := FormatVersion? Creator? PartData*</screen>
+<screen>ProfileDataFile := FormatSpec? FormatVersion? Creator? PartData*</screen>
+<screen>FormatSpec := "# callgrind format\n"</screen>
<screen>FormatVersion := "version: 1\n"</screen>
<screen>Creator := "creator:" NoNewLineChar* "\n"</screen>
<screen>PartData := (HeaderLine "\n")+ (BodyLine "\n")+</screen>
@@ -379,7 +388,7 @@
</para>
<para>A profile data file ("ProfileDataFile") starts with basic information
- such as the version and creator information, and then has a list of parts, where
+ such as a format marker, the version and creator information, and then has a list of parts, where
each part has its own header and body. Parts typically are different threads
and/or time spans/phases within a profiled application run.</para>
@@ -396,11 +405,23 @@
<itemizedlist>
<listitem>
+ <para><computeroutput># callgrind format</computeroutput> [Callgrind]</para>
+ <para>This line specifies that the file is a callgrind profile,
+ and it has to be the first line. It was added late to the
+ format (with Valgrind 3.13) and is optional, as all readers also
+ should work with older callgrind profiles not including this line.
+ However, generation of this line is recommended to allow desktop
+ environments and file managers to uniquely detect the format.</para>
+ </listitem>
+
+ <listitem>
<para><computeroutput>version: number</computeroutput> [Callgrind]</para>
<para>This is used to distinguish future profile data formats. A
major version of 0 or 1 is supposed to be upwards compatible with
Cachegrind's format. It is optional; if not appearing, version 1
- is assumed. Otherwise, this has to be the first header line.</para>
+ is assumed. Otherwise, it has to follow directly after the format
+ specification (i.e. be the first line if the optional format
+ specification is skipped).</para>
</listitem>
<listitem>
Modified: trunk/callgrind/dump.c
==============================================================================
--- trunk/callgrind/dump.c (original)
+++ trunk/callgrind/dump.c Tue Jan 10 20:21:21 2017
@@ -1215,6 +1215,9 @@
if (!appending) {
+ /* callgrind format specification, has to be on 1st line */
+ VG_(fprintf)(fp, "# callgrind format\n");
+
/* version */
VG_(fprintf)(fp, "version: 1\n");
Modified: trunk/coregrind/m_xtree.c
==============================================================================
--- trunk/coregrind/m_xtree.c (original)
+++ trunk/coregrind/m_xtree.c Tue Jan 10 20:21:21 2017
@@ -442,6 +442,7 @@
filename_ddpa = VG_(newDedupPA)(16000, 1, xt->alloc_fn,
"XT_callgrind_print.fl", xt->free_fn);
+ FP("# callgrind format\n");
FP("version: 1\n");
FP("creator: xtree-1\n");
FP("pid: %d\n", VG_(getpid)());
|
|
From: <sv...@va...> - 2017-01-10 18:07:14
|
Author: philippe
Date: Tue Jan 10 18:07:07 2017
New Revision: 16195
Log:
xtree: CALLED_FLF must be called only up to ips[0] + minor doc update
Modified:
trunk/coregrind/m_xtree.c
trunk/docs/xml/manual-core.xml
Modified: trunk/coregrind/m_xtree.c
==============================================================================
--- trunk/coregrind/m_xtree.c (original)
+++ trunk/coregrind/m_xtree.c Tue Jan 10 18:07:07 2017
@@ -546,8 +546,8 @@
else
FP("%d\n", called_linenum); //no self cost.
prev_linenum = called_linenum;
- CALLED_FLF(ips_idx-1);
if (ips_idx >= 1) {
+ CALLED_FLF(ips_idx-1);
FP_pos_str(fp, "cfi", called_filename_nr,
called_filename, called_filename_new);
FP_pos_str(fp, "cfn", called_fnname_nr,
Modified: trunk/docs/xml/manual-core.xml
==============================================================================
--- trunk/docs/xml/manual-core.xml (original)
+++ trunk/docs/xml/manual-core.xml Tue Jan 10 18:07:07 2017
@@ -2858,11 +2858,15 @@
</itemizedlist>
-<para>Note that the Callgrind Format is more compact than the Massif Format,
- and contains the full data : there is no filtering during file production,
- filtering is done by visualisers such as kcachegrind. kcachegrind is
- particularly easy to use to analyse big xtree data containing multiple
- events counts or resources consumption.</para>
+<para>Note that for equivalent information, the Callgrind Format is more compact
+ than the Massif Format. However, the Callgrind Format always contains the
+ full data: there is no filtering done during file production, filtering is
+ done by visualisers such as kcachegrind. kcachegrind is particularly easy to
+ use to analyse big xtree data containing multiple events counts or resources
+ consumption. The Massif Format (optionally) only contains a part of the data.
+ For example, the Massif tool might filter some of the data, according to the
+ <option>--threshold</option> option.
+</para>
<para>To clarify the xtree concept, the below gives several extracts of
the output produced by the following commands:
|
|
From: <sv...@va...> - 2017-01-10 16:10:01
|
Author: sewardj
Date: Tue Jan 10 16:09:53 2017
New Revision: 16194
Log:
Add test cases for 32-bit v8 FP and SIMD insns.
Added:
trunk/none/tests/arm/v8fpsimd_a.c
Added: trunk/none/tests/arm/v8fpsimd_a.c
==============================================================================
--- trunk/none/tests/arm/v8fpsimd_a.c (added)
+++ trunk/none/tests/arm/v8fpsimd_a.c Tue Jan 10 16:09:53 2017
@@ -0,0 +1,485 @@
+
+/*
+gcc -o v8fpsimd_a v8fpsimd_a.c -march=armv8-a -mfpu=crypto-neon-fp-armv8 \
+ -I../../.. -Wall -g -marm
+*/
+
+#include <stdio.h>
+#include <assert.h>
+#include <malloc.h> // memalign
+#include <string.h> // memset
+#include "tests/malloc.h"
+#include <math.h> // isnormal
+
+typedef unsigned char UChar;
+typedef unsigned short int UShort;
+typedef unsigned int UInt;
+typedef signed int Int;
+typedef unsigned char UChar;
+typedef unsigned long long int ULong;
+typedef signed long long int Long;
+typedef double Double;
+typedef float Float;
+
+typedef unsigned char Bool;
+#define False ((Bool)0)
+#define True ((Bool)1)
+
+
+#define ITERS 1
+
+typedef
+ enum { TyHF=1234, TySF, TyDF, TyB, TyH, TyS, TyD, TyNONE }
+ LaneTy;
+
+union _V128 {
+ UChar u8[16];
+ UShort u16[8];
+ UInt u32[4];
+ ULong u64[2];
+ Float f32[4];
+ Double f64[2];
+};
+typedef union _V128 V128;
+
+static inline UChar randUChar ( void )
+{
+ static UInt seed = 80021;
+ seed = 1103515245 * seed + 12345;
+ return (seed >> 17) & 0xFF;
+}
+
+//static ULong randULong ( LaneTy ty )
+//{
+// Int i;
+// ULong r = 0;
+// for (i = 0; i < 8; i++) {
+// r = (r << 8) | (ULong)(0xFF & randUChar());
+// }
+// return r;
+//}
+
+/* Generates a random V128. Ensures that that it contains normalised
+ FP numbers when viewed as either F32x4 or F64x2, so that it is
+ reasonable to use in FP test cases. */
+static void randV128 ( /*OUT*/V128* v, LaneTy ty )
+{
+ static UInt nCalls = 0, nIters = 0;
+ Int i;
+ nCalls++;
+ while (1) {
+ nIters++;
+ for (i = 0; i < 16; i++) {
+ v->u8[i] = randUChar();
+ }
+ if (randUChar() < 32) {
+ /* once every 8 times, clone one of the lanes */
+ switch (ty) {
+ case TySF: case TyS: {
+ UInt l1, l2;
+ while (1) {
+ l1 = randUChar() & 3;
+ l2 = randUChar() & 3;
+ if (l1 != l2) break;
+ }
+ assert(l1 < 4 && l2 < 4);
+ v->u32[l1] = v->u32[l2];
+ printf("randV128: doing v->u32[%u] = v->u32[%u]\n", l1, l2);
+ break;
+ }
+ case TyDF: case TyD: {
+ UInt l1, l2;
+ while (1) {
+ l1 = randUChar() & 1;
+ l2 = randUChar() & 1;
+ if (l1 != l2) break;
+ }
+ assert(l1 < 2 && l2 < 2);
+ printf("randV128: doing v->u64[%u] = v->u64[%u]\n", l1, l2);
+ v->u64[l1] = v->u64[l2];
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (isnormal(v->f32[0]) && isnormal(v->f32[1]) && isnormal(v->f32[2])
+ && isnormal(v->f32[3]) && isnormal(v->f64[0]) && isnormal(v->f64[1]))
+ break;
+ }
+ if (0 == (nCalls & 0xFF))
+ printf("randV128: %u calls, %u iters\n", nCalls, nIters);
+}
+
+static void showV128 ( V128* v )
+{
+ Int i;
+ for (i = 15; i >= 0; i--)
+ printf("%02x", (Int)v->u8[i]);
+}
+
+//static void showBlock ( const char* msg, V128* block, Int nBlock )
+//{
+// Int i;
+// printf("%s\n", msg);
+// for (i = 0; i < nBlock; i++) {
+// printf(" ");
+// showV128(&block[i]);
+// printf("\n");
+// }
+//}
+
+
+/* ---------------------------------------------------------------- */
+/* -- Parameterisable test macros -- */
+/* ---------------------------------------------------------------- */
+
+#define DO50(_action) \
+ do { \
+ Int _qq; for (_qq = 0; _qq < 50; _qq++) { _action ; } \
+ } while (0)
+
+
+/* Generate a test that involves two vector regs,
+ with no bias as towards which is input or output.
+ It's OK to use r8 as scratch.
+
+ Note that the insn doesn't *have* to use Q (128 bit) registers --
+ it can instead mention D (64 bit) and S (32-bit) registers.
+ However, in that case callers of this macro must be very careful to
+ specify QVECREG1NO and QVECREG2NO in such a way as to cover all of
+ the mentioned D and S registers, using the relations
+
+ D<n> == S<2n+1> and S<2n>
+ Q<n> == D<2n+1> and D<2n>
+
+ Failing to do so correctly will make the test meaningless, because
+ it will potentially load test data into the wrong registers before
+ the test, and/or show the values of the wrong registers after the
+ test. The allowed register values are:
+ S: 0 .. 31
+ D: 0 .. 31
+ Q: 0 .. 15
+ Note that Q[15..0] == D[31..0] but S[31..0] only overlaps Q[0..7],
+ so a Q value of 8 or above is definitely invalid for a S register.
+ None of this is checked, though, so be careful when creating the
+ Q numbers.
+*/
+#define GEN_TWOVEC_QDS_TEST(TESTNAME,INSN,QVECREG1NO,QVECREG2NO) \
+ __attribute__((noinline)) \
+ static void test_##TESTNAME ( LaneTy ty ) { \
+ Int i; \
+ assert(QVECREG1NO >= 0 && QVECREG1NO <= 15); \
+ assert(QVECREG2NO >= 0 && QVECREG2NO <= 15); \
+ for (i = 0; i < ITERS; i++) { \
+ V128 block[4+1]; \
+ memset(block, 0x55, sizeof(block)); \
+ randV128(&block[0], ty); \
+ randV128(&block[1], ty); \
+ randV128(&block[2], ty); \
+ randV128(&block[3], ty); \
+ __asm__ __volatile__( \
+ "mov r9, #0 ; vmsr fpscr, r9 ; " \
+ "add r9, %0, #0 ; vld1.8 { q"#QVECREG1NO" }, [r9] ; " \
+ "add r9, %0, #16 ; vld1.8 { q"#QVECREG2NO" }, [r9] ; " \
+ INSN " ; " \
+ "add r9, %0, #32 ; vst1.8 { q"#QVECREG1NO" }, [r9] ; " \
+ "add r9, %0, #48 ; vst1.8 { q"#QVECREG2NO" }, [r9] ; " \
+ "vmrs r9, fpscr ; str r9, [%0, #64] " \
+ : : "r"(&block[0]) \
+ : "cc", "memory", "q"#QVECREG1NO, "q"#QVECREG2NO, "r8", "r9" \
+ ); \
+ printf(INSN " "); \
+ UInt fpscr = 0xFFFFFFFF & block[4].u32[0]; \
+ showV128(&block[0]); printf(" "); \
+ showV128(&block[1]); printf(" "); \
+ showV128(&block[2]); printf(" "); \
+ showV128(&block[3]); printf(" fpscr=%08x\n", fpscr); \
+ } \
+ }
+
+
+/* Generate a test that involves three vector regs,
+ with no bias as towards which is input or output. It's also OK
+ to use r8 as scratch. */
+#define GEN_THREEVEC_QDS_TEST(TESTNAME,INSN,QVECREG1NO,QVECREG2NO,QVECREG3NO) \
+ __attribute__((noinline)) \
+ static void test_##TESTNAME ( LaneTy ty ) { \
+ Int i; \
+ assert(QVECREG1NO >= 0 && QVECREG1NO <= 15); \
+ assert(QVECREG2NO >= 0 && QVECREG2NO <= 15); \
+ assert(QVECREG3NO >= 0 && QVECREG3NO <= 15); \
+ for (i = 0; i < ITERS; i++) { \
+ V128 block[6+1]; \
+ memset(block, 0x55, sizeof(block)); \
+ randV128(&block[0], ty); \
+ randV128(&block[1], ty); \
+ randV128(&block[2], ty); \
+ randV128(&block[3], ty); \
+ randV128(&block[4], ty); \
+ randV128(&block[5], ty); \
+ __asm__ __volatile__( \
+ "mov r9, #0 ; vmsr fpscr, r9 ; " \
+ "add r9, %0, #0 ; vld1.8 { q"#QVECREG1NO" }, [r9] ; " \
+ "add r9, %0, #16 ; vld1.8 { q"#QVECREG2NO" }, [r9] ; " \
+ "add r9, %0, #32 ; vld1.8 { q"#QVECREG3NO" }, [r9] ; " \
+ INSN " ; " \
+ "add r9, %0, #48 ; vst1.8 { q"#QVECREG1NO" }, [r9] ; " \
+ "add r9, %0, #64 ; vst1.8 { q"#QVECREG2NO" }, [r9] ; " \
+ "add r9, %0, #80 ; vst1.8 { q"#QVECREG3NO" }, [r9] ; " \
+ "vmrs r9, fpscr ; str r9, [%0, #96] " \
+ : : "r"(&block[0]) \
+ : "cc", "memory", "q"#QVECREG1NO, "q"#QVECREG2NO, "q"#QVECREG3NO, \
+ "r8", "r9" \
+ ); \
+ printf(INSN " "); \
+ UInt fpscr = 0xFFFFFFFF & block[6].u32[0]; \
+ showV128(&block[0]); printf(" "); \
+ showV128(&block[1]); printf(" "); \
+ showV128(&block[2]); printf(" "); \
+ showV128(&block[3]); printf(" "); \
+ showV128(&block[4]); printf(" "); \
+ showV128(&block[5]); printf(" fpscr=%08x\n", fpscr); \
+ } \
+ }
+
+GEN_THREEVEC_QDS_TEST(vselge_f32, "vselge.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselge_f64, "vselge.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vselgt_f32, "vselgt.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselgt_f64, "vselgt.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vseleq_f32, "vseleq.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vseleq_f64, "vseleq.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vselvs_f32, "vselvs.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vselvs_f64, "vselvs.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32, "vmaxnm.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vmaxnm_f64, "vmaxnm.f64 d7, d8, d10", 3,4,5)
+
+GEN_THREEVEC_QDS_TEST(vminnm_f32, "vminnm.f32 s15,s16,s20", 3,4,5)
+GEN_THREEVEC_QDS_TEST(vminnm_f64, "vminnm.f64 d7, d8, d10", 3,4,5)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f64, "vcvtn.s32.f64 s27, d5", 6,2)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f64, "vcvta.s32.f64 s4, d20", 1,10)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f64, "vcvtp.s32.f64 s7, d31", 1,15)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f64, "vcvtm.s32.f64 s1, d0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32, "vcvtn.s32.f32 s27, s5", 6,1)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32, "vcvta.s32.f32 s4, s20", 1,5)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32, "vcvtp.s32.f32 s7, s31", 1,7)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32, "vcvtm.s32.f32 s1, s0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f64, "vcvtn.u32.f64 s27, d5", 6,2)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f64, "vcvta.u32.f64 s4, d20", 1,10)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f64, "vcvtp.u32.f64 s7, d31", 1,15)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f64, "vcvtm.u32.f64 s1, d0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32, "vcvtn.u32.f32 s27, s5", 6,1)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32, "vcvta.u32.f32 s4, s20", 1,5)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32, "vcvtp.u32.f32 s7, s31", 1,7)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32, "vcvtm.u32.f32 s1, s0", 0,0)
+
+GEN_TWOVEC_QDS_TEST(vcvtb_f64_f16, "vcvtb.f64.f16 d27, s18", 13, 4)
+GEN_TWOVEC_QDS_TEST(vcvtt_f64_f16, "vcvtt.f64.f16 d28, s17", 14, 4)
+
+GEN_TWOVEC_QDS_TEST(vcvtb_f16_f64, "vcvtb.f16.f64 s9, d17", 2, 8)
+GEN_TWOVEC_QDS_TEST(vcvtt_f16_f64, "vcvtt.f16.f64 s8, d27", 2, 13)
+
+GEN_TWOVEC_QDS_TEST(vrintzeq_f64_f64, "vrintzeq.f64.f64 d0, d9", 0, 4)
+GEN_TWOVEC_QDS_TEST(vrintzne_f64_f64, "vrintzne.f64.f64 d1, d10", 0, 5)
+GEN_TWOVEC_QDS_TEST(vrintzal_f64_f64, "vrintzal.f64.f64 d2, d11", 1, 5)
+
+GEN_TWOVEC_QDS_TEST(vrintreq_f64_f64, "vrintreq.f64.f64 d3, d12", 1, 6)
+GEN_TWOVEC_QDS_TEST(vrintrne_f64_f64, "vrintrne.f64.f64 d4, d13", 2, 6)
+GEN_TWOVEC_QDS_TEST(vrintral_f64_f64, "vrintral.f64.f64 d5, d14", 2, 7)
+
+GEN_TWOVEC_QDS_TEST(vrintxeq_f64_f64, "vrintxeq.f64.f64 d6, d15", 3, 7)
+GEN_TWOVEC_QDS_TEST(vrintxne_f64_f64, "vrintxne.f64.f64 d7, d16", 3, 8)
+GEN_TWOVEC_QDS_TEST(vrintxal_f64_f64, "vrintxal.f64.f64 d8, d8", 4, 4)
+
+GEN_TWOVEC_QDS_TEST(vrintzeq_f32_f32, "vrintzeq.f32.f32 s0, s9", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrintzne_f32_f32, "vrintzne.f32.f32 s1, s10", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrintzal_f32_f32, "vrintzal.f32.f32 s2, s11", 0, 2)
+
+GEN_TWOVEC_QDS_TEST(vrintreq_f32_f32, "vrintreq.f32.f32 s3, s12", 0, 3)
+GEN_TWOVEC_QDS_TEST(vrintrne_f32_f32, "vrintrne.f32.f32 s4, s13", 1, 3)
+GEN_TWOVEC_QDS_TEST(vrintral_f32_f32, "vrintral.f32.f32 s5, s14", 1, 3)
+
+GEN_TWOVEC_QDS_TEST(vrintxeq_f32_f32, "vrintxeq.f32.f32 s6, s15", 1, 3)
+GEN_TWOVEC_QDS_TEST(vrintxne_f32_f32, "vrintxne.f32.f32 s7, s16", 1, 4)
+GEN_TWOVEC_QDS_TEST(vrintxal_f32_f32, "vrintxal.f32.f32 s8, s8", 2, 2)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f64_f64, "vrintn.f64.f64 d3, d15", 1, 7)
+GEN_TWOVEC_QDS_TEST(vrinta_f64_f64, "vrinta.f64.f64 d6, d18", 3, 9)
+GEN_TWOVEC_QDS_TEST(vrintp_f64_f64, "vrintp.f64.f64 d9, d21", 4, 10)
+GEN_TWOVEC_QDS_TEST(vrintm_f64_f64, "vrintm.f64.f64 d12, d12", 6, 6)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32, "vrintn.f32.f32 s3, s15", 0, 3)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32, "vrinta.f32.f32 s6, s18", 1, 4)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32, "vrintp.f32.f32 s9, s21", 2, 5)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32, "vrintm.f32.f32 s12, s12", 3, 3)
+
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec64, "vmaxnm.f32 d15,d16,d20", 7,8,10)
+GEN_THREEVEC_QDS_TEST(vmaxnm_f32_vec128, "vmaxnm.f32 q7, q8, q10", 7,8,10)
+
+GEN_THREEVEC_QDS_TEST(vminnm_f32_vec64, "vminnm.f32 d15,d16,d20", 7,8,10)
+GEN_THREEVEC_QDS_TEST(vminnm_f32_vec128, "vminnm.f32 q7, q8, q10", 7,8,10)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec64, "vcvtn.s32.f32 d0, d20", 0, 10)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec64, "vcvta.s32.f32 d5, d25", 2, 12)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec64, "vcvtp.s32.f32 d10, d30", 5, 15)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec64, "vcvtm.s32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_s32_f32_vec128, "vcvtn.s32.f32 q15, q0", 15, 0)
+GEN_TWOVEC_QDS_TEST(vcvta_s32_f32_vec128, "vcvta.s32.f32 q14, q1", 14, 1)
+GEN_TWOVEC_QDS_TEST(vcvtp_s32_f32_vec128, "vcvtp.s32.f32 q13, q2", 13, 2)
+GEN_TWOVEC_QDS_TEST(vcvtm_s32_f32_vec128, "vcvtm.s32.f32 q12, q3", 12, 3)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec64, "vcvtn.u32.f32 d0, d20", 0, 10)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec64, "vcvta.u32.f32 d5, d25", 2, 12)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec64, "vcvtp.u32.f32 d10, d30", 5, 15)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec64, "vcvtm.u32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vcvtn_u32_f32_vec128, "vcvtn.u32.f32 q15, q0", 15, 0)
+GEN_TWOVEC_QDS_TEST(vcvta_u32_f32_vec128, "vcvta.u32.f32 q14, q1", 14, 1)
+GEN_TWOVEC_QDS_TEST(vcvtp_u32_f32_vec128, "vcvtp.u32.f32 q13, q2", 13, 2)
+GEN_TWOVEC_QDS_TEST(vcvtm_u32_f32_vec128, "vcvtm.u32.f32 q12, q3", 12, 3)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec64, "vrintn.f32.f32 d0, d18", 0, 9)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec64, "vrinta.f32.f32 d3, d21", 1, 10)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec64, "vrintp.f32.f32 d6, d24", 3, 12)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec64, "vrintm.f32.f32 d9, d27", 4, 13)
+GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec64, "vrintz.f32.f32 d12, d30", 6, 15)
+GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec64, "vrintx.f32.f32 d15, d15", 7, 7)
+
+GEN_TWOVEC_QDS_TEST(vrintn_f32_f32_vec128, "vrintn.f32.f32 q0, q2", 0, 2)
+GEN_TWOVEC_QDS_TEST(vrinta_f32_f32_vec128, "vrinta.f32.f32 q3, q5", 3, 5)
+GEN_TWOVEC_QDS_TEST(vrintp_f32_f32_vec128, "vrintp.f32.f32 q6, q8", 6, 8)
+GEN_TWOVEC_QDS_TEST(vrintm_f32_f32_vec128, "vrintm.f32.f32 q9, q11", 9, 11)
+GEN_TWOVEC_QDS_TEST(vrintz_f32_f32_vec128, "vrintz.f32.f32 q12, q14", 12, 14)
+GEN_TWOVEC_QDS_TEST(vrintx_f32_f32_vec128, "vrintx.f32.f32 q15, q15", 15, 15)
+
+int main ( void )
+{
+ if (1) DO50( test_vselge_f32(TySF) );
+ if (1) DO50( test_vselge_f64(TyDF) );
+
+ if (1) DO50( test_vselgt_f32(TySF) );
+ if (1) DO50( test_vselgt_f64(TyDF) );
+
+ if (1) DO50( test_vseleq_f32(TySF) );
+ if (1) DO50( test_vseleq_f64(TyDF) );
+
+ if (1) DO50( test_vselvs_f32(TySF) );
+ if (1) DO50( test_vselvs_f64(TyDF) );
+
+ if (1) DO50( test_vmaxnm_f32(TySF) );
+ if (1) DO50( test_vmaxnm_f64(TyDF) );
+
+ if (1) DO50( test_vminnm_f32(TySF) );
+ if (1) DO50( test_vminnm_f64(TyDF) );
+
+ if (1) DO50( test_vcvtn_s32_f64(TyDF) );
+ if (1) DO50( test_vcvta_s32_f64(TyDF) );
+ if (1) DO50( test_vcvtp_s32_f64(TyDF) );
+ if (1) DO50( test_vcvtm_s32_f64(TyDF) );
+
+ if (1) DO50( test_vcvtn_s32_f32(TySF) );
+ if (1) DO50( test_vcvta_s32_f32(TySF) );
+ if (1) DO50( test_vcvtp_s32_f32(TySF) );
+ if (1) DO50( test_vcvtm_s32_f32(TySF) );
+
+ if (1) DO50( test_vcvtn_u32_f64(TyDF) );
+ if (1) DO50( test_vcvta_u32_f64(TyDF) );
+ if (1) DO50( test_vcvtp_u32_f64(TyDF) );
+ if (1) DO50( test_vcvtm_u32_f64(TyDF) );
+
+ if (1) DO50( test_vcvtn_u32_f32(TySF) );
+ if (1) DO50( test_vcvta_u32_f32(TySF) );
+ if (1) DO50( test_vcvtp_u32_f32(TySF) );
+ if (1) DO50( test_vcvtm_u32_f32(TySF) );
+
+ if (1) DO50( test_vcvtb_f64_f16(TyDF) );
+ if (1) DO50( test_vcvtt_f64_f16(TyDF) );
+
+ if (1) DO50( test_vcvtb_f16_f64(TyHF) );
+ if (1) DO50( test_vcvtt_f16_f64(TyHF) );
+
+ if (1) DO50( test_vrintzeq_f64_f64(TyDF) );
+ if (1) DO50( test_vrintzne_f64_f64(TyDF) );
+ if (1) DO50( test_vrintzal_f64_f64(TyDF) );
+
+ if (1) DO50( test_vrintreq_f64_f64(TyDF) );
+ if (1) DO50( test_vrintrne_f64_f64(TyDF) );
+ if (1) DO50( test_vrintral_f64_f64(TyDF) );
+
+ if (1) DO50( test_vrintxeq_f64_f64(TyDF) );
+ if (1) DO50( test_vrintxne_f64_f64(TyDF) );
+ if (1) DO50( test_vrintxal_f64_f64(TyDF) );
+
+ if (1) DO50( test_vrintzeq_f32_f32(TySF) );
+ if (1) DO50( test_vrintzne_f32_f32(TySF) );
+ if (1) DO50( test_vrintzal_f32_f32(TySF) );
+
+ if (1) DO50( test_vrintreq_f32_f32(TySF) );
+ if (1) DO50( test_vrintrne_f32_f32(TySF) );
+ if (1) DO50( test_vrintral_f32_f32(TySF) );
+
+ if (1) DO50( test_vrintxeq_f32_f32(TySF) );
+ if (1) DO50( test_vrintxne_f32_f32(TySF) );
+ if (1) DO50( test_vrintxal_f32_f32(TySF) );
+
+ if (1) DO50( test_vrintn_f64_f64(TyDF) );
+ if (1) DO50( test_vrinta_f64_f64(TyDF) );
+ if (1) DO50( test_vrintp_f64_f64(TyDF) );
+ if (1) DO50( test_vrintm_f64_f64(TyDF) );
+
+ if (1) DO50( test_vrintn_f32_f32(TySF) );
+ if (1) DO50( test_vrinta_f32_f32(TySF) );
+ if (1) DO50( test_vrintp_f32_f32(TySF) );
+ if (1) DO50( test_vrintm_f32_f32(TySF) );
+
+ if (1) DO50( test_vmaxnm_f32_vec64(TySF) );
+ if (1) DO50( test_vmaxnm_f32_vec128(TySF) );
+
+ if (1) DO50( test_vminnm_f32_vec64(TySF) );
+ if (1) DO50( test_vminnm_f32_vec128(TySF) );
+
+ if (1) DO50( test_vcvtn_s32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvta_s32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvtp_s32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvtm_s32_f32_vec64(TySF) );
+
+ if (1) DO50( test_vcvtn_s32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvta_s32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvtp_s32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvtm_s32_f32_vec128(TySF) );
+
+ if (1) DO50( test_vcvtn_u32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvta_u32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvtp_u32_f32_vec64(TySF) );
+ if (1) DO50( test_vcvtm_u32_f32_vec64(TySF) );
+
+ if (1) DO50( test_vcvtn_u32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvta_u32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvtp_u32_f32_vec128(TySF) );
+ if (1) DO50( test_vcvtm_u32_f32_vec128(TySF) );
+
+ if (1) DO50( test_vrintn_f32_f32_vec64(TySF) );
+ if (1) DO50( test_vrinta_f32_f32_vec64(TySF) );
+ if (1) DO50( test_vrintp_f32_f32_vec64(TySF) );
+ if (1) DO50( test_vrintm_f32_f32_vec64(TySF) );
+ if (1) DO50( test_vrintz_f32_f32_vec64(TySF) );
+ if (1) DO50( test_vrintx_f32_f32_vec64(TySF) );
+
+ if (1) DO50( test_vrintn_f32_f32_vec128(TySF) );
+ if (1) DO50( test_vrinta_f32_f32_vec128(TySF) );
+ if (1) DO50( test_vrintp_f32_f32_vec128(TySF) );
+ if (1) DO50( test_vrintm_f32_f32_vec128(TySF) );
+ if (1) DO50( test_vrintz_f32_f32_vec128(TySF) );
+ if (1) DO50( test_vrintx_f32_f32_vec128(TySF) );
+
+ return 0;
+}
|
|
From: <sv...@va...> - 2017-01-10 16:05:21
|
Author: sewardj
Date: Tue Jan 10 16:05:14 2017
New Revision: 3289
Log:
Fix assertion failure in decode_V8_instruction. Fixes #372794.
Modified:
trunk/priv/guest_arm_toIR.c
Modified: trunk/priv/guest_arm_toIR.c
==============================================================================
--- trunk/priv/guest_arm_toIR.c (original)
+++ trunk/priv/guest_arm_toIR.c Tue Jan 10 16:05:14 2017
@@ -13348,12 +13348,14 @@
}
else /*NOTREACHED*/vassert(0);
}
- // Paranoia ..
- vassert(szBlg2 <= 3);
- if (szBlg2 < 3) { vassert(tt2 == 16/*invalid*/); }
- else { vassert(tt2 <= 14); }
- if (isLoad) { vassert(dd == 16/*invalid*/); }
- else { vassert(dd <= 14); }
+ if (gate) {
+ // Paranoia ..
+ vassert(szBlg2 <= 3);
+ if (szBlg2 < 3) { vassert(tt2 == 16/*invalid*/); }
+ else { vassert(tt2 <= 14); }
+ if (isLoad) { vassert(dd == 16/*invalid*/); }
+ else { vassert(dd <= 14); }
+ }
// If we're still good even after all that, generate the IR.
if (gate) {
/* First, go unconditional. Staying in-line is too complex. */
|
|
From: Ivo R. <iv...@iv...> - 2017-01-09 15:36:47
|
Going twice... Dear developers, If I do not receive any objections until Friday, I will integrate the latest patch attached to this bug. Tested successfully on amd64/Linux and amd64+sparcv9/Solaris. I. |
|
From: <sv...@va...> - 2017-01-06 18:38:35
|
Author: philippe
Date: Fri Jan 6 18:38:27 2017
New Revision: 16193
Log:
xtree: minor updates to documentation, comments and indentation, no functional change.
Modified:
trunk/coregrind/m_xtree.c
trunk/docs/xml/manual-core.xml
Modified: trunk/coregrind/m_xtree.c
==============================================================================
--- trunk/coregrind/m_xtree.c (original)
+++ trunk/coregrind/m_xtree.c Fri Jan 6 18:38:27 2017
@@ -135,9 +135,9 @@
shared->free_fn(shared);
}
-/* Compare 2 entries in ips_order_xecu by StackTrace elements. Note
- that a not existing ips is considered smaller than any other
- address. */
+/* Compare 2 entries in ips_order_xecu by StackTrace elements.
+ In case stack traces are of different length, an 'absent' ips is
+ considered smaller than any other address. */
static XArray* xec_data_for_sort; // Needed to translate an xecu into an xec
static Int ips_order_cmp(const void* vleft, const void* vright)
{
@@ -270,7 +270,7 @@
nxt = xt->alloc_fn(xt->cc, sizeof(struct _XTree) );
*nxt = *xt;
- addRef_XT_shared (nxt->shared);
+ addRef_XT_shared(nxt->shared);
nxt->tmp_data = nxt->alloc_fn(nxt->cc, nxt->dataSzB);
nxt->data = VG_(cloneXA)(nxt->cc, xt->data);
@@ -404,8 +404,13 @@
/* ----------- Callgrind output ------------------------------------------- */
-/* Output a callgrind file element in compressed or not compressed format,
- according to VG_(clo_xtree_compress_strings). */
+/* Output a callgrind format element in compressed format:
+ "name=(pos)" or "name=(pos) value" (if value_new)
+ or not compressed format: "name=value"
+ VG_(clo_xtree_compress_strings) indicates if the compressed format is used.
+ name is the format element (e.g. fl, fn, cfi, cfn, ...).
+ pos is the value dictionary position, used for compressed format.
+ value_new is True if this is the first usage of value. */
static void FP_pos_str(VgFile* fp, const HChar* name, UInt pos,
const HChar* value, Bool value_new)
{
@@ -453,15 +458,15 @@
HChar* p;
VG_(strcpy)(strtok_events, events);
- for (e = VG_(strtok_r) (strtok_events, ",", &ssaveptr);
+ for (e = VG_(strtok_r)(strtok_events, ",", &ssaveptr);
e != NULL;
- e = VG_(strtok_r) (NULL, ",", &ssaveptr))
+ e = VG_(strtok_r)(NULL, ",", &ssaveptr))
FP("event: %s\n", e);
FP("events:");
VG_(strcpy)(strtok_events, events);
- for (e = VG_(strtok_r) (strtok_events, ",", &ssaveptr);
+ for (e = VG_(strtok_r)(strtok_events, ",", &ssaveptr);
e != NULL;
- e = VG_(strtok_r) (NULL, ",", &ssaveptr)) {
+ e = VG_(strtok_r)(NULL, ",", &ssaveptr)) {
p = e;
while (*p) {
if (*p == ':')
@@ -482,7 +487,8 @@
continue;
const HChar* img = img_value(VG_(indexXA)(xt->data, xecu));
-
+
+ // CALLED_FLF gets the Filename/Line number/Function name for ips[n]
#define CALLED_FLF(n) \
if ((n) < 0 \
|| !VG_(get_filename_linenum)(ips[(n)], \
@@ -511,10 +517,10 @@
if (img) {
const HChar* called_filename;
UInt called_filename_nr;
- Bool called_filename_new;
+ Bool called_filename_new; // True the first time we see this filename.
const HChar* called_fnname;
UInt called_fnname_nr;
- Bool called_fnname_new;
+ Bool called_fnname_new; // True the first time we see this fnname.
UInt called_linenum;
UInt prev_linenum;
@@ -540,7 +546,7 @@
else
FP("%d\n", called_linenum); //no self cost.
prev_linenum = called_linenum;
- CALLED_FLF (ips_idx-1);
+ CALLED_FLF(ips_idx-1);
if (ips_idx >= 1) {
FP_pos_str(fp, "cfi", called_filename_nr,
called_filename, called_filename_new);
@@ -580,7 +586,6 @@
/* For Massif output, some functions from the execontext are not output, a.o.
the allocation functions at the top of the stack and the functions below
main. So, the StackTrace of the execontexts in the xtree must be filtered.
- The functions below main.
Ms_Ec defines the subset of the stacktrace relevant for the report. */
typedef
struct {
@@ -708,7 +713,7 @@
}
/* Sort on total size, bigger size first. */
- VG_(ssort) (*groups, *n_groups, sizeof(Ms_Group), ms_group_revcmp_total);
+ VG_(ssort)(*groups, *n_groups, sizeof(Ms_Group), ms_group_revcmp_total);
}
static void ms_output_group (VgFile* fp, UInt depth, Ms_Group* group,
@@ -721,15 +726,15 @@
// If this is an insignificant group, handle it specially
if (group->ms_ec == NULL) {
const HChar* s = ( 1 == group->n_ec? "," : "s, all" );
- vg_assert (group->group_ip == 0);
+ vg_assert(group->group_ip == 0);
FP("%*sn0: %lu in %d place%s below massif's threshold (%.2f%%)\n",
depth+1, "", group->total, group->n_ec, s, sig_pct_threshold);
return;
}
// Normal group => output the group and its subgroups.
- ms_make_groups (depth+1, group->ms_ec, group->n_ec, sig_sz,
- &n_groups, &groups);
+ ms_make_groups(depth+1, group->ms_ec, group->n_ec, sig_sz,
+ &n_groups, &groups);
FP("%*s" "n%u: %ld %s\n",
depth + 1, "",
@@ -745,7 +750,7 @@
/* Output sub groups of this group. */
for (i = 0; i < n_groups; i++)
- ms_output_group (fp, depth+1, &groups[i], sig_sz, sig_pct_threshold);
+ ms_output_group(fp, depth+1, &groups[i], sig_sz, sig_pct_threshold);
VG_(free)(groups);
}
@@ -762,7 +767,7 @@
Ms_Ec* ms_ec = VG_(malloc)("XT_massif_print.ms_ec", n_xecu * sizeof(Ms_Ec));
UInt n_xecu_sel = 0; // Nr of xecu that are selected for output.
- vg_assert (n_data_xecu <= n_xecu);
+ vg_assert(n_data_xecu <= n_xecu);
// Ensure we have in shared->ips_order_xecu our xecu sorted by StackTrace.
ensure_ips_order_xecu_valid(shared);
@@ -909,7 +914,7 @@
/* Produce the groups at depth 0 */
DMSG(1, "XT_massif_print producing depth 0 groups\n");
- ms_make_groups (0, ms_ec, n_ec, sig_sz, &n_groups, &groups);
+ ms_make_groups(0, ms_ec, n_ec, sig_sz, &n_groups, &groups);
/* Output the top node. */
FP("n%u: %llu %s\n", n_groups, top_total, header->top_node_desc);
@@ -917,7 +922,7 @@
/* Output depth 0 groups. */
DMSG(1, "XT_massif_print outputing %u depth 0 groups\n", n_groups);
for (i = 0; i < n_groups; i++)
- ms_output_group (fp, 0, &groups[i], sig_sz, header->sig_threshold);
+ ms_output_group(fp, 0, &groups[i], sig_sz, header->sig_threshold);
VG_(free)(groups);
VG_(free)(ms_ec);
Modified: trunk/docs/xml/manual-core.xml
==============================================================================
--- trunk/docs/xml/manual-core.xml (original)
+++ trunk/docs/xml/manual-core.xml Fri Jan 6 18:38:27 2017
@@ -2761,7 +2761,7 @@
function (malloc), and so have a non zero 'Self' value. Note that when
kcachegrind shows an xtree, the 'Called' column and call nr indications in
the Call Graph are not significant (always set to 0 or 1, independently
- of the real nr of calls. A future version of kcachegrind will not show
+ of the real nr of calls. The kcachegrind versions >= 0.8.0 do not show
anymore such irrelevant xtree call number information.</para>
<graphic fileref="images/kcachegrind_xtree.png" scalefit="1"/>
@@ -2858,11 +2858,11 @@
</itemizedlist>
-<para>Note that it is recommended to use the "Callgrind Format" as it
- is more compact than the Massif Format, and the Callgrind Format
- visualiser are more versatile that the Massif Format
- visualisers. kcachegrind is particularly easy to use to analyse
- big xtree data.</para>
+<para>Note that the Callgrind Format is more compact than the Massif Format,
+ and contains the full data : there is no filtering during file production,
+ filtering is done by visualisers such as kcachegrind. kcachegrind is
+ particularly easy to use to analyse big xtree data containing multiple
+ events counts or resources consumption.</para>
<para>To clarify the xtree concept, the below gives several extracts of
the output produced by the following commands:
|
|
From: Philippe W. <phi...@sk...> - 2017-01-04 14:21:21
|
No sign of any tilegx user or developer activity since something like one year. No reply received for question in https://sourceforge.net/p/valgrind/mailman/message/35566192/ Is there any tilegx user or developer still active ? Should we consider this platform as dead ? Philippe |
|
From: <sv...@va...> - 2017-01-03 22:03:51
|
Author: iraisr
Date: Tue Jan 3 22:03:43 2017
New Revision: 16192
Log:
Add Solaris specific notes on running regression tests
Reported by: Paul Floyd <pa...@fr...>
n-i-bz
Modified:
trunk/README.solaris
Modified: trunk/README.solaris
==============================================================================
--- trunk/README.solaris (original)
+++ trunk/README.solaris Tue Jan 3 22:03:43 2017
@@ -17,6 +17,8 @@
- GNU make is also required. On Solaris, this can be quickly achieved with:
$ PATH=/usr/gnu/bin:$PATH; export PATH
- For remote debugging support, working GDB is required (see below).
+- For running regression tests, GNU sed, grep, awk, diff are required.
+ This can be quickly achieved on Solaris by prepending /usr/gnu/bin to PATH.
Compilation
@@ -123,7 +125,6 @@
- Provide better error reporting for various subsyscalls.
- Implement storing of extra register state in signal frame.
- Performance comparison against other platforms.
-
- Prevent SIGPIPE when writing to a socket (coregrind/m_libcfile.c).
- Implement ticket locking for fair scheduling (--fair-sched=yes).
- Implement support in DRD and Helgrind tools for thr_join() with thread == 0.
@@ -137,6 +138,8 @@
to see this in effect. Would require awareness of syscall parameter semantics.
- Correctly print arguments of DW_CFA_ORCL_arg_loc in show_CF_instruction() when
it is implemented in libdwarf.
+- Handle a situation when guest program sets SC_CANCEL_FLG in schedctl and
+ Valgrind needs to invoke a syscall on its own.
Contacts
|