I plan to overhaul BFP testcases. The key observation (and that is no surprise at all) is that for many BFP insns the following holds: If guest code contains BFP insn XYZ then at the end of the VEX pipeline insn XYZ will be emitted for it. We also know that the IR optimisers won't touch floating point IROps. Today our testing looks like this (from fpconv.stdout.exp): ----- int32_t -> double cdfbr 0 -> 0.000000 cdfbr 1 -> 1.000000 cdfbr -1 -> -1.000000 cdfbr 42 -> 42.000000 cdfbr 32767 -> 32767.000000 cdfbr -32768 -> -32768.000000 cdfbr 2147483647 -> 2147483647.000000 cdfbr -2147483648 -> -2147483648.000000 This is not interesting at all. We're not interested - to verify that hardware works correctly - to find suitable width and precision for printf format strings (depending on the floating point value) - finding bugs in printf implementation In other words, all those values above are boring. What we *do* want to know is whether for a given BFP insn XYZ the very same insn is emitted in the end. How do we do that? Using cdfbr as the example: 1) Create a testcase template: auxprogs/s390-runone -t > foo.c 2) Replace the FIXME line with an asm stmt containing the insn we want to test: sed -i "s/^.*FIXME.*/ asm volatile (\"cdfbr %f0,%f1\");/" foo.c 3) Compile foo.c into an executable "foo" not requiring the dynamic loader. The executable will have exactly one superblock. auxprogs/s390-runone foo.c 4) Run valgrind, trace IR generation and assembly and filter the output: coregrind/valgrind --tool=none --trace-notbelow=0 --trace-flags=10000001 ./foo 2>&1 | egrep "(Front|Assembly|cdfbr)" This will print: ------------------------ Front end ------------------------ cdfbr %f0,%r1 ------------------------ Assembly ------------------------ cdfbr %f7,%r5 Voila. For non-commutative binary operators having testcases that write out register contents is a good thing because it allows to find operand order errors. Everything I said about BFP also holds for DFP. And I bet it also holds for other architectures.
A related bugs is https://bugs.kde.org/show_bug.cgi?id=306098
Some more obervations in no particular order: We need sizeof(long double) == 128 to be able to test 128-bit BFP The GCC I'm using (11.4.0) says: '-mlong-double-64' '-mlong-double-128' These switches control the size of 'long double' type. A size of 64 bits makes the 'long double' type equivalent to the 'double' type. This is the default. So we need to add -mlong-double-128 when compiling because we cannot assume that GCC has been configured --with-long-double-128. if HAS_MLONG_DOUBLE_128 ... ---------- For some insns the behaviour depends on whether or not the floating-point extension is installed. That is a royal pain to distinguish. I am going to make all testcases assume that it is installed. --------- Another thing.. We ought to check for correct computation of condition codes. Those get computed from the cc thunk in the guest state. Affected insns are: - ADD - COMPARE - COMPARE AND SIGNAL - CONVERT TO FIXED - CONVERT TO LOGICAL - DIVIDE TO INTEGER - LOAD AND TEST - LOAD COMPLEMENT - LOAD NEGATIVE - LOAD POSITIVE - SUBTRACT - TEST DATA CLASS
Now fixed. 9a1dbff3812a71ea556b9d80056a11ca8ff88023 78f1569e2235796256742d7c75763034677065af b1f875b63d6a07115dfba571c6dcc1f280c0b1f4 2c79953bd75b4c9bb36a4ff4ccfa3675e1aa7e36 7d9005f4912fa02eb48dcf578f40c035d8cc851b 73ece460ef7e891b404576fd7cc8bd92f4f753ed 6190acedb1d5f1e8a3365e8affcf8ce5c0beac0f 69e67dadf5572b5e6521da2b87633d503f1d597b ce0b91e1e49af679c1cbd51d88b5a95df7fc3c29 d8cf0a84b26ff1ed1b5a9560bfbe5bf476f10c3a 18c5454874d9193fb422832523925406f1d32b80 c574f5eb10d06b491512806354f8d15c3d3e020a 1109ef57b23cf84be551cb9d25373a8169bedce4