All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat
@ 2018-03-21 20:11 Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks Emilio G. Cota
                   ` (16 more replies)
  0 siblings, 17 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

This series is a first stab at (1) having a test suite for our floating
point (FP) implementation, and (2) leveraging the host FPU to speed up
guest FP operations whenever possible.

- Patch 1 is a set of simple microbenchmarks to isolate the performance
  of particular FP operations.

- Patch 2 adds fp-test, a floating point test suite. Note that I'm
  hacking around target poisoning to be able to include softfloat
  headers. I am not defining any TARGET_* cpu, so softfloat-specialize
  will take the defaults. The commit message has more info on how
  fp-test can be used to test the full FP implementation of a guest CPU.

- Patch 3 fixes a bug in FP that was identified with fp-test.
  The bug is very minor, but we might want to get this fixed in 2.12.

- Patches 5-6 add some helpers to be used later. Note that
  the functions there return bools, not integers like the
  functions around them. [wasn't sure which way to go for.]

- Patch 8 introduces hostfloat, as a separate, GPL'ed file.
  The commit message and a comment in the file document the
  assumptions and possible pitfalls of this approach.

- Patches 9-14 implement some common FP operations in hostfloat.

For performance numbers see the last patch.

BTW checkpatch reports some warnings, but they're false positives
so please ignore them.

This series applies on top of f6d81cde ("Merge remote-tracking
branch 'remotes/stsquad/tags/pull-shippable-disable-ppc-080318-1'
into staging", 2018-03-08).

You can fetch the series from:
  https://github.com/cota/qemu/tree/hostfloat-v1

Feedback appreciated!
Thanks,

		Emilio

diffstat:
 Makefile.target             |    2 +-
 configure                   |    2 +
 fpu/hostfloat.c             |  342 +++++++++++++
 fpu/softfloat.c             |   97 ++--
 include/fpu/hostfloat.h     |   34 ++
 include/fpu/softfloat.h     |   53 +-
 target/m68k/Makefile.objs   |    2 +-
 tests/.gitignore            |    2 +
 tests/Makefile.include      |    3 +-
 tests/fp-bench.c            |  290 +++++++++++
 tests/fp-test/.gitignore    |    3 +
 tests/fp-test/Makefile      |   34 ++
 tests/fp-test/fp-test.c     | 1183 ++++++++++++++++++++++++++++++++++++++++++++
 tests/fp-test/muladd.fptest |   51 ++
 14 files changed, 2035 insertions(+), 63 deletions(-)

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27  8:45   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite Emilio G. Cota
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

This will allow us to measure the performance impact of FP
emulation optimizations.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 tests/fp-bench.c       | 290 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/.gitignore       |   1 +
 tests/Makefile.include |   3 +-
 3 files changed, 293 insertions(+), 1 deletion(-)
 create mode 100644 tests/fp-bench.c

diff --git a/tests/fp-bench.c b/tests/fp-bench.c
new file mode 100644
index 0000000..a782093
--- /dev/null
+++ b/tests/fp-bench.c
@@ -0,0 +1,290 @@
+/*
+ * fp-bench.c - A collection of simple floating point microbenchmarks.
+ *
+ * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/atomic.h"
+
+#include <math.h>
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h>
+
+/* amortize the computation of random inputs */
+#define OPS_PER_ITER     (1000ULL)
+
+#define SEED_A 0xdeadfacedeadface
+#define SEED_B 0xbadc0feebadc0fee
+#define SEED_C 0xbeefdeadbeefdead
+
+enum op {
+    OP_ADD,
+    OP_SUB,
+    OP_MUL,
+    OP_DIV,
+    OP_FMA,
+    OP_SQRT,
+};
+
+static const char * const op_names[] = {
+    [OP_ADD] = "add",
+    [OP_SUB] = "sub",
+    [OP_MUL] = "mul",
+    [OP_DIV] = "div",
+    [OP_FMA] = "fma",
+    [OP_SQRT] = "sqrt",
+};
+
+static uint64_t n_ops = 10000000;
+static enum op op;
+static const char *precision = "float";
+
+static const char commands_string[] =
+    " -n = number of floating point operations\n"
+    " -o = floating point operation (add, sub, mul, div, fma, sqrt). Default: add\n"
+    " -p = precision (float|single, double). Default: float";
+
+static void usage_complete(int argc, char *argv[])
+{
+    fprintf(stderr, "Usage: %s [options]\n", argv[0]);
+    fprintf(stderr, "options:\n%s\n", commands_string);
+    exit(-1);
+}
+
+static void set_op(const char *name)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(op_names); i++) {
+        if (strcmp(name, op_names[i]) == 0) {
+            op = i;
+            return;
+        }
+    }
+    fprintf(stderr, "Unsupported op '%s'\n", name);
+    exit(EXIT_FAILURE);
+}
+
+static inline int64_t get_clock_realtime(void)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
+}
+
+/*
+ * From: https://en.wikipedia.org/wiki/Xorshift
+ * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
+ * guaranteed to be >= INT_MAX).
+ */
+static uint64_t xorshift64star(uint64_t x)
+{
+    x ^= x >> 12; /* a */
+    x ^= x << 25; /* b */
+    x ^= x >> 27; /* c */
+    return x * UINT64_C(2685821657736338717);
+}
+
+static inline bool u32_is_normal(uint32_t x)
+{
+    return ((x + 0x00800000) & 0x7fffffff) >= 0x01000000;
+}
+
+static inline bool u64_is_normal(uint64_t x)
+{
+    return ((x + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
+}
+
+static inline float get_random_float(uint64_t *x)
+{
+    uint64_t r = *x;
+    uint32_t r32;
+
+    do {
+        r = xorshift64star(r);
+    } while (!u32_is_normal(r));
+    *x = r;
+    r32 = r;
+    return *(float *)&r32;
+}
+
+static inline double get_random_double(uint64_t *x)
+{
+    uint64_t r = *x;
+
+    do {
+        r = xorshift64star(r);
+    } while (!u64_is_normal(r));
+    *x = r;
+    return *(double *)&r;
+}
+
+/*
+ * Disable optimizations (e.g. "a OP b" outside of the inner loop) with
+ * volatile.
+ */
+#define GEN_BENCH_1OPF(NAME, FUNC, PRECISION)                           \
+    static void NAME(volatile PRECISION *res)                           \
+    {                                                                   \
+        uint64_t ra = SEED_A;                                           \
+        uint64_t i, j;                                                  \
+                                                                        \
+        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
+                                                                        \
+            for (j = 0; j < OPS_PER_ITER; j++) {                        \
+                *res = FUNC(a);                                         \
+            }                                                           \
+        }                                                               \
+    }
+
+GEN_BENCH_1OPF(bench_float_sqrt, sqrtf, float)
+GEN_BENCH_1OPF(bench_double_sqrt, sqrt, double)
+#undef GEN_BENCH_1OPF
+
+#define GEN_BENCH_2OP(NAME, OP, PRECISION)                              \
+    static void NAME(volatile PRECISION *res)                           \
+    {                                                                   \
+        uint64_t ra = SEED_A;                                           \
+        uint64_t rb = SEED_B;                                           \
+        uint64_t i, j;                                                  \
+                                                                        \
+        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
+            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \
+                                                                        \
+            for (j = 0; j < OPS_PER_ITER; j++) {                        \
+                *res = a OP b;                                          \
+            }                                                           \
+        }                                                               \
+    }
+
+GEN_BENCH_2OP(bench_float_add, +, float)
+GEN_BENCH_2OP(bench_float_sub, -, float)
+GEN_BENCH_2OP(bench_float_mul, *, float)
+GEN_BENCH_2OP(bench_float_div, /, float)
+
+GEN_BENCH_2OP(bench_double_add, +, double)
+GEN_BENCH_2OP(bench_double_sub, -, double)
+GEN_BENCH_2OP(bench_double_mul, *, double)
+GEN_BENCH_2OP(bench_double_div, /, double)
+
+#define GEN_BENCH_3OPF(NAME, FUNC, PRECISION)                           \
+    static void NAME(volatile PRECISION *res)                           \
+    {                                                                   \
+        uint64_t ra = SEED_A;                                           \
+        uint64_t rb = SEED_B;                                           \
+        uint64_t rc = SEED_C;                                           \
+        uint64_t i, j;                                                  \
+                                                                        \
+        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
+            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \
+            volatile PRECISION c = glue(get_random_, PRECISION)(&rc);   \
+                                                                        \
+            for (j = 0; j < OPS_PER_ITER; j++) {                        \
+                *res = FUNC(a, b, c);                                   \
+            }                                                           \
+        }                                                               \
+    }
+
+GEN_BENCH_3OPF(bench_float_fma, fmaf, float)
+GEN_BENCH_3OPF(bench_double_fma, fma, double)
+#undef GEN_BENCH_3OPF
+
+static void parse_args(int argc, char *argv[])
+{
+    int c;
+
+    for (;;) {
+        c = getopt(argc, argv, "n:ho:p:");
+        if (c < 0) {
+            break;
+        }
+        switch (c) {
+        case 'h':
+            usage_complete(argc, argv);
+            exit(0);
+        case 'n':
+            n_ops = atoll(optarg);
+            if (n_ops < OPS_PER_ITER) {
+                n_ops = OPS_PER_ITER;
+            }
+            n_ops -= n_ops % OPS_PER_ITER;
+            break;
+        case 'o':
+            set_op(optarg);
+            break;
+        case 'p':
+            precision = optarg;
+            if (strcmp(precision, "float") &&
+                strcmp(precision, "single") &&
+                strcmp(precision, "double")) {
+                fprintf(stderr, "Unsupported precision '%s'\n", precision);
+                exit(EXIT_FAILURE);
+            }
+            break;
+        }
+    }
+}
+
+#define CALL_BENCH(OP, PRECISION, RESP)                 \
+    do {                                                \
+        switch (OP) {                                   \
+        case OP_ADD:                                    \
+            glue(glue(bench_, PRECISION), _add)(RESP);  \
+            break;                                      \
+        case OP_SUB:                                    \
+            glue(glue(bench_, PRECISION), _sub)(RESP);  \
+            break;                                      \
+        case OP_MUL:                                    \
+            glue(glue(bench_, PRECISION), _mul)(RESP);  \
+            break;                                      \
+        case OP_DIV:                                    \
+            glue(glue(bench_, PRECISION), _div)(RESP);  \
+            break;                                      \
+        case OP_FMA:                                    \
+            glue(glue(bench_, PRECISION), _fma)(RESP);  \
+            break;                                      \
+        case OP_SQRT:                                   \
+            glue(glue(bench_, PRECISION), _sqrt)(RESP); \
+            break;                                      \
+        default:                                        \
+            g_assert_not_reached();                     \
+        }                                               \
+    } while (0)
+
+int main(int argc, char *argv[])
+{
+    int64_t t0, t1;
+    double resd;
+
+    parse_args(argc, argv);
+    if (!strcmp(precision, "float") || !strcmp(precision, "single")) {
+        float res;
+        t0 = get_clock_realtime();
+        CALL_BENCH(op, float, &res);
+        t1 = get_clock_realtime();
+        resd = res;
+    } else if (!strcmp(precision, "double")) {
+        t0 = get_clock_realtime();
+        CALL_BENCH(op, double, &resd);
+        t1 = get_clock_realtime();
+    } else {
+        g_assert_not_reached();
+    }
+    printf("%.2f MFlops\n", (double)n_ops / (t1 - t0) * 1e3);
+    if (resd) {
+        return 0;
+    }
+    return 0;
+}
diff --git a/tests/.gitignore b/tests/.gitignore
index 18e58b2..df69175 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -12,6 +12,7 @@ check-qobject
 check-qstring
 check-qom-interface
 check-qom-proplist
+fp-bench
 qht-bench
 rcutorture
 test-aio
diff --git a/tests/Makefile.include b/tests/Makefile.include
index ef9b88c..f6121ee 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -587,7 +587,7 @@ test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
 	tests/rcutorture.o tests/test-rcu-list.o \
 	tests/test-qdist.o tests/test-shift128.o \
 	tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
-	tests/atomic_add-bench.o
+	tests/atomic_add-bench.o tests/fp-bench.o
 
 $(test-obj-y): QEMU_INCLUDES += -Itests
 QEMU_CFLAGS += -I$(SRC_PATH)/tests
@@ -639,6 +639,7 @@ tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(tes
 tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
 tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
 tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
+tests/fp-bench$(EXESUF): tests/fp-bench.o $(test-util-obj-y)
 
 tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
 	hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27 10:13   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

This will allow us to run correctness tests against our
FP implementation. The test can be run in two modes (called
"testers"): host and soft. With the former we check the results
and FP flags on the host machine against the model.
With the latter we check QEMU's fpu primitives against the
model. Note that in soft mode we are not instantiating any
particular CPU (hence the HW_POISON_H hack to avoid macro poisoning);
for that we need to run the test in host mode under QEMU.

The input files are taken from IBM's FPGen test suite:
https://www.research.ibm.com/haifa/projects/verification/fpgen/

I see no license file in there so I am just downloading them
with wget. We might want to keep a copy on a qemu server though,
in case IBM takes those files down in the future.

The "IBM" syntax of those files (for now the only syntax supported
in fp-test) is documented here:
https://www.research.ibm.com/haifa/projects/verification/fpgen/papers/ieee-test-suite-v2.pdf

Note that the syntax document has some inaccuracies; the appended
parsing code works around some of those.

The exception flag (-e) is important: many of the optimizations
included in the following commits assume that the inexact flag
is set, so "-e x" is necessary in order to test those code paths.

The whitelist flag (-w) points to a file with test cases to be ignored.
I have put some whitelist files online, but we should have them
on a QEMU-related server.

Thus, a typical of fp-test is as follows:

  $ cd qemu/build/tests/fp-test
  $ make -j && \
	./fp-test -t soft ibm/*.fptest \
	-w whitelist.txt \
	-e x

If we want to test after-rounding tininess detection, then we need to
pass "-a -w whitelist-tininess-after.txt" in addition to the above.
(NB. we can pass "-w" as many times as we want.)

The patch immediately after this one fixes a mismatch against the model
in softfloat, but after that is applied the above should finish with a 0
return code, and print something like:
  All tests OK.
  Tests passed: 76572. Not handled: 51237, whitelisted: 2662

The tests pass on "host" mode on x86_64 and aarch64 machines.
On an IBM Power8 machine some exception flags are different from the
model files, which is interesting given that the model comes from IBM.

Running on host mode under QEMU reports flag mismatches (e.g. for
x86_64-linux-user), but that isn't too surprising given how little
love the i386 frontend gets. Host mode under aarch64-linux-user
passes OK.

Flush-to-zero and flush-inputs-to-zero modes can be tested with the
-z and -Z flags. Note however that the IBM input files are only
IEEE-compliant, so for now I've tested these modes by diff'ing
the reported errors against the model files. We should look into
generating files for these non-standard modes to make testing
these modes less painful.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 configure                |    2 +
 tests/fp-test/fp-test.c  | 1159 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/.gitignore         |    1 +
 tests/fp-test/.gitignore |    3 +
 tests/fp-test/Makefile   |   34 ++
 5 files changed, 1199 insertions(+)
 create mode 100644 tests/fp-test/fp-test.c
 create mode 100644 tests/fp-test/.gitignore
 create mode 100644 tests/fp-test/Makefile

diff --git a/configure b/configure
index 6f3921c..8ea3825 100755
--- a/configure
+++ b/configure
@@ -7046,12 +7046,14 @@ fi
 
 # build tree in object directory in case the source is not in the current directory
 DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
+DIRS="$DIRS tests/fp-test"
 DIRS="$DIRS docs docs/interop fsdev scsi"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
+FILES="$FILES tests/fp-test/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES pc-bios/s390-ccw/Makefile"
diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
new file mode 100644
index 0000000..27637c4
--- /dev/null
+++ b/tests/fp-test/fp-test.c
@@ -0,0 +1,1159 @@
+/*
+ * fp-test.c - Floating point test suite.
+ *
+ * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef HW_POISON_H
+#error Must define HW_POISON_H to work around TARGET_* poisoning
+#endif
+
+#include "qemu/osdep.h"
+#include "fpu/softfloat.h"
+
+#include <fenv.h>
+#include <math.h>
+
+enum error {
+    ERROR_NONE,
+    ERROR_NOT_HANDLED,
+    ERROR_WHITELISTED,
+    ERROR_COMMENT,
+    ERROR_INPUT,
+    ERROR_RESULT,
+    ERROR_EXCEPTIONS,
+    ERROR_MAX,
+};
+
+enum input_fmt {
+    INPUT_FMT_IBM,
+};
+
+struct input {
+    const char * const name;
+    enum error (*test_line)(const char *line);
+};
+
+enum precision {
+    PREC_FLOAT,
+    PREC_DOUBLE,
+    PREC_QUAD,
+    PREC_FLOAT_TO_DOUBLE,
+};
+
+struct op_desc {
+    const char * const name;
+    int n_operands;
+};
+
+enum op {
+    OP_ADD,
+    OP_SUB,
+    OP_MUL,
+    OP_MULADD,
+    OP_DIV,
+    OP_SQRT,
+    OP_MINNUM,
+    OP_MAXNUM,
+    OP_MAXNUMMAG,
+    OP_ABS,
+    OP_IS_NAN,
+    OP_IS_INF,
+    OP_FLOAT_TO_DOUBLE,
+};
+
+static const struct op_desc ops[] = {
+    [OP_ADD] =       { "+", 2 },
+    [OP_SUB] =       { "-", 2 },
+    [OP_MUL] =       { "*", 2 },
+    [OP_MULADD] =    { "*+", 3 },
+    [OP_DIV] =       { "/", 2 },
+    [OP_SQRT] =      { "V", 1 },
+    [OP_MINNUM] =    { "<C", 2 },
+    [OP_MAXNUM] =    { ">C", 2 },
+    [OP_MAXNUMMAG] = { ">A", 2 },
+    [OP_ABS] =       { "A", 1 },
+    [OP_IS_NAN] =    { "?N", 1 },
+    [OP_IS_INF] =    { "?i", 1 },
+    [OP_FLOAT_TO_DOUBLE] = { "cff", 1 },
+};
+
+/*
+ * We could enumerate all the types here. But really we only care about
+ * QNaN and SNaN since only those can vary across ISAs.
+ */
+enum op_type {
+    OP_TYPE_NUMBER,
+    OP_TYPE_QNAN,
+    OP_TYPE_SNAN,
+};
+
+struct operand {
+    uint64_t val;
+    enum op_type type;
+};
+
+struct test_op {
+    struct operand operands[3];
+    struct operand expected_result;
+    enum precision prec;
+    enum op op;
+    signed char round;
+    uint8_t trapped_exceptions;
+    uint8_t exceptions;
+    bool expected_result_is_valid;
+};
+
+typedef enum error (*tester_func_t)(struct test_op *);
+
+struct tester {
+    tester_func_t func;
+    const char *name;
+};
+
+struct whitelist {
+    char **lines;
+    size_t n;
+    GHashTable *ht;
+};
+
+static uint64_t test_stats[ERROR_MAX];
+static struct whitelist whitelist;
+static uint8_t default_exceptions;
+static bool die_on_error = true;
+static struct float_status soft_status = {
+    .float_detect_tininess = float_tininess_before_rounding,
+};
+
+static inline float u64_to_float(uint64_t v)
+{
+    uint32_t v32 = v;
+    uint32_t *v32p = &v32;
+
+    return *(float *)v32p;
+}
+
+static inline double u64_to_double(uint64_t v)
+{
+    uint64_t *vp = &v;
+
+    return *(double *)vp;
+}
+
+static inline uint64_t float_to_u64(float f)
+{
+    float *fp = &f;
+
+    return *(uint32_t *)fp;
+}
+
+static inline uint64_t double_to_u64(double d)
+{
+    double *dp = &d;
+
+    return *(uint64_t *)dp;
+}
+
+static inline bool is_err(enum error err)
+{
+    return err != ERROR_NONE &&
+        err != ERROR_NOT_HANDLED &&
+        err != ERROR_WHITELISTED &&
+        err != ERROR_COMMENT;
+}
+
+static int host_exceptions_translate(int host_flags)
+{
+    int flags = 0;
+
+    if (host_flags & FE_INEXACT) {
+        flags |= float_flag_inexact;
+    }
+    if (host_flags & FE_UNDERFLOW) {
+        flags |= float_flag_underflow;
+    }
+    if (host_flags & FE_OVERFLOW) {
+        flags |= float_flag_overflow;
+    }
+    if (host_flags & FE_DIVBYZERO) {
+        flags |= float_flag_divbyzero;
+    }
+    if (host_flags & FE_INVALID) {
+        flags |= float_flag_invalid;
+    }
+    return flags;
+}
+
+static inline uint8_t host_get_exceptions(void)
+{
+    return host_exceptions_translate(fetestexcept(FE_ALL_EXCEPT));
+}
+
+static void host_set_exceptions(uint8_t flags)
+{
+    int host_flags = 0;
+
+    if (flags & float_flag_inexact) {
+        host_flags |= FE_INEXACT;
+    }
+    if (flags & float_flag_underflow) {
+        host_flags |= FE_UNDERFLOW;
+    }
+    if (flags & float_flag_overflow) {
+        host_flags |= FE_OVERFLOW;
+    }
+    if (flags & float_flag_divbyzero) {
+        host_flags |= FE_DIVBYZERO;
+    }
+    if (flags & float_flag_invalid) {
+        host_flags |= FE_INVALID;
+    }
+    feraiseexcept(host_flags);
+}
+
+#define STANDARD_EXCEPTIONS \
+    (float_flag_inexact | float_flag_underflow | \
+     float_flag_overflow | float_flag_divbyzero | float_flag_invalid)
+#define FMT_EXCEPTIONS "%s%s%s%s%s%s"
+#define PR_EXCEPTIONS(x)                                \
+        ((x) & STANDARD_EXCEPTIONS ? "" : "none"),      \
+        (((x) & float_flag_inexact)   ? "x" : ""),      \
+        (((x) & float_flag_underflow) ? "u" : ""),      \
+        (((x) & float_flag_overflow)  ? "o" : ""),      \
+        (((x) & float_flag_divbyzero) ? "z" : ""),      \
+        (((x) & float_flag_invalid)   ? "i" : "")
+
+static enum error tester_check(const struct test_op *t, uint64_t res64,
+                               bool res_is_nan, uint8_t flags)
+{
+    enum error err = ERROR_NONE;
+
+    if (t->expected_result_is_valid) {
+        if (t->expected_result.type == OP_TYPE_QNAN ||
+            t->expected_result.type == OP_TYPE_SNAN) {
+            if (!res_is_nan) {
+                err = ERROR_RESULT;
+                goto out;
+            }
+        } else if (res64 != t->expected_result.val) {
+            err = ERROR_RESULT;
+            goto out;
+        }
+    }
+    if (t->exceptions && flags != (t->exceptions | default_exceptions)) {
+        err = ERROR_EXCEPTIONS;
+        goto out;
+    }
+
+ out:
+    if (is_err(err)) {
+        int i;
+
+        fprintf(stderr, "%s ", ops[t->op].name);
+        for (i = 0; i < ops[t->op].n_operands; i++) {
+            fprintf(stderr, "0x%" PRIx64 "%s", t->operands[i].val,
+                    i < ops[t->op].n_operands - 1 ? " " : "");
+        }
+        fprintf(stderr, ", expected: 0x%" PRIx64 ", returned: 0x%" PRIx64,
+                t->expected_result.val, res64);
+        if (err == ERROR_EXCEPTIONS) {
+            fprintf(stderr, ", expected exceptions: " FMT_EXCEPTIONS
+                    ", returned: " FMT_EXCEPTIONS,
+                    PR_EXCEPTIONS(t->exceptions), PR_EXCEPTIONS(flags));
+        }
+        fprintf(stderr, "\n");
+    }
+    return err;
+}
+
+static enum error host_tester(struct test_op *t)
+{
+    uint64_t res64;
+    bool result_is_nan;
+    uint8_t flags = 0;
+
+    feclearexcept(FE_ALL_EXCEPT);
+    if (default_exceptions) {
+        host_set_exceptions(default_exceptions);
+    }
+
+    if (t->prec == PREC_FLOAT) {
+        float a, b, c;
+        float *in[] = { &a, &b, &c };
+        float res;
+        int i;
+
+        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+        for (i = 0; i < ops[t->op].n_operands; i++) {
+            /* use the host's QNaN/SNaN patterns */
+            if (t->operands[i].type == OP_TYPE_QNAN) {
+                *in[i] = __builtin_nanf("");
+            } else if (t->operands[i].type == OP_TYPE_SNAN) {
+                *in[i] = __builtin_nansf("");
+            } else {
+                *in[i] = u64_to_float(t->operands[i].val);
+            }
+        }
+
+        if (t->expected_result.type == OP_TYPE_QNAN) {
+            t->expected_result.val = float_to_u64(__builtin_nanf(""));
+        } else if (t->expected_result.type == OP_TYPE_SNAN) {
+            t->expected_result.val = float_to_u64(__builtin_nansf(""));
+        }
+
+        switch (t->op) {
+        case OP_ADD:
+            res = a + b;
+            break;
+        case OP_SUB:
+            res = a - b;
+            break;
+        case OP_MUL:
+            res = a * b;
+            break;
+        case OP_MULADD:
+            res = fmaf(a, b, c);
+            break;
+        case OP_DIV:
+            res = a / b;
+            break;
+        case OP_SQRT:
+            res = sqrtf(a);
+            break;
+        case OP_ABS:
+            res = fabsf(a);
+            break;
+        case OP_IS_NAN:
+            res = !!isnan(a);
+            break;
+        case OP_IS_INF:
+            res = !!isinf(a);
+            break;
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        flags = host_get_exceptions();
+        res64 = float_to_u64(res);
+        result_is_nan = isnan(res);
+    } else if (t->prec == PREC_DOUBLE) {
+        double a, b, c;
+        double *in[] = { &a, &b, &c };
+        double res;
+        int i;
+
+        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+        for (i = 0; i < ops[t->op].n_operands; i++) {
+            /* use the host's QNaN/SNaN patterns */
+            if (t->operands[i].type == OP_TYPE_QNAN) {
+                *in[i] = __builtin_nan("");
+            } else if (t->operands[i].type == OP_TYPE_SNAN) {
+                *in[i] = __builtin_nans("");
+            } else {
+                *in[i] = u64_to_double(t->operands[i].val);
+            }
+        }
+
+        if (t->expected_result.type == OP_TYPE_QNAN) {
+            t->expected_result.val = double_to_u64(__builtin_nan(""));
+        } else if (t->expected_result.type == OP_TYPE_SNAN) {
+            t->expected_result.val = double_to_u64(__builtin_nans(""));
+        }
+
+        switch (t->op) {
+        case OP_ADD:
+            res = a + b;
+            break;
+        case OP_SUB:
+            res = a - b;
+            break;
+        case OP_MUL:
+            res = a * b;
+            break;
+        case OP_MULADD:
+            res = fma(a, b, c);
+            break;
+        case OP_DIV:
+            res = a / b;
+            break;
+        case OP_SQRT:
+            res = sqrt(a);
+            break;
+        case OP_ABS:
+            res = fabs(a);
+            break;
+        case OP_IS_NAN:
+            res = !!isnan(a);
+            break;
+        case OP_IS_INF:
+            res = !!isinf(a);
+            break;
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        flags = host_get_exceptions();
+        res64 = double_to_u64(res);
+        result_is_nan = isnan(res);
+    } else if (t->prec == PREC_FLOAT_TO_DOUBLE) {
+        float a;
+        double res;
+
+        if (t->operands[0].type == OP_TYPE_QNAN) {
+            a = __builtin_nanf("");
+        } else if (t->operands[0].type == OP_TYPE_SNAN) {
+            a = __builtin_nansf("");
+        } else {
+            a = u64_to_float(t->operands[0].val);
+        }
+
+        if (t->expected_result.type == OP_TYPE_QNAN) {
+            t->expected_result.val = double_to_u64(__builtin_nan(""));
+        } else if (t->expected_result.type == OP_TYPE_SNAN) {
+            t->expected_result.val = double_to_u64(__builtin_nans(""));
+        }
+
+        switch (t->op) {
+        case OP_FLOAT_TO_DOUBLE:
+            res = a;
+            break;
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        flags = host_get_exceptions();
+        res64 = double_to_u64(res);
+        result_is_nan = isnan(res);
+    } else {
+        return ERROR_NOT_HANDLED; /* XXX */
+    }
+    return tester_check(t, res64, result_is_nan, flags);
+}
+
+static enum error soft_tester(struct test_op *t)
+{
+    float_status *s = &soft_status;
+    uint64_t res64;
+    enum error err = ERROR_NONE;
+    bool result_is_nan;
+
+    s->float_rounding_mode = t->round;
+    s->float_exception_flags = default_exceptions;
+
+    if (t->prec == PREC_FLOAT) {
+        float32 a, b, c;
+        float32 *in[] = { &a, &b, &c };
+        float32 res;
+        int i;
+
+        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+        for (i = 0; i < ops[t->op].n_operands; i++) {
+            *in[i] = t->operands[i].val;
+        }
+
+        switch (t->op) {
+        case OP_ADD:
+            res = float32_add(a, b, s);
+            break;
+        case OP_SUB:
+            res = float32_sub(a, b, s);
+            break;
+        case OP_MUL:
+            res = float32_mul(a, b, s);
+            break;
+        case OP_MULADD:
+            res = float32_muladd(a, b, c, 0, s);
+            break;
+        case OP_DIV:
+            res = float32_div(a, b, s);
+            break;
+        case OP_SQRT:
+            res = float32_sqrt(a, s);
+            break;
+        case OP_MINNUM:
+            res = float32_minnum(a, b, s);
+            break;
+        case OP_MAXNUM:
+            res = float32_maxnum(a, b, s);
+            break;
+        case OP_MAXNUMMAG:
+            res = float32_maxnummag(a, b, s);
+            break;
+        case OP_IS_NAN:
+        {
+            float f = !!float32_is_any_nan(a);
+
+            res = float_to_u64(f);
+            break;
+        }
+        case OP_IS_INF:
+        {
+            float f = !!float32_is_infinity(a);
+
+            res = float_to_u64(f);
+            break;
+        }
+        case OP_ABS:
+            /* Fall-through: float32_abs does not handle NaN's */
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        res64 = res;
+        result_is_nan = isnan(*(float *)&res);
+    } else if (t->prec == PREC_DOUBLE) {
+        float64 a, b, c;
+        float64 *in[] = { &a, &b, &c };
+        int i;
+
+        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+        for (i = 0; i < ops[t->op].n_operands; i++) {
+            *in[i] = t->operands[i].val;
+        }
+
+        switch (t->op) {
+        case OP_ADD:
+            res64 = float64_add(a, b, s);
+            break;
+        case OP_SUB:
+            res64 = float64_sub(a, b, s);
+            break;
+        case OP_MUL:
+            res64 = float64_mul(a, b, s);
+            break;
+        case OP_MULADD:
+            res64 = float64_muladd(a, b, c, 0, s);
+            break;
+        case OP_DIV:
+            res64 = float64_div(a, b, s);
+            break;
+        case OP_SQRT:
+            res64 = float64_sqrt(a, s);
+            break;
+        case OP_MINNUM:
+            res64 = float64_minnum(a, b, s);
+            break;
+        case OP_MAXNUM:
+            res64 = float64_maxnum(a, b, s);
+            break;
+        case OP_MAXNUMMAG:
+            res64 = float64_maxnummag(a, b, s);
+            break;
+        case OP_IS_NAN:
+        {
+            double d = !!float64_is_any_nan(a);
+
+            res64 = double_to_u64(d);
+            break;
+        }
+        case OP_IS_INF:
+        {
+            double d = !!float64_is_infinity(a);
+
+            res64 = double_to_u64(d);
+            break;
+        }
+        case OP_ABS:
+            /* Fall-through: float64_abs does not handle NaN's */
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        result_is_nan = isnan(*(double *)&res64);
+    } else if (t->prec == PREC_FLOAT_TO_DOUBLE) {
+        float32 a = t->operands[0].val;
+
+        switch (t->op) {
+        case OP_FLOAT_TO_DOUBLE:
+            res64 = float32_to_float64(a, s);
+            break;
+        default:
+            return ERROR_NOT_HANDLED;
+        }
+        result_is_nan = isnan(*(double *)&res64);
+    } else {
+        return ERROR_NOT_HANDLED; /* XXX */
+    }
+    return tester_check(t, res64, result_is_nan, s->float_exception_flags);
+    return err;
+}
+
+static const struct tester valid_testers[] = {
+    [0] = {
+        .name = "soft",
+        .func = soft_tester,
+    },
+    [1] = {
+        .name = "host",
+        .func = host_tester,
+    },
+};
+static const struct tester *tester = &valid_testers[0];
+
+static int ibm_get_exceptions(const char *p, uint8_t *excp)
+{
+    while (*p) {
+        switch (*p) {
+        case 'x':
+            *excp |= float_flag_inexact;
+            break;
+        case 'u':
+            *excp |= float_flag_underflow;
+            break;
+        case 'o':
+            *excp |= float_flag_overflow;
+            break;
+        case 'z':
+            *excp |= float_flag_divbyzero;
+            break;
+        case 'i':
+            *excp |= float_flag_invalid;
+            break;
+        default:
+            return 1;
+        }
+        p++;
+    }
+    return 0;
+}
+
+static uint64_t fp_choose(enum precision prec, uint64_t f, uint64_t d)
+{
+    switch (prec) {
+    case PREC_FLOAT:
+        return f;
+    case PREC_DOUBLE:
+        return d;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static int
+ibm_fp_hex(const char *p, enum precision prec, struct operand *ret)
+{
+    int len;
+
+    ret->type = OP_TYPE_NUMBER;
+
+    /* QNaN */
+    if (unlikely(!strcmp("Q", p))) {
+        ret->val = fp_choose(prec, 0xffc00000, 0xfff8000000000000);
+        ret->type = OP_TYPE_QNAN;
+        return 0;
+    }
+    /* SNaN */
+    if (unlikely(!strcmp("S", p))) {
+        ret->val = fp_choose(prec, 0xffb00000, 0xfff7000000000000);
+        ret->type = OP_TYPE_SNAN;
+        return 0;
+    }
+    if (unlikely(!strcmp("+Zero", p))) {
+        ret->val = fp_choose(prec, 0x00000000, 0x0000000000000000);
+        return 0;
+    }
+    if (unlikely(!strcmp("-Zero", p))) {
+        ret->val = fp_choose(prec, 0x80000000, 0x8000000000000000);
+        return 0;
+    }
+    if (unlikely(!strcmp("+inf", p) || !strcmp("+Inf", p))) {
+        ret->val = fp_choose(prec, 0x7f800000, 0x7ff0000000000000);
+        return 0;
+    }
+    if (unlikely(!strcmp("-inf", p) || !strcmp("-Inf", p))) {
+        ret->val = fp_choose(prec, 0xff800000, 0xfff0000000000000);
+        return 0;
+    }
+
+    len = strlen(p);
+
+    if (strchr(p, 'P')) {
+        bool negative = p[0] == '-';
+        char *pos;
+        bool denormal;
+
+        if (len <= 4) {
+            return 1;
+        }
+        denormal = p[1] == '0';
+        if (prec == PREC_FLOAT) {
+            uint32_t exponent;
+            uint32_t significand;
+            uint32_t h;
+
+            significand = strtoul(&p[3], &pos, 16);
+            if (*pos != 'P') {
+                return 1;
+            }
+            pos++;
+            exponent = strtol(pos, &pos, 10) + 127;
+            if (pos != p + len) {
+                return 1;
+            }
+            /*
+             * When there's a leading zero, we have a denormal number. We'd
+             * expect the input (unbiased) exponent to be -127, but for some
+             * reason -126 is used. Correct that here.
+             */
+            if (denormal) {
+                if (exponent != 1) {
+                    return 1;
+                }
+                exponent = 0;
+            }
+            h = negative ? (1 << 31) : 0;
+            h |= exponent << 23;
+            h |= significand;
+            ret->val = h;
+            return 0;
+        } else if (prec == PREC_DOUBLE) {
+            uint64_t exponent;
+            uint64_t significand;
+            uint64_t h;
+
+            significand = strtoul(&p[3], &pos, 16);
+            if (*pos != 'P') {
+                return 1;
+            }
+            pos++;
+            exponent = strtol(pos, &pos, 10) + 1023;
+            if (pos != p + len) {
+                return 1;
+            }
+            if (denormal) {
+                return 1; /* XXX */
+            }
+            h = negative ? (1ULL << 63) : 0;
+            h |= exponent << 52;
+            h |= significand;
+            ret->val = h;
+            return 0;
+        } else { /* XXX */
+            return 1;
+        }
+    } else if (strchr(p, 'e')) {
+        char *pos;
+
+        if (prec == PREC_FLOAT) {
+            float f = strtof(p, &pos);
+
+            if (*pos) {
+                return 1;
+            }
+            ret->val = float_to_u64(f);
+            return 0;
+        }
+        if (prec == PREC_DOUBLE) {
+            double d = strtod(p, &pos);
+
+            if (*pos) {
+                return 1;
+            }
+            ret->val = double_to_u64(d);
+            return 0;
+        }
+        return 0;
+    } else if (!strcmp(p, "0x0")) {
+        if (prec == PREC_FLOAT) {
+            ret->val = float_to_u64(0.0);
+        } else if (prec == PREC_DOUBLE) {
+            ret->val = double_to_u64(0.0);
+        } else {
+            g_assert_not_reached();
+        }
+        return 0;
+    } else if (!strcmp(p, "0x1")) {
+        if (prec == PREC_FLOAT) {
+            ret->val = float_to_u64(1.0);
+        } else if (prec == PREC_DOUBLE) {
+            ret->val = double_to_u64(1.0);
+        } else {
+            g_assert_not_reached();
+        }
+        return 0;
+    }
+    return 1;
+}
+
+static int find_op(const char *name, enum op *op)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(ops); i++) {
+        if (strcmp(ops[i].name, name) == 0) {
+            *op = i;
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/* Syntax of IBM FP test cases:
+ * https://www.research.ibm.com/haifa/projects/verification/fpgen/syntax.txt
+ */
+static enum error ibm_test_line(const char *line)
+{
+    struct test_op t;
+    /* at most nine fields; this should be more than enough for each field */
+    char s[9][64];
+    char *p;
+    int n, field;
+    int i;
+
+    /* data lines start with either b32 or d(64|128) */
+    if (unlikely(line[0] != 'b' && line[0] != 'd')) {
+        return ERROR_COMMENT;
+    }
+    n = sscanf(line, "%63s %63s %63s %63s %63s %63s %63s %63s %63s",
+               s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
+    if (unlikely(n < 5 || n > 9)) {
+        return ERROR_INPUT;
+    }
+
+    field = 0;
+    p = s[field];
+    if (unlikely(strlen(p) < 4)) {
+        return ERROR_INPUT;
+    }
+    if (strcmp("b32b64cff", p) == 0) {
+        t.prec = PREC_FLOAT_TO_DOUBLE;
+        if (find_op(&p[6], &t.op)) {
+            return ERROR_NOT_HANDLED;
+        }
+    } else {
+        if (strncmp("b32", p, 3) == 0) {
+            t.prec = PREC_FLOAT;
+        } else if (strncmp("d64", p, 3) == 0) {
+            t.prec = PREC_DOUBLE;
+        } else if (strncmp("d128", p, 4) == 0) {
+            return ERROR_NOT_HANDLED; /* XXX */
+        } else {
+            return ERROR_INPUT;
+        }
+        if (find_op(&p[3], &t.op)) {
+            return ERROR_NOT_HANDLED;
+        }
+    }
+
+    field = 1;
+    p = s[field];
+    if (!strncmp("=0", p, 2)) {
+        t.round = float_round_nearest_even;
+    } else {
+        return ERROR_NOT_HANDLED; /* XXX */
+    }
+
+    /* The trapped exceptions field is optional */
+    t.trapped_exceptions = 0;
+    field = 2;
+    p = s[field];
+    if (ibm_get_exceptions(p, &t.trapped_exceptions)) {
+        if (unlikely(n == 9)) {
+            return ERROR_INPUT;
+        }
+    } else {
+        field++;
+    }
+
+    for (i = 0; i < ops[t.op].n_operands; i++) {
+        enum precision prec = t.prec == PREC_FLOAT_TO_DOUBLE ?
+            PREC_FLOAT : t.prec;
+
+        p = s[field++];
+        if (ibm_fp_hex(p, prec, &t.operands[i])) {
+            return ERROR_INPUT;
+        }
+    }
+
+    p = s[field++];
+    if (strcmp("->", p)) {
+        return ERROR_INPUT;
+    }
+
+    p = s[field++];
+    if (unlikely(strcmp("#", p) == 0)) {
+        t.expected_result_is_valid = false;
+    } else {
+        enum precision prec = t.prec == PREC_FLOAT_TO_DOUBLE ?
+            PREC_DOUBLE : t.prec;
+
+        if (ibm_fp_hex(p, prec, &t.expected_result)) {
+            return ERROR_INPUT;
+        }
+        t.expected_result_is_valid = true;
+    }
+
+    /*
+     * A 0 here means "do not check the exceptions", i.e. it does NOT mean
+     * "there should be no exceptions raised".
+     */
+    t.exceptions = 0;
+    /* the expected exceptions field is optional */
+    if (field == n - 1) {
+        p = s[field++];
+        if (ibm_get_exceptions(p, &t.exceptions)) {
+            return ERROR_INPUT;
+        }
+    }
+
+    /*
+     * We ignore "trapped exceptions" because we're not testing the trapping
+     * mechanism of the host CPU.
+     * We test though that the exception bits are correctly set.
+     */
+    if (t.trapped_exceptions) {
+        return ERROR_NOT_HANDLED;
+    }
+    return tester->func(&t);
+}
+
+static const struct input valid_input_types[] = {
+    [INPUT_FMT_IBM] = {
+        .name = "ibm",
+        .test_line = ibm_test_line,
+    },
+};
+
+static const struct input *input_type = &valid_input_types[INPUT_FMT_IBM];
+
+static bool line_is_whitelisted(const char *line)
+{
+    if (whitelist.ht == NULL) {
+        return false;
+    }
+    return !!g_hash_table_lookup(whitelist.ht, line);
+}
+
+static void test_file(const char *filename)
+{
+    static char line[256];
+    unsigned int i;
+    FILE *fp;
+
+    fp = fopen(filename, "r");
+    if (fp == NULL) {
+        fprintf(stderr, "cannot open file '%s': %s\n",
+                filename, strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    i = 0;
+    while (fgets(line, sizeof(line), fp)) {
+        enum error err;
+
+        i++;
+        if (unlikely(line_is_whitelisted(line))) {
+            test_stats[ERROR_WHITELISTED]++;
+            continue;
+        }
+        err = input_type->test_line(line);
+        if (unlikely(is_err(err))) {
+            switch (err) {
+            case ERROR_INPUT:
+                fprintf(stderr, "error: malformed input @ %s:%d:\n",
+                        filename, i);
+                break;
+            case ERROR_RESULT:
+                fprintf(stderr, "error: result mismatch for input @ %s:%d:\n",
+                        filename, i);
+                break;
+            case ERROR_EXCEPTIONS:
+                fprintf(stderr, "error: flags mismatch for input @ %s:%d:\n",
+                        filename, i);
+                break;
+            default:
+                g_assert_not_reached();
+            }
+            fprintf(stderr, "%s", line);
+            if (die_on_error) {
+                exit(EXIT_FAILURE);
+            }
+        }
+        test_stats[err]++;
+    }
+    if (fclose(fp)) {
+        fprintf(stderr, "warning: cannot close file '%s': %s\n",
+                filename, strerror(errno));
+    }
+}
+
+static void set_input_fmt(const char *optarg)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(valid_input_types); i++) {
+        const struct input *type = &valid_input_types[i];
+
+        if (strcmp(optarg, type->name) == 0) {
+            input_type = type;
+            return;
+        }
+    }
+    fprintf(stderr, "Unknown input format '%s'", optarg);
+    exit(EXIT_FAILURE);
+}
+
+static void set_tester(const char *optarg)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(valid_testers); i++) {
+        const struct tester *t = &valid_testers[i];
+
+        if (strcmp(optarg, t->name) == 0) {
+            tester = t;
+            return;
+        }
+    }
+    fprintf(stderr, "Unknown tester '%s'", optarg);
+    exit(EXIT_FAILURE);
+}
+
+static void whitelist_add_line(const char *orig_line)
+{
+    char *line;
+    bool inserted;
+
+    if (whitelist.ht == NULL) {
+        whitelist.ht = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+    line = g_hash_table_lookup(whitelist.ht, orig_line);
+    if (unlikely(line != NULL)) {
+        return;
+    }
+    whitelist.n++;
+    whitelist.lines = g_realloc_n(whitelist.lines, whitelist.n, sizeof(line));
+    line = strdup(orig_line);
+    whitelist.lines[whitelist.n - 1] = line;
+    /* if we pass key == val GLib will not reserve space for the value */
+    inserted = g_hash_table_insert(whitelist.ht, line, line);
+    g_assert(inserted);
+}
+
+static void set_whitelist(const char *filename)
+{
+    FILE *fp;
+    static char line[256];
+
+    fp = fopen(filename, "r");
+    if (fp == NULL) {
+        fprintf(stderr, "warning: cannot open white list file '%s': %s\n",
+                filename, strerror(errno));
+        return;
+    }
+    while (fgets(line, sizeof(line), fp)) {
+        if (isspace(line[0]) || line[0] == '#') {
+            continue;
+        }
+        whitelist_add_line(line);
+    }
+    if (fclose(fp)) {
+        fprintf(stderr, "warning: cannot close file '%s': %s\n",
+                filename, strerror(errno));
+    }
+}
+
+static void set_default_exceptions(const char *str)
+{
+    if (ibm_get_exceptions(str, &default_exceptions)) {
+        fprintf(stderr, "Invalid exception '%s'\n", str);
+        exit(EXIT_FAILURE);
+    }
+}
+
+static void usage_complete(int argc, char *argv[])
+{
+    fprintf(stderr, "Usage: %s [options] file1 [file2 ...]\n", argv[0]);
+    fprintf(stderr, "options:\n");
+    fprintf(stderr, "  -a = Perform tininess detection after rounding "
+            "(soft tester only). Default: before\n");
+    fprintf(stderr, "  -n = do not die on error. Default: dies on error\n");
+    fprintf(stderr, "  -e = default exception flags (xiozu). Default: none\n");
+    fprintf(stderr, "  -f = format of the input file(s). Default: %s\n",
+            valid_input_types[0].name);
+    fprintf(stderr, "  -t = tester. Default: %s\n", valid_testers[0].name);
+    fprintf(stderr, "  -w = path to file with test cases to be whitelisted\n");
+    fprintf(stderr, "  -z = flush inputs to zero (soft tester only). "
+            "Default: disabled\n");
+    fprintf(stderr, "  -Z = flush output to zero (soft tester only). "
+            "Default: disabled\n");
+}
+
+static void parse_opts(int argc, char *argv[])
+{
+    int c;
+
+    for (;;) {
+        c = getopt(argc, argv, "ae:f:hnt:w:zZ");
+        if (c < 0) {
+            return;
+        }
+        switch (c) {
+        case 'a':
+            soft_status.float_detect_tininess = float_tininess_after_rounding;
+            break;
+        case 'e':
+            set_default_exceptions(optarg);
+            break;
+        case 'f':
+            set_input_fmt(optarg);
+            break;
+        case 'h':
+            usage_complete(argc, argv);
+            exit(EXIT_SUCCESS);
+        case 'n':
+            die_on_error = false;
+            break;
+        case 't':
+            set_tester(optarg);
+            break;
+        case 'w':
+            set_whitelist(optarg);
+            break;
+        case 'z':
+            soft_status.flush_inputs_to_zero = 1;
+            break;
+        case 'Z':
+            soft_status.flush_to_zero = 1;
+            break;
+        }
+    }
+    g_assert_not_reached();
+}
+
+static uint64_t count_errors(void)
+{
+    uint64_t ret = 0;
+    int i;
+
+    for (i = ERROR_INPUT; i < ERROR_MAX; i++) {
+        ret += test_stats[i];
+    }
+    return ret;
+}
+
+int main(int argc, char *argv[])
+{
+    uint64_t n_errors;
+    int i;
+
+    if (argc == 1) {
+        usage_complete(argc, argv);
+        exit(EXIT_FAILURE);
+    }
+    parse_opts(argc, argv);
+    for (i = optind; i < argc; i++) {
+        test_file(argv[i]);
+    }
+
+    n_errors = count_errors();
+    if (n_errors) {
+        printf("Tests failed: %"PRIu64". Parsing: %"PRIu64
+               ", result:%"PRIu64", flags:%"PRIu64"\n",
+               n_errors, test_stats[ERROR_INPUT], test_stats[ERROR_RESULT],
+               test_stats[ERROR_EXCEPTIONS]);
+    } else {
+        printf("All tests OK.\n");
+    }
+    printf("Tests passed: %" PRIu64 ". Not handled: %" PRIu64
+           ", whitelisted: %"PRIu64 "\n",
+           test_stats[ERROR_NONE], test_stats[ERROR_NOT_HANDLED],
+           test_stats[ERROR_WHITELISTED]);
+    return !!n_errors;
+}
diff --git a/tests/.gitignore b/tests/.gitignore
index df69175..f9b0f08 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -97,5 +97,6 @@ test-netfilter
 test-filter-mirror
 test-filter-redirector
 *-test
+!fp-test
 qapi-schema/*.test.*
 vm/*.img
diff --git a/tests/fp-test/.gitignore b/tests/fp-test/.gitignore
new file mode 100644
index 0000000..e1e175c
--- /dev/null
+++ b/tests/fp-test/.gitignore
@@ -0,0 +1,3 @@
+ibm
+whitelist.txt
+fp-test
diff --git a/tests/fp-test/Makefile b/tests/fp-test/Makefile
new file mode 100644
index 0000000..703434f
--- /dev/null
+++ b/tests/fp-test/Makefile
@@ -0,0 +1,34 @@
+BUILD_DIR=$(CURDIR)/../..
+
+include ../../config-host.mak
+include $(SRC_PATH)/rules.mak
+
+$(call set-vpath, $(SRC_PATH)/tests/fp-test $(SRC_PATH)/fpu)
+
+QEMU_INCLUDES += -I../..
+QEMU_INCLUDES += -I$(SRC_PATH)/fpu
+# work around TARGET_* poisoning
+QEMU_CFLAGS += -DHW_POISON_H
+
+IBMFP := ibm-fptests.zip
+
+OBJS := fp-test$(EXESUF)
+
+WHITELIST_FILES := whitelist.txt whitelist-tininess-after.txt
+
+all: $(OBJS) ibm $(WHITELIST_FILES)
+
+ibm:
+	wget -nv -O $(IBMFP) http://www.haifa.il.ibm.com/projects/verification/fpgen/download/test_suite.zip
+	mkdir -p $@
+	unzip $(IBMFP) -d $@
+	rm -rf $(IBMFP)
+
+# XXX: upload this to a qemu server, or just commit it.
+$(WHITELIST_FILES):
+	wget -nv -O $@ http://www.cs.columbia.edu/~cota/qemu/fpbench-$@
+
+fp-test$(EXESUF): fp-test.o softfloat.o
+
+clean:
+	rm -f *.o *.d $(OBJS)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27 10:15   ` Alex Bennée
  2018-03-27 10:15   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants Emilio G. Cota
                   ` (13 subsequent siblings)
  16 siblings, 2 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Before 8936006 ("fpu/softfloat: re-factor minmax", 2018-02-21),
we used to return +Zero for maxnummag(-Zero,+Zero); after that
commit, we return -Zero.

Fix it by making {min,max}nummag consistent with {min,max}num,
deferring to the latter when the absolute value of the operands
is the same.

With this fix we now pass fp-test.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 fpu/softfloat.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e124df9..ee615a9 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1700,7 +1700,6 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
         return pick_nan(a, b, s);
     } else {
         int a_exp, b_exp;
-        bool a_sign, b_sign;
 
         switch (a.cls) {
         case float_class_normal:
@@ -1731,20 +1730,22 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
             break;
         }
 
-        a_sign = a.sign;
-        b_sign = b.sign;
-        if (ismag) {
-            a_sign = b_sign = 0;
+        if (ismag && (a_exp != b_exp || a.frac != b.frac)) {
+            bool a_less = a_exp < b_exp;
+            if (a_exp == b_exp) {
+                a_less = a.frac < b.frac;
+            }
+            return a_less ^ ismin ? b : a;
         }
 
-        if (a_sign == b_sign) {
+        if (a.sign == b.sign) {
             bool a_less = a_exp < b_exp;
             if (a_exp == b_exp) {
                 a_less = a.frac < b.frac;
             }
-            return a_sign ^ a_less ^ ismin ? b : a;
+            return a.sign ^ a_less ^ ismin ? b : a;
         } else {
-            return a_sign ^ ismin ? b : a;
+            return a.sign ^ ismin ? b : a;
         }
     }
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (2 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27 11:33   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal Emilio G. Cota
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

These are a few muladd-related operations that the original IBM syntax
does not specify; model files for these are in muladd.fptest.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 tests/fp-test/fp-test.c     | 24 +++++++++++++++++++++
 tests/fp-test/muladd.fptest | 51 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 tests/fp-test/muladd.fptest

diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
index 27637c4..2200d40 100644
--- a/tests/fp-test/fp-test.c
+++ b/tests/fp-test/fp-test.c
@@ -53,6 +53,9 @@ enum op {
     OP_SUB,
     OP_MUL,
     OP_MULADD,
+    OP_MULADD_NEG_ADDEND,
+    OP_MULADD_NEG_PRODUCT,
+    OP_MULADD_NEG_RESULT,
     OP_DIV,
     OP_SQRT,
     OP_MINNUM,
@@ -69,6 +72,9 @@ static const struct op_desc ops[] = {
     [OP_SUB] =       { "-", 2 },
     [OP_MUL] =       { "*", 2 },
     [OP_MULADD] =    { "*+", 3 },
+    [OP_MULADD_NEG_ADDEND] =  { "*+nc", 3 },
+    [OP_MULADD_NEG_PRODUCT] = { "*+np", 3 },
+    [OP_MULADD_NEG_RESULT] =  { "*+nr", 3 },
     [OP_DIV] =       { "/", 2 },
     [OP_SQRT] =      { "V", 1 },
     [OP_MINNUM] =    { "<C", 2 },
@@ -463,6 +469,15 @@ static enum error soft_tester(struct test_op *t)
         case OP_MULADD:
             res = float32_muladd(a, b, c, 0, s);
             break;
+        case OP_MULADD_NEG_ADDEND:
+            res = float32_muladd(a, b, c, float_muladd_negate_c, s);
+            break;
+        case OP_MULADD_NEG_PRODUCT:
+            res = float32_muladd(a, b, c, float_muladd_negate_product, s);
+            break;
+        case OP_MULADD_NEG_RESULT:
+            res = float32_muladd(a, b, c, float_muladd_negate_result, s);
+            break;
         case OP_DIV:
             res = float32_div(a, b, s);
             break;
@@ -522,6 +537,15 @@ static enum error soft_tester(struct test_op *t)
         case OP_MULADD:
             res64 = float64_muladd(a, b, c, 0, s);
             break;
+        case OP_MULADD_NEG_ADDEND:
+            res64 = float64_muladd(a, b, c, float_muladd_negate_c, s);
+            break;
+        case OP_MULADD_NEG_PRODUCT:
+            res64 = float64_muladd(a, b, c, float_muladd_negate_product, s);
+            break;
+        case OP_MULADD_NEG_RESULT:
+            res64 = float64_muladd(a, b, c, float_muladd_negate_result, s);
+            break;
         case OP_DIV:
             res64 = float64_div(a, b, s);
             break;
diff --git a/tests/fp-test/muladd.fptest b/tests/fp-test/muladd.fptest
new file mode 100644
index 0000000..6cd48ff
--- /dev/null
+++ b/tests/fp-test/muladd.fptest
@@ -0,0 +1,51 @@
+# nc == negate addend
+b32*+nc =0 -Inf -Inf +Inf -> Q i
+b32*+nc =0 -1.7FFFFFP127 -Inf +Inf -> Q i
+b32*+nc =0 -1.6C9AE7P113 -Inf +Inf -> Q i
+b32*+nc =0 -1.000000P-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.7FFFFFP-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.1B977AP-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.000001P-126 -Inf +Inf -> Q i
+b32*+nc =0 -1.000000P0 -Inf +Inf -> Q i
+b32*+nc =0 -Zero -Inf +Inf -> Q i
+b32*+nc =0 +Zero -Inf +Inf -> Q i
+b32*+nc =0 -Zero -1.000000P-126 +1.7FFFFFP127 -> -1.7FFFFFP127
+b32*+nc =0 +Zero -1.000000P-126 +1.7FFFFFP127 -> -1.7FFFFFP127
+b32*+nc =0 -1.000000P-126 -1.7FFFFFP127 -1.4B9156P109 -> +1.4B9156P109 x
+b32*+nc =0 -0.7FFFFFP-126 -1.7FFFFFP127 -1.51BA59P-113 -> +1.7FFFFDP1 x
+b32*+nc =0 -0.3D6B57P-126 -1.7FFFFFP127 -1.265398P-67 -> +1.75AD5BP0 x
+b32*+nc =0 -0.000001P-126 -1.7FFFFFP127 -1.677330P-113 -> +1.7FFFFFP-22 x
+
+# np == negate product
+b32*+np =0 +Inf -Inf -Inf -> Q i
+b32*+np =0 +1.7FFFFFP127 -Inf -Inf -> Q i
+b32*+np =0 +1.6C9AE7P113 -Inf -Inf -> Q i
+b32*+np =0 +1.000000P-126 -Inf -Inf -> Q i
+b32*+np =0 +0.7FFFFFP-126 -Inf -Inf -> Q i
+b32*+np =0 +0.1B977AP-126 -Inf -Inf -> Q i
+b32*+np =0 +0.000001P-126 -Inf -Inf -> Q i
+b32*+np =0 +1.000000P0 -Inf -Inf -> Q i
+b32*+np =0 +Zero -Inf -Inf -> Q i
+b32*+np =0 +Zero -Inf -Inf -> Q i
+b32*+np =0 -Zero -1.000000P-126 -1.7FFFFFP127 -> -1.7FFFFFP127
+b32*+np =0 +Zero -1.000000P-126 -1.7FFFFFP127 -> -1.7FFFFFP127
+b32*+np =0 -1.3A6A89P-18 +1.24E7AEP9 -0.7FFFFFP-126 -> +1.7029E9P-9 x
+
+# nr == negate result
+b32*+nr =0 -Inf -Inf -Inf -> Q i
+b32*+nr =0 -1.7FFFFFP127 -Inf -Inf -> Q i
+b32*+nr =0 -1.6C9AE7P113 -Inf -Inf -> Q i
+b32*+nr =0 -1.000000P-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.7FFFFFP-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.1B977AP-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.000001P-126 -Inf -Inf -> Q i
+b32*+nr =0 -1.000000P0 -Inf -Inf -> Q i
+b32*+nr =0 -Zero -Inf -Inf -> Q i
+b32*+nr =0 -Zero -Inf -Inf -> Q i
+b32*+nr =0 +Zero -1.000000P-126 -1.7FFFFFP127 -> +1.7FFFFFP127
+b32*+nr =0 -Zero -1.000000P-126 -1.7FFFFFP127 -> +1.7FFFFFP127
+b32*+nr =0 -1.000000P-126 -1.7FFFFFP127 -1.4B9156P109 -> +1.4B9156P109 x
+b32*+nr =0 -0.7FFFFFP-126 -1.7FFFFFP127 -1.51BA59P-113 -> -1.7FFFFDP1 x
+b32*+nr =0 -0.3D6B57P-126 -1.7FFFFFP127 -1.265398P-67 -> -1.75AD5BP0 x
+b32*+nr =0 -0.000001P-126 -1.7FFFFFP127 -1.677330P-113 -> -1.7FFFFFP-22 x
+b32*+nr =0 +1.72E53AP-33 -1.7FFFFFP127 -1.5AA684P-2 -> +1.72E539P95 x
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (3 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27 11:34   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal Emilio G. Cota
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

This paves the way for upcoming work.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/softfloat.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 36626a5..7b9d31c 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -402,6 +402,11 @@ static inline int float32_is_zero(float32 a)
     return (float32_val(a) & 0x7fffffff) == 0;
 }
 
+static inline bool float32_is_normal(float32 a)
+{
+    return ((float32_val(a) + 0x00800000) & 0x7fffffff) >= 0x01000000;
+}
+
 static inline int float32_is_any_nan(float32 a)
 {
     return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
@@ -531,6 +536,11 @@ static inline int float64_is_zero(float64 a)
     return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
 }
 
+static inline bool float64_is_normal(float64 a)
+{
+    return ((float64_val(a) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
+}
+
 static inline int float64_is_any_nan(float64 a)
 {
     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (4 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-27 11:35   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat Emilio G. Cota
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

This paves the way for upcoming work.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/softfloat.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 7b9d31c..8fb44a8 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -417,6 +417,11 @@ static inline int float32_is_zero_or_denormal(float32 a)
     return (float32_val(a) & 0x7f800000) == 0;
 }
 
+static inline bool float32_is_denormal(float32 a)
+{
+    return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
+}
+
 static inline float32 float32_set_sign(float32 a, int sign)
 {
     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
@@ -551,6 +556,11 @@ static inline int float64_is_zero_or_denormal(float64 a)
     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
 }
 
+static inline bool float64_is_denormal(float64 a)
+{
+    return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
+}
+
 static inline float64 float64_set_sign(float64 a, int sign)
 {
     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (5 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:41   ` Laurent Vivier
  2018-03-27 11:49   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction Emilio G. Cota
                   ` (9 subsequent siblings)
  16 siblings, 2 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

The appended paves the way for leveraging the host FPU for a subset
of guest FP operations. For most guest workloads (e.g. FP flags
aren't ever cleared, inexact occurs often and rounding is set to the
default [to nearest]) this will yield sizable performance speedups.

The approach followed here avoids checking the FP exception flags register.
See the comment at the top of hostfloat.c for details.

This assumes that QEMU is running on an IEEE754-compliant FPU and
that the rounding is set to the default (to nearest). The
implementation-dependent specifics of the FPU should not matter; things
like tininess detection and snan representation are still dealt with in
soft-fp. However, this approach will break on most hosts if we compile
QEMU with flags such as -ffast-math. We control the flags so this should
be easy to enforce though.

The licensing in softfloat.h is complicated at best, so to keep things
simple I'm adding this as a separate, GPL'ed file.

This patch just adds some boilerplate code; subsequent patches add
operations, one per commit to ease bisection.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 Makefile.target           |  2 +-
 include/fpu/hostfloat.h   | 14 +++++++
 include/fpu/softfloat.h   |  1 +
 fpu/hostfloat.c           | 96 +++++++++++++++++++++++++++++++++++++++++++++++
 target/m68k/Makefile.objs |  2 +-
 tests/fp-test/Makefile    |  2 +-
 6 files changed, 114 insertions(+), 3 deletions(-)
 create mode 100644 include/fpu/hostfloat.h
 create mode 100644 fpu/hostfloat.c

diff --git a/Makefile.target b/Makefile.target
index 6549481..efcdfb9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -97,7 +97,7 @@ obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o
 obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
-obj-y += fpu/softfloat.o
+obj-y += fpu/softfloat.o fpu/hostfloat.o
 obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
new file mode 100644
index 0000000..b01291b
--- /dev/null
+++ b/include/fpu/hostfloat.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef HOSTFLOAT_H
+#define HOSTFLOAT_H
+
+#ifndef SOFTFLOAT_H
+#error fpu/hostfloat.h must only be included from softfloat.h
+#endif
+
+#endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 8fb44a8..8963b68 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -95,6 +95,7 @@ enum {
 };
 
 #include "fpu/softfloat-types.h"
+#include "fpu/hostfloat.h"
 
 static inline void set_float_detect_tininess(int val, float_status *status)
 {
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
new file mode 100644
index 0000000..cab0341
--- /dev/null
+++ b/fpu/hostfloat.c
@@ -0,0 +1,96 @@
+/*
+ * hostfloat.c - FP primitives that use the host's FPU whenever possible.
+ *
+ * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ *
+ * Fast emulation of guest FP instructions is challenging for two reasons.
+ * First, FP instruction semantics are similar but not identical, particularly
+ * when handling NaNs. Second, emulating at reasonable speed the guest FP
+ * exception flags is not trivial: reading the host's flags register with a
+ * feclearexcept & fetestexcept pair is slow [slightly slower than soft-fp],
+ * and trapping on every FP exception is not fast nor pleasant to work with.
+ *
+ * This module leverages the host FPU for a subset of the operations. To
+ * do this it follows the main idea presented in this paper:
+ *
+ * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions in a
+ * binary translator." Software: Practice and Experience 46.12 (2016):1591-1615.
+ *
+ * The idea is thus to leverage the host FPU to (1) compute FP operations
+ * and (2) identify whether FP exceptions occurred while avoiding
+ * expensive exception flag register accesses.
+ *
+ * An important optimization shown in the paper is that given that exception
+ * flags are rarely cleared by the guest, we can avoid recomputing some flags.
+ * This is particularly useful for the inexact flag, which is very frequently
+ * raised in floating-point workloads.
+ *
+ * We optimize the code further by deferring to soft-fp whenever FP
+ * exception detection might get hairy. Fortunately this is not common.
+ */
+#include <math.h>
+
+#include "qemu/osdep.h"
+#include "fpu/softfloat.h"
+
+#define GEN_TYPE_CONV(name, to_t, from_t)       \
+    static inline to_t name(from_t a)           \
+    {                                           \
+        to_t r = *(to_t *)&a;                   \
+        return r;                               \
+    }
+
+GEN_TYPE_CONV(float32_to_float, float, float32)
+GEN_TYPE_CONV(float64_to_double, double, float64)
+GEN_TYPE_CONV(float_to_float32, float32, float)
+GEN_TYPE_CONV(double_to_float64, float64, double)
+#undef GEN_TYPE_CONV
+
+#define GEN_INPUT_FLUSH(soft_t)                                         \
+    static inline __attribute__((always_inline)) void                   \
+    soft_t ## _input_flush__nocheck(soft_t *a, float_status *s)         \
+    {                                                                   \
+        if (unlikely(soft_t ## _is_denormal(*a))) {                     \
+            *a = soft_t ## _set_sign(soft_t ## _zero,                   \
+                                     soft_t ## _is_neg(*a));            \
+            s->float_exception_flags |= float_flag_input_denormal;      \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    static inline __attribute__((always_inline)) void                   \
+    soft_t ## _input_flush1(soft_t *a, float_status *s)                 \
+    {                                                                   \
+        if (likely(!s->flush_inputs_to_zero)) {                         \
+            return;                                                     \
+        }                                                               \
+        soft_t ## _input_flush__nocheck(a, s);                          \
+    }                                                                   \
+                                                                        \
+    static inline __attribute__((always_inline)) void                   \
+    soft_t ## _input_flush2(soft_t *a, soft_t *b, float_status *s)      \
+    {                                                                   \
+        if (likely(!s->flush_inputs_to_zero)) {                         \
+            return;                                                     \
+        }                                                               \
+        soft_t ## _input_flush__nocheck(a, s);                          \
+        soft_t ## _input_flush__nocheck(b, s);                          \
+    }                                                                   \
+                                                                        \
+    static inline __attribute__((always_inline)) void                   \
+    soft_t ## _input_flush3(soft_t *a, soft_t *b, soft_t *c,            \
+                            float_status *s)                            \
+    {                                                                   \
+        if (likely(!s->flush_inputs_to_zero)) {                         \
+            return;                                                     \
+        }                                                               \
+        soft_t ## _input_flush__nocheck(a, s);                          \
+        soft_t ## _input_flush__nocheck(b, s);                          \
+        soft_t ## _input_flush__nocheck(c, s);                          \
+    }
+
+GEN_INPUT_FLUSH(float32)
+GEN_INPUT_FLUSH(float64)
+#undef GEN_INPUT_FLUSH
diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
index ac61948..2868b11 100644
--- a/target/m68k/Makefile.objs
+++ b/target/m68k/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += m68k-semi.o
 obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += fpu_helper.o softfloat.o
+obj-y += fpu_helper.o softfloat.o hostfloat.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += monitor.o
diff --git a/tests/fp-test/Makefile b/tests/fp-test/Makefile
index 703434f..187cfcc 100644
--- a/tests/fp-test/Makefile
+++ b/tests/fp-test/Makefile
@@ -28,7 +28,7 @@ ibm:
 $(WHITELIST_FILES):
 	wget -nv -O $@ http://www.cs.columbia.edu/~cota/qemu/fpbench-$@
 
-fp-test$(EXESUF): fp-test.o softfloat.o
+fp-test$(EXESUF): fp-test.o softfloat.o hostfloat.o
 
 clean:
 	rm -f *.o *.d $(OBJS)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (6 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-22  5:05   ` Richard Henderson
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 09/14] hostfloat: support float32/64 multiplication Emilio G. Cota
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Performance results (single and double precision) for
fp-bench run under aarch64-linux-user on an Intel(R)
Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
add-single: 86.74 MFlops
add-double: 86.46 MFlops
sub-single: 83.33 MFlops
sub-double: 84.57 MFlops

- after:
add-single: 188.26 MFlops
add-double: 186.60 MFlops
sub-single: 186.19 MFlops
sub-double: 187.77 MFlops

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  6 ++++++
 include/fpu/softfloat.h |  8 ++++----
 fpu/hostfloat.c         | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c         | 16 ++++++++--------
 4 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index b01291b..db49efa 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -11,4 +11,10 @@
 #error fpu/hostfloat.h must only be included from softfloat.h
 #endif
 
+float32 float32_add(float32 a, float32 b, float_status *status);
+float32 float32_sub(float32 a, float32 b, float_status *status);
+
+float64 float64_add(float64 a, float64 b, float_status *status);
+float64 float64_sub(float64 a, float64 b, float_status *status);
+
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 8963b68..eb7e9bc 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -342,8 +342,8 @@ float128 float32_to_float128(float32, float_status *status);
 | Software IEC/IEEE single-precision operations.
 *----------------------------------------------------------------------------*/
 float32 float32_round_to_int(float32, float_status *status);
-float32 float32_add(float32, float32, float_status *status);
-float32 float32_sub(float32, float32, float_status *status);
+float32 soft_float32_add(float32, float32, float_status *status);
+float32 soft_float32_sub(float32, float32, float_status *status);
 float32 float32_mul(float32, float32, float_status *status);
 float32 float32_div(float32, float32, float_status *status);
 float32 float32_rem(float32, float32, float_status *status);
@@ -482,8 +482,8 @@ float128 float64_to_float128(float64, float_status *status);
 *----------------------------------------------------------------------------*/
 float64 float64_round_to_int(float64, float_status *status);
 float64 float64_trunc_to_int(float64, float_status *status);
-float64 float64_add(float64, float64, float_status *status);
-float64 float64_sub(float64, float64, float_status *status);
+float64 soft_float64_add(float64, float64, float_status *status);
+float64 soft_float64_sub(float64, float64, float_status *status);
 float64 float64_mul(float64, float64, float_status *status);
 float64 float64_div(float64, float64, float_status *status);
 float64 float64_rem(float64, float64, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index cab0341..502552b 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -94,3 +94,53 @@ GEN_TYPE_CONV(double_to_float64, float64, double)
 GEN_INPUT_FLUSH(float32)
 GEN_INPUT_FLUSH(float64)
 #undef GEN_INPUT_FLUSH
+
+#define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
+                       host_abs_func, min_normal)                       \
+    static inline __attribute__((always_inline)) soft_t                 \
+    fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,        \
+                              float_status *s)                          \
+    {                                                                   \
+        soft_t ## _input_flush2(&a, &b, s);                             \
+        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+                   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+                   s->float_exception_flags & float_flag_inexact &&     \
+                   s->float_rounding_mode == float_round_nearest_even)) { \
+            host_t ha = soft_t ## _to_ ## host_t(a);                    \
+            host_t hb = soft_t ## _to_ ## host_t(b);                    \
+            host_t hr;                                                  \
+            soft_t r;                                                   \
+                                                                        \
+            if (subtract) {                                             \
+                hb = -hb;                                               \
+            }                                                           \
+            hr = ha + hb;                                               \
+            r = host_t ## _to_ ## soft_t(hr);                           \
+            if (unlikely(soft_t ## _is_infinity(r))) {                  \
+                s->float_exception_flags |= float_flag_overflow;        \
+            } else if (unlikely(host_abs_func(hr) <= min_normal)) {     \
+                goto soft;                                              \
+            }                                                           \
+            return r;                                                   \
+        }                                                               \
+    soft:                                                               \
+        if (subtract) {                                                 \
+            return soft_ ## soft_t ## _sub(a, b, s);                    \
+        } else {                                                        \
+            return soft_ ## soft_t ## _add(a, b, s);                    \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    soft_t add_name(soft_t a, soft_t b, float_status *status)           \
+    {                                                                   \
+        return fpu_ ## soft_t ## _addsub(a, b, false, status);          \
+    }                                                                   \
+                                                                        \
+    soft_t sub_name(soft_t a, soft_t b, float_status *status)           \
+    {                                                                   \
+        return fpu_ ## soft_t ## _addsub(a, b, true, status);           \
+    }                                                                   \
+
+GEN_FPU_ADDSUB(float32_add, float32_sub, float32, float, fabsf, FLT_MIN)
+GEN_FPU_ADDSUB(float64_add, float64_sub, float64, double, fabs, DBL_MIN)
+#undef GEN_FPU_ADDSUB
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ee615a9..bd82adf 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -738,8 +738,8 @@ float16  __attribute__((flatten)) float16_add(float16 a, float16 b,
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_add(float32 a, float32 b,
-                                             float_status *status)
+float32 __attribute__((flatten)) soft_float32_add(float32 a, float32 b,
+                                                  float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pb = float32_unpack_canonical(b, status);
@@ -748,8 +748,8 @@ float32 __attribute__((flatten)) float32_add(float32 a, float32 b,
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_add(float64 a, float64 b,
-                                             float_status *status)
+float64 __attribute__((flatten)) soft_float64_add(float64 a, float64 b,
+                                                  float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
@@ -768,8 +768,8 @@ float16 __attribute__((flatten)) float16_sub(float16 a, float16 b,
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_sub(float32 a, float32 b,
-                                             float_status *status)
+float32 __attribute__((flatten)) soft_float32_sub(float32 a, float32 b,
+                                                  float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pb = float32_unpack_canonical(b, status);
@@ -778,8 +778,8 @@ float32 __attribute__((flatten)) float32_sub(float32 a, float32 b,
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_sub(float64 a, float64 b,
-                                             float_status *status)
+float64 __attribute__((flatten)) soft_float64_sub(float64 a, float64 b,
+                                                  float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 09/14] hostfloat: support float32/64 multiplication
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (7 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 10/14] hostfloat: support float32/64 division Emilio G. Cota
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Note that special-casing "a_is_zero || b_is_zero" pays off--see
the last patch in this series for performance numbers on that.

Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
mul-single: 86.17 MFlops
mul-double: 87.74 MFlops

- after:
mul-single: 114.74 MFlops
mul-double: 112.33 MFlops

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  2 ++
 include/fpu/softfloat.h |  4 ++--
 fpu/hostfloat.c         | 34 ++++++++++++++++++++++++++++++++++
 fpu/softfloat.c         |  8 ++++----
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index db49efa..7049f7e 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -13,8 +13,10 @@
 
 float32 float32_add(float32 a, float32 b, float_status *status);
 float32 float32_sub(float32 a, float32 b, float_status *status);
+float32 float32_mul(float32 a, float32 b, float_status *status);
 
 float64 float64_add(float64 a, float64 b, float_status *status);
 float64 float64_sub(float64 a, float64 b, float_status *status);
+float64 float64_mul(float64 a, float64 b, float_status *status);
 
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index eb7e9bc..2b07ae8 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -344,7 +344,7 @@ float128 float32_to_float128(float32, float_status *status);
 float32 float32_round_to_int(float32, float_status *status);
 float32 soft_float32_add(float32, float32, float_status *status);
 float32 soft_float32_sub(float32, float32, float_status *status);
-float32 float32_mul(float32, float32, float_status *status);
+float32 soft_float32_mul(float32, float32, float_status *status);
 float32 float32_div(float32, float32, float_status *status);
 float32 float32_rem(float32, float32, float_status *status);
 float32 float32_muladd(float32, float32, float32, int, float_status *status);
@@ -484,7 +484,7 @@ float64 float64_round_to_int(float64, float_status *status);
 float64 float64_trunc_to_int(float64, float_status *status);
 float64 soft_float64_add(float64, float64, float_status *status);
 float64 soft_float64_sub(float64, float64, float_status *status);
-float64 float64_mul(float64, float64, float_status *status);
+float64 soft_float64_mul(float64, float64, float_status *status);
 float64 float64_div(float64, float64, float_status *status);
 float64 float64_rem(float64, float64, float_status *status);
 float64 float64_muladd(float64, float64, float64, int, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index 502552b..985d6f1 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -144,3 +144,37 @@ GEN_INPUT_FLUSH(float64)
 GEN_FPU_ADDSUB(float32_add, float32_sub, float32, float, fabsf, FLT_MIN)
 GEN_FPU_ADDSUB(float64_add, float64_sub, float64, double, fabs, DBL_MIN)
 #undef GEN_FPU_ADDSUB
+
+#define GEN_FPU_MUL(name, soft_t, host_t, host_abs_func, min_normal)    \
+    soft_t name(soft_t a, soft_t b, float_status *s)                    \
+    {                                                                   \
+        soft_t ## _input_flush2(&a, &b, s);                             \
+        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+                   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+                   s->float_exception_flags & float_flag_inexact &&     \
+                   s->float_rounding_mode == float_round_nearest_even)) { \
+            if (soft_t ## _is_zero(a) || soft_t ## _is_zero(b)) {       \
+                bool signbit = soft_t ## _is_neg(a) ^ soft_t ## _is_neg(b); \
+                                                                        \
+                return soft_t ## _set_sign(soft_t ## _zero, signbit);   \
+            } else {                                                    \
+                host_t ha = soft_t ## _to_ ## host_t(a);                \
+                host_t hb = soft_t ## _to_ ## host_t(b);                \
+                host_t hr = ha * hb;                                    \
+                soft_t r = host_t ## _to_ ## soft_t(hr);                \
+                                                                        \
+                if (unlikely(soft_t ## _is_infinity(r))) {              \
+                    s->float_exception_flags |= float_flag_overflow;    \
+                } else if (unlikely(host_abs_func(hr) <= min_normal)) { \
+                    goto soft;                                          \
+                }                                                       \
+                return r;                                               \
+            }                                                           \
+        }                                                               \
+    soft:                                                               \
+        return soft_ ## soft_t ## _mul(a, b, s);                        \
+    }
+
+GEN_FPU_MUL(float32_mul, float32, float, fabsf, FLT_MIN)
+GEN_FPU_MUL(float64_mul, float64, double, fabs, DBL_MIN)
+#undef GEN_FPU_MUL
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index bd82adf..e3f2918 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -849,8 +849,8 @@ float16 __attribute__((flatten)) float16_mul(float16 a, float16 b,
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_mul(float32 a, float32 b,
-                                             float_status *status)
+float32 __attribute__((flatten))
+soft_float32_mul(float32 a, float32 b, float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pb = float32_unpack_canonical(b, status);
@@ -859,8 +859,8 @@ float32 __attribute__((flatten)) float32_mul(float32 a, float32 b,
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_mul(float64 a, float64 b,
-                                             float_status *status)
+float64 __attribute__((flatten))
+soft_float64_mul(float64 a, float64 b, float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 10/14] hostfloat: support float32/64 division
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (8 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 09/14] hostfloat: support float32/64 multiplication Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 11/14] hostfloat: support float32/64 fused multiply-add Emilio G. Cota
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
div-single: 29.77 MFlops
div-double: 29.85 MFlops

- after:
div-single: 85.90 MFlops
div-double: 86.10 MFlops

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  2 ++
 include/fpu/softfloat.h |  4 ++--
 fpu/hostfloat.c         | 28 ++++++++++++++++++++++++++++
 fpu/softfloat.c         |  4 ++--
 4 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index 7049f7e..61a8525 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -14,9 +14,11 @@
 float32 float32_add(float32 a, float32 b, float_status *status);
 float32 float32_sub(float32 a, float32 b, float_status *status);
 float32 float32_mul(float32 a, float32 b, float_status *status);
+float32 float32_div(float32 a, float32 b, float_status *status);
 
 float64 float64_add(float64 a, float64 b, float_status *status);
 float64 float64_sub(float64 a, float64 b, float_status *status);
 float64 float64_mul(float64 a, float64 b, float_status *status);
+float64 float64_div(float64 a, float64 b, float_status *status);
 
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 2b07ae8..a690a57 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -345,7 +345,7 @@ float32 float32_round_to_int(float32, float_status *status);
 float32 soft_float32_add(float32, float32, float_status *status);
 float32 soft_float32_sub(float32, float32, float_status *status);
 float32 soft_float32_mul(float32, float32, float_status *status);
-float32 float32_div(float32, float32, float_status *status);
+float32 soft_float32_div(float32, float32, float_status *status);
 float32 float32_rem(float32, float32, float_status *status);
 float32 float32_muladd(float32, float32, float32, int, float_status *status);
 float32 float32_sqrt(float32, float_status *status);
@@ -485,7 +485,7 @@ float64 float64_trunc_to_int(float64, float_status *status);
 float64 soft_float64_add(float64, float64, float_status *status);
 float64 soft_float64_sub(float64, float64, float_status *status);
 float64 soft_float64_mul(float64, float64, float_status *status);
-float64 float64_div(float64, float64, float_status *status);
+float64 soft_float64_div(float64, float64, float_status *status);
 float64 float64_rem(float64, float64, float_status *status);
 float64 float64_muladd(float64, float64, float64, int, float_status *status);
 float64 float64_sqrt(float64, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index 985d6f1..ff980ac 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -178,3 +178,31 @@ GEN_FPU_ADDSUB(float64_add, float64_sub, float64, double, fabs, DBL_MIN)
 GEN_FPU_MUL(float32_mul, float32, float, fabsf, FLT_MIN)
 GEN_FPU_MUL(float64_mul, float64, double, fabs, DBL_MIN)
 #undef GEN_FPU_MUL
+
+#define GEN_FPU_DIV(name, soft_t, host_t, host_abs_func, min_normal)    \
+    soft_t name(soft_t a, soft_t b, float_status *s)                    \
+    {                                                                   \
+        soft_t ## _input_flush2(&a, &b, s);                             \
+        if (likely(soft_t ## _is_normal(a) &&                           \
+                   soft_t ## _is_normal(b) &&                           \
+                   s->float_exception_flags & float_flag_inexact &&     \
+                   s->float_rounding_mode == float_round_nearest_even)) { \
+            host_t ha = soft_t ## _to_ ## host_t(a);                    \
+            host_t hb = soft_t ## _to_ ## host_t(b);                    \
+            host_t hr = ha / hb;                                        \
+            soft_t r = host_t ## _to_ ## soft_t(hr);                    \
+                                                                        \
+            if (unlikely(soft_t ## _is_infinity(r))) {                  \
+                s->float_exception_flags |= float_flag_overflow;        \
+            } else if (unlikely(host_abs_func(hr) <= min_normal)) {     \
+                goto soft;                                              \
+            }                                                           \
+            return r;                                                   \
+        }                                                               \
+     soft:                                                              \
+        return soft_ ## soft_t ## _div(a, b, s);                        \
+    }
+
+GEN_FPU_DIV(float32_div, float32, float, fabsf, FLT_MIN)
+GEN_FPU_DIV(float64_div, float64, double, fabs, DBL_MIN)
+#undef GEN_FPU_DIV
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e3f2918..ebc59be 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1176,7 +1176,7 @@ float16 float16_div(float16 a, float16 b, float_status *status)
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 float32_div(float32 a, float32 b, float_status *status)
+float32 soft_float32_div(float32 a, float32 b, float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pb = float32_unpack_canonical(b, status);
@@ -1185,7 +1185,7 @@ float32 float32_div(float32 a, float32 b, float_status *status)
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 float64_div(float64 a, float64 b, float_status *status)
+float64 soft_float64_div(float64 a, float64 b, float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 11/14] hostfloat: support float32/64 fused multiply-add
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (9 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 10/14] hostfloat: support float32/64 division Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root Emilio G. Cota
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Note that special-casing "a_is_zero || b_is_zero" pays off--see
the last patch in this series for performance numbers on that.

Performance results for fp-bench run under aarch64-linux-user
on an aarch64 host:

- before:
fma-single: 53.05 MFlops
fma-double: 51.89 MFlops

- after:
fma-single: 113.93 MFlops
fma-double: 113.04 MFlops

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  2 ++
 include/fpu/softfloat.h |  4 ++--
 fpu/hostfloat.c         | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c         | 10 ++++----
 4 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index 61a8525..c006576 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -15,10 +15,12 @@ float32 float32_add(float32 a, float32 b, float_status *status);
 float32 float32_sub(float32 a, float32 b, float_status *status);
 float32 float32_mul(float32 a, float32 b, float_status *status);
 float32 float32_div(float32 a, float32 b, float_status *status);
+float32 float32_muladd(float32 a, float32 b, float32 c, int f, float_status *s);
 
 float64 float64_add(float64 a, float64 b, float_status *status);
 float64 float64_sub(float64 a, float64 b, float_status *status);
 float64 float64_mul(float64 a, float64 b, float_status *status);
 float64 float64_div(float64 a, float64 b, float_status *status);
+float64 float64_muladd(float64 a, float64 b, float64 c, int f, float_status *s);
 
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index a690a57..866bd3b 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -347,7 +347,7 @@ float32 soft_float32_sub(float32, float32, float_status *status);
 float32 soft_float32_mul(float32, float32, float_status *status);
 float32 soft_float32_div(float32, float32, float_status *status);
 float32 float32_rem(float32, float32, float_status *status);
-float32 float32_muladd(float32, float32, float32, int, float_status *status);
+float32 soft_float32_muladd(float32, float32, float32, int, float_status *s);
 float32 float32_sqrt(float32, float_status *status);
 float32 float32_exp2(float32, float_status *status);
 float32 float32_log2(float32, float_status *status);
@@ -487,7 +487,7 @@ float64 soft_float64_sub(float64, float64, float_status *status);
 float64 soft_float64_mul(float64, float64, float_status *status);
 float64 soft_float64_div(float64, float64, float_status *status);
 float64 float64_rem(float64, float64, float_status *status);
-float64 float64_muladd(float64, float64, float64, int, float_status *status);
+float64 soft_float64_muladd(float64, float64, float64, int, float_status *s);
 float64 float64_sqrt(float64, float_status *status);
 float64 float64_log2(float64, float_status *status);
 int float64_eq(float64, float64, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index ff980ac..a56b70a 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -206,3 +206,67 @@ GEN_FPU_MUL(float64_mul, float64, double, fabs, DBL_MIN)
 GEN_FPU_DIV(float32_div, float32, float, fabsf, FLT_MIN)
 GEN_FPU_DIV(float64_div, float64, double, fabs, DBL_MIN)
 #undef GEN_FPU_DIV
+
+/*
+ * When (a || b) == 0, there's no need to check for overflow, since we
+ * know the addend is normal || zero and the product is zero.
+ */
+#define GEN_FPU_FMA(name, soft_t, host_t, host_fma_f, host_abs_f, min_normal) \
+    soft_t name(soft_t a, soft_t b, soft_t c, int flags, float_status *s) \
+    {                                                                   \
+        soft_t ## _input_flush3(&a, &b, &c, s);                         \
+        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+                   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+                   (soft_t ## _is_normal(c) || soft_t ## _is_zero(c)) && \
+                   !(flags & float_muladd_halve_result) &&              \
+                   s->float_exception_flags & float_flag_inexact &&     \
+                   s->float_rounding_mode == float_round_nearest_even)) { \
+            if (soft_t ## _is_zero(a) || soft_t ## _is_zero(b)) {       \
+                soft_t p, r;                                            \
+                host_t hp, hc, hr;                                      \
+                bool prod_sign;                                         \
+                                                                        \
+                prod_sign = soft_t ## _is_neg(a) ^ soft_t ## _is_neg(b); \
+                prod_sign ^= !!(flags & float_muladd_negate_product);   \
+                p = soft_t ## _set_sign(soft_t ## _zero, prod_sign);    \
+                                                                        \
+                if (flags & float_muladd_negate_c) {                    \
+                    c = soft_t ## _chs(c);                              \
+                }                                                       \
+                                                                        \
+                hp = soft_t ## _to_ ## host_t(p);                       \
+                hc = soft_t ## _to_ ## host_t(c);                       \
+                hr = hp + hc;                                           \
+                r = host_t ## _to_ ## soft_t(hr);                       \
+                return flags & float_muladd_negate_result ?             \
+                    soft_t ## _chs(r) : r;                              \
+            } else {                                                    \
+                host_t ha, hb, hc, hr;                                  \
+                soft_t r;                                               \
+                soft_t sa = flags & float_muladd_negate_product ?       \
+                    soft_t ## _chs(a) : a;                              \
+                soft_t sc = flags & float_muladd_negate_c ?             \
+                    soft_t ## _chs(c) : c;                              \
+                                                                        \
+                ha = soft_t ## _to_ ## host_t(sa);                      \
+                hb = soft_t ## _to_ ## host_t(b);                       \
+                hc = soft_t ## _to_ ## host_t(sc);                      \
+                hr = host_fma_f(ha, hb, hc);                            \
+                r = host_t ## _to_ ## soft_t(hr);                       \
+                                                                        \
+                if (unlikely(soft_t ## _is_infinity(r))) {              \
+                    s->float_exception_flags |= float_flag_overflow;    \
+                } else if (unlikely(host_abs_f(hr) <= min_normal)) {    \
+                    goto soft;                                          \
+                }                                                       \
+                return flags & float_muladd_negate_result ?             \
+                    soft_t ## _chs(r) : r;                              \
+            }                                                           \
+        }                                                               \
+    soft:                                                               \
+        return soft_ ## soft_t ## _muladd(a, b, c, flags, s);           \
+    }
+
+GEN_FPU_FMA(float32_muladd, float32, float, fmaf, fabsf, FLT_MIN)
+GEN_FPU_FMA(float64_muladd, float64, double, fma, fabs, DBL_MIN)
+#undef GEN_FPU_FMA
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ebc59be..da81ec9 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1084,8 +1084,9 @@ float16 __attribute__((flatten)) float16_muladd(float16 a, float16 b, float16 c,
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_muladd(float32 a, float32 b, float32 c,
-                                                int flags, float_status *status)
+float32 __attribute__((flatten))
+soft_float32_muladd(float32 a, float32 b, float32 c, int flags,
+                    float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pb = float32_unpack_canonical(b, status);
@@ -1095,8 +1096,9 @@ float32 __attribute__((flatten)) float32_muladd(float32 a, float32 b, float32 c,
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_muladd(float64 a, float64 b, float64 c,
-                                                int flags, float_status *status)
+float64 __attribute__((flatten))
+soft_float64_muladd(float64 a, float64 b, float64 c, int flags,
+                    float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (10 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 11/14] hostfloat: support float32/64 fused multiply-add Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-22  1:29   ` Alex Bennée
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 13/14] hostfloat: support float32/64 comparison Emilio G. Cota
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
sqrt-single: 13.23 MFlops
sqrt-double: 13.24 MFlops

- after:
sqrt-single: 15.02 MFlops
sqrt-double: 15.07 MFlops

Note that sqrt in soft-ft is relatively fast, which means
that fp-bench is not very sensitive to changes to sqrt's
emulation speed.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  2 ++
 include/fpu/softfloat.h |  4 ++--
 fpu/hostfloat.c         | 20 ++++++++++++++++++++
 fpu/softfloat.c         |  6 ++++--
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index c006576..b1e0689 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -16,11 +16,13 @@ float32 float32_sub(float32 a, float32 b, float_status *status);
 float32 float32_mul(float32 a, float32 b, float_status *status);
 float32 float32_div(float32 a, float32 b, float_status *status);
 float32 float32_muladd(float32 a, float32 b, float32 c, int f, float_status *s);
+float32 float32_sqrt(float32 a, float_status *status);
 
 float64 float64_add(float64 a, float64 b, float_status *status);
 float64 float64_sub(float64 a, float64 b, float_status *status);
 float64 float64_mul(float64 a, float64 b, float_status *status);
 float64 float64_div(float64 a, float64 b, float_status *status);
 float64 float64_muladd(float64 a, float64 b, float64 c, int f, float_status *s);
+float64 float64_sqrt(float64 a, float_status *status);
 
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 866bd3b..8d5a50a 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -348,7 +348,7 @@ float32 soft_float32_mul(float32, float32, float_status *status);
 float32 soft_float32_div(float32, float32, float_status *status);
 float32 float32_rem(float32, float32, float_status *status);
 float32 soft_float32_muladd(float32, float32, float32, int, float_status *s);
-float32 float32_sqrt(float32, float_status *status);
+float32 soft_float32_sqrt(float32, float_status *status);
 float32 float32_exp2(float32, float_status *status);
 float32 float32_log2(float32, float_status *status);
 int float32_eq(float32, float32, float_status *status);
@@ -488,7 +488,7 @@ float64 soft_float64_mul(float64, float64, float_status *status);
 float64 soft_float64_div(float64, float64, float_status *status);
 float64 float64_rem(float64, float64, float_status *status);
 float64 soft_float64_muladd(float64, float64, float64, int, float_status *s);
-float64 float64_sqrt(float64, float_status *status);
+float64 soft_float64_sqrt(float64, float_status *status);
 float64 float64_log2(float64, float_status *status);
 int float64_eq(float64, float64, float_status *status);
 int float64_le(float64, float64, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index a56b70a..974bd57 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -270,3 +270,23 @@ GEN_FPU_DIV(float64_div, float64, double, fabs, DBL_MIN)
 GEN_FPU_FMA(float32_muladd, float32, float, fmaf, fabsf, FLT_MIN)
 GEN_FPU_FMA(float64_muladd, float64, double, fma, fabs, DBL_MIN)
 #undef GEN_FPU_FMA
+
+#define GEN_FPU_SQRT(name, soft_t, host_t, host_sqrt_func)              \
+    soft_t name(soft_t a, float_status *s)                              \
+    {                                                                   \
+        soft_t ## _input_flush1(&a, s);                                 \
+        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+                   !soft_t ## _is_neg(a) &&                             \
+                   s->float_exception_flags & float_flag_inexact &&     \
+                   s->float_rounding_mode == float_round_nearest_even)) { \
+            host_t ha = soft_t ## _to_ ## host_t(a);                    \
+            host_t hr = host_sqrt_func(ha);                             \
+                                                                        \
+            return host_t ## _to_ ## soft_t(hr);                        \
+        }                                                               \
+        return soft_ ## soft_t ## _sqrt(a, s);                          \
+    }
+
+GEN_FPU_SQRT(float32_sqrt, float32, float, sqrtf)
+GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt)
+#undef GEN_FPU_SQRT
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index da81ec9..096b658 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1980,14 +1980,16 @@ float16 __attribute__((flatten)) float16_sqrt(float16 a, float_status *status)
     return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_sqrt(float32 a, float_status *status)
+float32 __attribute__((flatten))
+soft_float32_sqrt(float32 a, float_status *status)
 {
     FloatParts pa = float32_unpack_canonical(a, status);
     FloatParts pr = sqrt_float(pa, status, &float32_params);
     return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_sqrt(float64 a, float_status *status)
+float64 __attribute__((flatten))
+soft_float64_sqrt(float64 a, float_status *status)
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pr = sqrt_float(pa, status, &float64_params);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 13/14] hostfloat: support float32/64 comparison
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (11 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 14/14] hostfloat: support float32_to_float64 Emilio G. Cota
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Performance results included in the following commit's log.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  4 ++++
 include/fpu/softfloat.h |  6 ++----
 fpu/hostfloat.c         | 36 ++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c         | 34 ++++++++++++++++++++--------------
 4 files changed, 62 insertions(+), 18 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index b1e0689..aa555f6 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -17,6 +17,8 @@ float32 float32_mul(float32 a, float32 b, float_status *status);
 float32 float32_div(float32 a, float32 b, float_status *status);
 float32 float32_muladd(float32 a, float32 b, float32 c, int f, float_status *s);
 float32 float32_sqrt(float32 a, float_status *status);
+int float32_compare(float32 a, float32 b, float_status *s);
+int float32_compare_quiet(float32 a, float32 b, float_status *s);
 
 float64 float64_add(float64 a, float64 b, float_status *status);
 float64 float64_sub(float64 a, float64 b, float_status *status);
@@ -24,5 +26,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status);
 float64 float64_div(float64 a, float64 b, float_status *status);
 float64 float64_muladd(float64 a, float64 b, float64 c, int f, float_status *s);
 float64 float64_sqrt(float64 a, float_status *status);
+int float64_compare(float64 a, float64 b, float_status *s);
+int float64_compare_quiet(float64 a, float64 b, float_status *s);
 
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 8d5a50a..cb57942 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -359,8 +359,7 @@ int float32_eq_quiet(float32, float32, float_status *status);
 int float32_le_quiet(float32, float32, float_status *status);
 int float32_lt_quiet(float32, float32, float_status *status);
 int float32_unordered_quiet(float32, float32, float_status *status);
-int float32_compare(float32, float32, float_status *status);
-int float32_compare_quiet(float32, float32, float_status *status);
+int soft_float32_compare(float32, float32, bool is_quiet, float_status *status);
 float32 float32_min(float32, float32, float_status *status);
 float32 float32_max(float32, float32, float_status *status);
 float32 float32_minnum(float32, float32, float_status *status);
@@ -498,8 +497,7 @@ int float64_eq_quiet(float64, float64, float_status *status);
 int float64_le_quiet(float64, float64, float_status *status);
 int float64_lt_quiet(float64, float64, float_status *status);
 int float64_unordered_quiet(float64, float64, float_status *status);
-int float64_compare(float64, float64, float_status *status);
-int float64_compare_quiet(float64, float64, float_status *status);
+int soft_float64_compare(float64, float64, bool is_quiet, float_status *status);
 float64 float64_min(float64, float64, float_status *status);
 float64 float64_max(float64, float64, float_status *status);
 float64 float64_minnum(float64, float64, float_status *status);
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index 974bd57..139e419 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -290,3 +290,39 @@ GEN_FPU_FMA(float64_muladd, float64, double, fma, fabs, DBL_MIN)
 GEN_FPU_SQRT(float32_sqrt, float32, float, sqrtf)
 GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt)
 #undef GEN_FPU_SQRT
+
+#define GEN_FPU_COMPARE(name, soft_t, host_t)                           \
+    static inline __attribute__((always_inline)) int                    \
+    fpu_ ## name(soft_t a, soft_t b, bool is_quiet, float_status *s)    \
+    {                                                                   \
+        soft_t ## _input_flush2(&a, &b, s);                             \
+        if (unlikely(soft_t ## _is_any_nan(a) ||                        \
+                     soft_t ## _is_any_nan(b))) {                       \
+            return soft_ ## name(a, b, is_quiet, s);                    \
+        } else {                                                        \
+            host_t ha = soft_t ## _to_ ## host_t(a);                    \
+            host_t hb = soft_t ## _to_ ## host_t(b);                    \
+                                                                        \
+            if (isgreater(ha, hb)) {                                    \
+                return float_relation_greater;                          \
+            }                                                           \
+            if (isless(ha, hb)) {                                       \
+                return float_relation_less;                             \
+            }                                                           \
+            return float_relation_equal;                                \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    int name(soft_t a, soft_t b, float_status *s)                       \
+    {                                                                   \
+        return fpu_ ## name(a, b, false, s);                            \
+    }                                                                   \
+                                                                        \
+    int name ## _quiet(soft_t a, soft_t b, float_status *s)             \
+    {                                                                   \
+        return fpu_ ## name(a, b, true, s);                             \
+    }
+
+GEN_FPU_COMPARE(float32_compare, float32, float)
+GEN_FPU_COMPARE(float64_compare, float64, double)
+#undef GEN_FPU_COMPARE
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 096b658..1a32216 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1844,28 +1844,34 @@ static int compare_floats(FloatParts a, FloatParts b, bool is_quiet,
     }
 }
 
-#define COMPARE(sz)                                                     \
-int float ## sz ## _compare(float ## sz a, float ## sz b,               \
-                            float_status *s)                            \
+#define COMPARE(storage_class, sz)                                      \
+storage_class int                                                       \
+soft_float ## sz ## _compare(float ## sz a, float ## sz b,              \
+                                     bool is_quiet, float_status *s)    \
 {                                                                       \
     FloatParts pa = float ## sz ## _unpack_canonical(a, s);             \
     FloatParts pb = float ## sz ## _unpack_canonical(b, s);             \
-    return compare_floats(pa, pb, false, s);                            \
-}                                                                       \
-int float ## sz ## _compare_quiet(float ## sz a, float ## sz b,         \
-                                  float_status *s)                      \
-{                                                                       \
-    FloatParts pa = float ## sz ## _unpack_canonical(a, s);             \
-    FloatParts pb = float ## sz ## _unpack_canonical(b, s);             \
-    return compare_floats(pa, pb, true, s);                             \
+    return compare_floats(pa, pb, is_quiet, s);                         \
 }
 
-COMPARE(16)
-COMPARE(32)
-COMPARE(64)
+COMPARE(static, 16)
+COMPARE(, 32)
+COMPARE(, 64)
 
 #undef COMPARE
 
+int __attribute__((flatten))
+float16_compare(float16 a, float16 b, float_status *s)
+{
+    return soft_float16_compare(a, b, false, s);
+}
+
+int __attribute__((flatten))
+float16_compare_quiet(float16 a, float16 b, float_status *s)
+{
+    return soft_float16_compare(a, b, true, s);
+}
+
 /* Multiply A by 2 raised to the power N.  */
 static FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [Qemu-devel] [PATCH v1 14/14] hostfloat: support float32_to_float64
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (12 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 13/14] hostfloat: support float32/64 comparison Emilio G. Cota
@ 2018-03-21 20:11 ` Emilio G. Cota
  2018-03-21 20:36 ` [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat no-reply
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 20:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Performance improvement for SPEC06fp for the last few commits:

                               qemu-aarch64 SPEC06fp (test set) speedup over QEMU f6d81cdec8
                                      Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
                                            error bars: 95% confidence interval

    5 +-+---+-----+----+-----+-----+-----+-----+----+-----+-----+-----+----+-----+-----+-----+-----+----+-----+---+-+
  4.5 +-+..........................+&&+...........................................................................+-+
  3.5 +-+................+++.......@@&...............+++............................................+++dsub       +-+
  2 3 +-+....+++.++++++%%&=+......+@@&....+++...==+..&&=..........................................++&=+++++++     +-+
    2 +-+..%%@&+.%%@=++%%&=.......+%@&..%%@&+.%%@=++%%&=.++&&+.......++&=+.+++++.......+&&=.%%@&+.%%@= +%%@=++%%&=+-+
  1.5 +-+++$%@&+#$%@=+#$%&=##$%&**#$@&**#%@&**$%@=**$%&=##%@&**#+&&**#%@=**$%@=+++&&=##$@&**#%@&**#%@=*+f%@=*#$%&=+-+
  0 1 +-+**#%@&**$%@=**$%&=*#$%&**#$@&**#%@&**$%@=**$%&=*#$@&**#$@&**#%@=**$%@=*#$%&=*#$@&**#%@&**#%@=+sqr@=*#$%&=+-+
    0 +-+**#%@&**$%@=**$%&=*#$%&**#$@&**#%@&**$%@=**$%&=*#$@&**#$@&**#%@=**$%@=*#$%&=*#$@&**#%@&**#%@=*+cmp=*#$%&=+-+
  410.bw416.gam433.434.z435.436.cac437.lesli444.447.de450.so453454.ca459.GemsF465.tont470.lb4482.sph+f32f64ean
  png: https://imgur.com/5BErNz7

That is, a final geomean speedup of 2.21X.

The floating point workloads from nbench show similar improvements:

                                       qemu-aarch64 NBench score; higher is better
                                     Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz

  16 +-+-------------------+---------------------+----------------------+---------------------+-------------------+-+
  14 +-+..............................................====**............@@@&&&==**................................+-+
  12 +-+.........................................@@@@&&..=.*............@.@..&.=.*..................+before       +-+
  10 +-+.........................................@..@.&..=.*............@.@..&.=.*............@@@&&&==***ub       +-+
   8 +-+....................................$$$$%%..@.&..=.*............@.@..&.=.*............@.@..&+= +*ul       +-+
   6 +-+...................@@@@&&===**..***##..$.%..@.&..=.*..++####$$%%%.@..&.=.*....####$$%%%.@..&+= +*iv       +-+
   4 +-+............###$$$%%..@.&..=.*..*+*.#..$.%..@.&..=.*..***..#.$..%.@..&.=.*..***..#.$..%.@..&+= +*ma       +-+
   2 +-+.........****.#..$.%..@.&..=.*..*.*.#..$.%..@.&..=.*..*.*..#.$..%.@..&.=.*..*.*..#.$..%.@..&+=+s*rt       +-+
   0 +-+---------****##$$$%%@@@&&===**--***##$$$%%@@@&&===**--***###$$%%%@@&&&==**--***###$$%%%@@&&&==***mp-------+-+
                    FOURIER            NEURAL NET       LU DECOMPOSITION                 gmean      +f32f64
  png: https://imgur.com/KjLHumh

That is, a ~2.6X speedup. [error bars here are just the standard deviation of
just a few measurements; this explains the noisy results.]

Results for the i386 target are very similar; the only major
difference is that they're much more sensitive to the multiplication
optimization, since the i386 target does not currently use floatX_muladd
(aka fma).

Below are the x86_64 SPEC06fp results, although note that they are from
a development branch, so each bar does not match the patches in this,
and the final numbers might be slightly different from those you'd
get with these patches.

                               qemu-x86_64 SPEC06fp (train set) speedup over QEMU f6d81cdec8
                                      Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
                                            error bars: 95% confidence interval

    4 +-+---+-----+----+-----+-----+%%---+-----+----+-----+-----+-----+----+-----+-----+-----+-----+----+-----+---+-+
  3.5 +-+..........................$$%............................................................................+-+
    3 +-+............**$$$......+**#$%............**$$++..................................+add+sub++%%+sq+++      +-+
  2.5 +-+..+++.**##$%**#+$%......**#$%..+$$%..++%%**#$%%.............+++.**#$$%........$$%+**$$%+###$%is#$$%  $$%%+-+
  1.5 +-+***#$%**.#$%**#.$%..$$%+**#$%***#$%**##$%**#$.%**#$%+++$$%***#$%**#+$%..$$++**#$%+fas$%path$%ul(0$%**#$ %+-+
    1 +-+*+*#$%**+#$%**#+$%**#$%+**#$%*+*#$%**+#$%**#$+%**#$%-**#$%*+*#$%**#+$%**#$%%**#$%+**+f%2 to %4+div%**#$+%+-+
  0.5 +-+*.*#$%**.#$%**#.$%**#$%.**#$%*.*#$%**.#$%**#$.%**#$%.**#$%*.*#$%**#.$%**#$.%**#$%.**#$%**.#$%**#.$%**#$.%+-+
    0 +-+***#$%**##$%**#$$%**#$%-**#$%***#$%**##$%**#$%%**#$%-**#$%***#$%**#$$%**#$%%**#$%-**#$%**##$%**#$$%**#$%%+-+
  410.bw416.gam433.434.z435.436.cac437.lesli444.447.de450.so453454.ca459.GemsF465.tont470.lb4482.sphinxgeomean
  png: https://imgur.com/MfvTb3H

Two points are worth mentioning:

- Special-casing 0-inputs for multiplication pays off handsomely (the same
  thing happens for FMA for targets that use it). I was surprised to
  see that some benchmarks (e.g. GemsFDTD) compute >99% of their
  multiplications with at least one operand being Zero (and this is
  without flush-to-zero!).

- Avoiding comparisons via the host FPU (i.e. using soft_t ## _is_normal()
  instead of glibc's isnormal()) gives a small speedup.

Finally, the same results using native execution time as the baseline,
where we plot the slowdown instead of the speedup.
We bring down the slowdown of SPEC06fp w.r.t. native from ~21X to ~10X:

                         qemu-x86_64 SPEC06fp (train set) slowdown over native (lower is better)
                                     Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
                                           error bars: 95% confidence interval

  90 +-+---+-----+-----+----+-----+-----+-----+-----+-----+----+-----+-----+-----+-----+-----+----+-----+-----+---+-+
  80 +-+.......................+**................................................................................+-+
  70 +-+........................**........................................................+          before       +-+
  50 +-+........................**........................................................+add+sub+mul+sqrt       +-+
  40 +-+......+++...............**................................+++.....................+  +integer isinf       +-+
  30 +-+**+...**+...............**#$%@**.........**+..............+**++.............**+...+fast path mul(0++**    +-+
  10 +-+**#$%@**#$%@**$$@@**#$%@**#$%@**#$%**#$%+**#$%@**#$%@**#$%+**#$%@**#$%@*#$%@**#$%@**#+f@2 to @4+div@**#$%@+-+
   0 +-+**#$%@**#$%@**#$%@**#$%@**#$%@**#$%**#$%@**#$%@**#$%@**#$%@**#$%@**#$%@*#$%@**#$%@**#$%@**#$%@**#$%@**#$%@+-+
 410.bw416.game433434.z435.436.cac437.leslie444.447.d450.so453.454.ca459.GemsF465.tont470.l48482.sphinxgeomean
  png: https://imgur.com/iTmVkJL

All png's shown above can be found here: https://imgur.com/a/YSxxR

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/fpu/hostfloat.h |  2 ++
 include/fpu/softfloat.h |  2 +-
 fpu/hostfloat.c         | 14 ++++++++++++++
 fpu/softfloat.c         |  2 +-
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
index aa555f6..79e9b6c 100644
--- a/include/fpu/hostfloat.h
+++ b/include/fpu/hostfloat.h
@@ -29,4 +29,6 @@ float64 float64_sqrt(float64 a, float_status *status);
 int float64_compare(float64 a, float64 b, float_status *s);
 int float64_compare_quiet(float64 a, float64 b, float_status *s);
 
+float64 float32_to_float64(float32, float_status *status);
+
 #endif /* HOSTFLOAT_H */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index cb57942..b0a4d75 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -334,7 +334,7 @@ int64_t float32_to_int64(float32, float_status *status);
 uint64_t float32_to_uint64(float32, float_status *status);
 uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
 int64_t float32_to_int64_round_to_zero(float32, float_status *status);
-float64 float32_to_float64(float32, float_status *status);
+float64 soft_float32_to_float64(float32, float_status *status);
 floatx80 float32_to_floatx80(float32, float_status *status);
 float128 float32_to_float128(float32, float_status *status);
 
diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
index 139e419..b635839 100644
--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -326,3 +326,17 @@ GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt)
 GEN_FPU_COMPARE(float32_compare, float32, float)
 GEN_FPU_COMPARE(float64_compare, float64, double)
 #undef GEN_FPU_COMPARE
+
+float64 float32_to_float64(float32 a, float_status *status)
+{
+    if (likely(float32_is_normal(a))) {
+        float f = *(float *)&a;
+        double r = f;
+
+        return *(float64 *)&r;
+    } else if (float32_is_zero(a)) {
+        return float64_set_sign(float64_zero, float32_is_neg(a));
+    } else {
+        return soft_float32_to_float64(a, status);
+    }
+}
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 1a32216..cf8d6ec 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3149,7 +3149,7 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
 | Arithmetic.
 *----------------------------------------------------------------------------*/
 
-float64 float32_to_float64(float32 a, float_status *status)
+float64 soft_float32_to_float64(float32 a, float_status *status)
 {
     flag aSign;
     int aExp;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (13 preceding siblings ...)
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 14/14] hostfloat: support float32_to_float64 Emilio G. Cota
@ 2018-03-21 20:36 ` no-reply
  2018-03-22  5:02 ` no-reply
  2018-03-22  8:56 ` Alex Bennée
  16 siblings, 0 replies; 46+ messages in thread
From: no-reply @ 2018-03-21 20:36 UTC (permalink / raw)
  To: cota
  Cc: famz, qemu-devel, peter.maydell, mark.cave-ayland,
	richard.henderson, laurent, pbonzini, alex.bennee, aurelien

Hi,

This series failed build test on s390x host. Please find the details below.

Type: series
Message-id: 1521663109-32262-1-git-send-email-cota@braap.org
Subject: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
CC=$HOME/bin/cc
INSTALL=$PWD/install
BUILD=$PWD/build
echo -n "Using CC: "
realpath $CC
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --cc=$CC --prefix=$INSTALL
make -j4
# XXX: we need reliable clean up
# make check -j4 V=1
make install
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/1521663109-32262-1-git-send-email-cota@braap.org -> patchew/1521663109-32262-1-git-send-email-cota@braap.org
 t [tag update]            patchew/20180321200114.10981-1-jsnow@redhat.com -> patchew/20180321200114.10981-1-jsnow@redhat.com
Switched to a new branch 'test'
2776883619 hostfloat: support float32_to_float64
dbb0c2a60b hostfloat: support float32/64 comparison
b21bd8b75d hostfloat: support float32/64 square root
40b1723ab1 hostfloat: support float32/64 fused multiply-add
d1ff4b2bcd hostfloat: support float32/64 division
6622d46dfe hostfloat: support float32/64 multiplication
a2e1f5e4c7 hostfloat: support float32/64 addition and subtraction
d25f954555 fpu: introduce hostfloat
4356927b54 softfloat: add float32_is_denormal and float64_is_denormal
4ceef15bf5 softfloat: add float32_is_normal and float64_is_normal
30f0f71fd2 fp-test: add muladd variants
ac7bd8e7f7 softfloat: fix {min, max}nummag for same-abs-value inputs
72f8541c7c tests: add fp-test, a floating point test suite
5718f9fdf4 tests: add fp-bench, a collection of simple floating-point microbenchmarks

=== OUTPUT BEGIN ===
=== ENV ===
LANG=en_US.UTF-8
XDG_SESSION_ID=107260
USER=fam
PWD=/var/tmp/patchew-tester-tmp-3_ytlhdd/src
HOME=/home/fam
SHELL=/bin/sh
SHLVL=2
PATCHEW=/home/fam/patchew/patchew-cli -s http://patchew.org --nodebug
LOGNAME=fam
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1012/bus
XDG_RUNTIME_DIR=/run/user/1012
PATH=/usr/bin:/bin
_=/usr/bin/env
=== PACKAGES ===
gpg-pubkey-873529b8-54e386ff
glibc-debuginfo-common-2.24-10.fc25.s390x
fedora-release-26-1.noarch
dejavu-sans-mono-fonts-2.35-4.fc26.noarch
xemacs-filesystem-21.5.34-22.20170124hgf412e9f093d4.fc26.noarch
bash-4.4.12-7.fc26.s390x
freetype-2.7.1-9.fc26.s390x
libSM-1.2.2-5.fc26.s390x
libmpc-1.0.2-6.fc26.s390x
libaio-0.3.110-7.fc26.s390x
libverto-0.2.6-7.fc26.s390x
perl-Scalar-List-Utils-1.48-1.fc26.s390x
iptables-libs-1.6.1-2.fc26.s390x
p11-kit-trust-0.23.9-2.fc26.s390x
tcl-8.6.6-2.fc26.s390x
libxshmfence-1.2-4.fc26.s390x
expect-5.45-23.fc26.s390x
perl-Thread-Queue-3.12-1.fc26.noarch
perl-encoding-2.19-6.fc26.s390x
keyutils-1.5.10-1.fc26.s390x
gmp-devel-6.1.2-4.fc26.s390x
enchant-1.6.0-16.fc26.s390x
net-snmp-libs-5.7.3-17.fc26.s390x
python-gobject-base-3.24.1-1.fc26.s390x
python3-enchant-1.6.10-1.fc26.noarch
python-lockfile-0.11.0-6.fc26.noarch
python2-pyparsing-2.1.10-3.fc26.noarch
python2-lxml-4.1.1-1.fc26.s390x
librados2-10.2.7-2.fc26.s390x
trousers-lib-0.3.13-7.fc26.s390x
libpaper-1.1.24-14.fc26.s390x
libdatrie-0.2.9-4.fc26.s390x
libsoup-2.58.2-1.fc26.s390x
passwd-0.79-9.fc26.s390x
bind99-libs-9.9.10-3.P3.fc26.s390x
python3-rpm-4.13.0.2-1.fc26.s390x
systemd-233-7.fc26.s390x
virglrenderer-0.6.0-1.20170210git76b3da97b.fc26.s390x
s390utils-ziomon-1.36.1-3.fc26.s390x
s390utils-osasnmpd-1.36.1-3.fc26.s390x
libXrandr-1.5.1-2.fc26.s390x
libglvnd-glx-1.0.0-1.fc26.s390x
texlive-ifxetex-svn19685.0.5-33.fc26.2.noarch
texlive-psnfss-svn33946.9.2a-33.fc26.2.noarch
texlive-dvipdfmx-def-svn40328-33.fc26.2.noarch
texlive-natbib-svn20668.8.31b-33.fc26.2.noarch
texlive-xdvi-bin-svn40750-33.20160520.fc26.2.s390x
texlive-cm-svn32865.0-33.fc26.2.noarch
texlive-beton-svn15878.0-33.fc26.2.noarch
texlive-fpl-svn15878.1.002-33.fc26.2.noarch
texlive-mflogo-svn38628-33.fc26.2.noarch
texlive-texlive-docindex-svn41430-33.fc26.2.noarch
texlive-luaotfload-bin-svn34647.0-33.20160520.fc26.2.noarch
texlive-koma-script-svn41508-33.fc26.2.noarch
texlive-pst-tree-svn24142.1.12-33.fc26.2.noarch
texlive-breqn-svn38099.0.98d-33.fc26.2.noarch
texlive-xetex-svn41438-33.fc26.2.noarch
gstreamer1-plugins-bad-free-1.12.3-1.fc26.s390x
xorg-x11-font-utils-7.5-33.fc26.s390x
ghostscript-fonts-5.50-36.fc26.noarch
libXext-devel-1.3.3-5.fc26.s390x
libusbx-devel-1.0.21-2.fc26.s390x
libglvnd-devel-1.0.0-1.fc26.s390x
emacs-25.3-3.fc26.s390x
alsa-lib-devel-1.1.4.1-1.fc26.s390x
kbd-2.0.4-2.fc26.s390x
dconf-0.26.0-2.fc26.s390x
ccache-3.3.4-1.fc26.s390x
mc-4.8.19-5.fc26.s390x
doxygen-1.8.13-9.fc26.s390x
dpkg-1.18.24-1.fc26.s390x
libtdb-1.3.13-1.fc26.s390x
python2-pynacl-1.1.1-1.fc26.s390x
nss-sysinit-3.34.0-1.0.fc26.s390x
kernel-4.13.16-202.fc26.s390x
perl-Filter-1.58-1.fc26.s390x
python2-pip-9.0.1-11.fc26.noarch
dnf-2.7.5-2.fc26.noarch
sssd-common-1.16.0-4.fc26.s390x
python2-sssdconfig-1.16.0-4.fc26.noarch
bind-license-9.11.2-1.P1.fc26.noarch
libtasn1-4.13-1.fc26.s390x
glusterfs-fuse-3.10.10-1.fc26.s390x
cpp-7.3.1-2.fc26.s390x
pkgconf-1.3.12-2.fc26.s390x
python2-fedora-0.10.0-1.fc26.noarch
cmake-filesystem-3.10.1-11.fc26.s390x
selinux-policy-targeted-3.13.1-260.18.fc26.noarch
python3-requests-kerberos-0.12.0-1.fc26.noarch
libmicrohttpd-0.9.59-1.fc26.s390x
GeoIP-GeoLite-data-2018.01-1.fc26.noarch
glibc-debuginfo-2.24-10.fc25.s390x
dejavu-fonts-common-2.35-4.fc26.noarch
bind99-license-9.9.10-3.P3.fc26.noarch
ncurses-libs-6.0-8.20170212.fc26.s390x
libpng-1.6.28-2.fc26.s390x
libICE-1.0.9-9.fc26.s390x
perl-Text-ParseWords-3.30-366.fc26.noarch
libtool-ltdl-2.4.6-17.fc26.s390x
libselinux-utils-2.6-7.fc26.s390x
userspace-rcu-0.9.3-2.fc26.s390x
libXfont-1.5.2-5.fc26.s390x
perl-Class-Inspector-1.31-3.fc26.noarch
perl-open-1.10-395.fc26.noarch
keyutils-libs-devel-1.5.10-1.fc26.s390x
isl-0.16.1-1.fc26.s390x
libsecret-0.18.5-3.fc26.s390x
compat-openssl10-1.0.2m-1.fc26.s390x
python3-iniparse-0.4-24.fc26.noarch
python3-dateutil-2.6.0-3.fc26.noarch
python3-firewall-0.4.4.5-1.fc26.noarch
python-enum34-1.1.6-1.fc26.noarch
python2-pygments-2.2.0-7.fc26.noarch
python2-dockerfile-parse-0.0.7-1.fc26.noarch
perl-Net-SSLeay-1.81-1.fc26.s390x
hostname-3.18-2.fc26.s390x
libtirpc-1.0.2-0.fc26.s390x
rpm-build-libs-4.13.0.2-1.fc26.s390x
libutempter-1.1.6-9.fc26.s390x
systemd-pam-233-7.fc26.s390x
libXinerama-1.1.3-7.fc26.s390x
mesa-libGL-17.2.4-2.fc26.s390x
texlive-amsfonts-svn29208.3.04-33.fc26.2.noarch
texlive-caption-svn41409-33.fc26.2.noarch
texlive-enumitem-svn24146.3.5.2-33.fc26.2.noarch
texlive-pdftex-def-svn22653.0.06d-33.fc26.2.noarch
texlive-xdvi-svn40768-33.fc26.2.noarch
texlive-courier-svn35058.0-33.fc26.2.noarch
texlive-charter-svn15878.0-33.fc26.2.noarch
texlive-graphics-def-svn41879-33.fc26.2.noarch
texlive-mfnfss-svn19410.0-33.fc26.2.noarch
texlive-texlive-en-svn41185-33.fc26.2.noarch
texlive-ifplatform-svn21156.0.4-33.fc26.2.noarch
texlive-ms-svn29849.0-33.fc26.2.noarch
texlive-pst-tools-svn34067.0.05-33.fc26.2.noarch
texlive-powerdot-svn38984-33.fc26.2.noarch
texlive-xetexconfig-svn41133-33.fc26.2.noarch
libvdpau-1.1.1-4.fc26.s390x
zlib-devel-1.2.11-2.fc26.s390x
gdk-pixbuf2-devel-2.36.9-1.fc26.s390x
libX11-devel-1.6.5-2.fc26.s390x
libglvnd-core-devel-1.0.0-1.fc26.s390x
SDL2-devel-2.0.7-2.fc26.s390x
webkitgtk3-2.4.11-5.fc26.s390x
grubby-8.40-4.fc26.s390x
uboot-tools-2017.05-4.fc26.s390x
cracklib-dicts-2.9.6-5.fc26.s390x
texinfo-6.3-3.fc26.s390x
time-1.7-52.fc26.s390x
python2-deltarpm-3.6-19.fc26.s390x
nss-3.34.0-1.0.fc26.s390x
python2-setuptools-37.0.0-1.fc26.noarch
python2-dnf-2.7.5-2.fc26.noarch
groff-base-1.22.3-10.fc26.s390x
python2-devel-2.7.14-4.fc26.s390x
python2-GitPython-2.1.7-2.fc26.noarch
boost-iostreams-1.63.0-10.fc26.s390x
distribution-gpg-keys-1.18-1.fc26.noarch
glusterfs-client-xlators-3.10.10-1.fc26.s390x
cups-libs-2.2.2-8.fc26.s390x
bind-libs-lite-9.11.2-1.P1.fc26.s390x
libpkgconf-1.3.12-2.fc26.s390x
python2-rpkg-1.51-3.fc26.noarch
java-1.8.0-openjdk-headless-1.8.0.161-5.b14.fc26.s390x
fedpkg-1.31-5.fc26.noarch
python3-dnf-plugin-system-upgrade-2.0.5-1.fc26.noarch
dtc-1.4.6-1.fc26.s390x
fedora-repos-26-2.noarch
gpg-pubkey-efe550f5-5220ba41
gpg-pubkey-81b46521-55b3ca9a
filesystem-3.2-40.fc26.s390x
basesystem-11-3.fc26.noarch
js-jquery-3.2.1-1.fc26.noarch
elfutils-libelf-0.169-1.fc26.s390x
libidn-1.33-2.fc26.s390x
libogg-1.3.2-6.fc26.s390x
slang-2.3.1a-2.fc26.s390x
apr-1.6.3-1.fc26.s390x
libxkbcommon-0.7.1-3.fc26.s390x
perl-IO-1.36-395.fc26.s390x
libvorbis-1.3.5-2.fc26.s390x
less-487-3.fc26.s390x
lttng-ust-2.9.0-2.fc26.s390x
OpenEXR-libs-2.2.0-6.fc26.s390x
ipset-libs-6.29-3.fc26.s390x
perl-XML-XPath-1.42-1.fc26.noarch
lua-filesystem-1.6.3-3.fc24.s390x
sqlite-3.20.1-1.fc26.s390x
gstreamer1-1.12.3-1.fc26.s390x
libpwquality-1.3.0-8.fc26.s390x
gettext-libs-0.19.8.1-9.fc26.s390x
python3-chardet-2.3.0-3.fc26.noarch
python3-slip-dbus-0.6.4-6.fc26.noarch
python-chardet-2.3.0-3.fc26.noarch
python2-pyasn1-0.2.3-1.fc26.noarch
python-slip-dbus-0.6.4-6.fc26.noarch
libarchive-3.2.2-4.fc26.s390x
libbabeltrace-1.5.2-2.fc26.s390x
cdparanoia-libs-10.2-22.fc26.s390x
krb5-workstation-1.15.2-4.fc26.s390x
gpgme-1.8.0-12.fc26.s390x
python2-gpg-1.8.0-12.fc26.s390x
shadow-utils-4.3.1-3.fc26.s390x
cryptsetup-libs-1.7.5-1.fc26.s390x
kpartx-0.4.9-88.fc26.s390x
net-snmp-agent-libs-5.7.3-17.fc26.s390x
libXi-1.7.9-2.fc26.s390x
texlive-tetex-svn41059-33.fc26.2.noarch
texlive-tools-svn40934-33.fc26.2.noarch
texlive-bibtex-bin-svn40473-33.20160520.fc26.2.s390x
texlive-mfware-bin-svn40473-33.20160520.fc26.2.s390x
texlive-underscore-svn18261.0-33.fc26.2.noarch
texlive-avantgar-svn31835.0-33.fc26.2.noarch
texlive-anysize-svn15878.0-33.fc26.2.noarch
texlive-lineno-svn21442.4.41-33.fc26.2.noarch
texlive-mathpazo-svn15878.1.003-33.fc26.2.noarch
texlive-soul-svn15878.2.4-33.fc26.2.noarch
texlive-luatexbase-svn38550-33.fc26.2.noarch
texlive-listings-svn37534.1.6-33.fc26.2.noarch
texlive-pstricks-svn41321-33.fc26.2.noarch
texlive-metalogo-svn18611.0.12-33.fc26.2.noarch
texlive-dvipdfmx-svn41149-33.fc26.2.noarch
kbd-legacy-2.0.4-2.fc26.noarch
nspr-devel-4.17.0-1.fc26.s390x
ghostscript-x11-9.20-10.fc26.s390x
libXrender-devel-0.9.10-2.fc26.s390x
libxkbcommon-devel-0.7.1-3.fc26.s390x
mesa-libGL-devel-17.2.4-2.fc26.s390x
sqlite-devel-3.20.1-1.fc26.s390x
usbredir-devel-0.7.1-3.fc26.s390x
libcap-devel-2.25-5.fc26.s390x
brlapi-devel-0.6.6-5.fc26.s390x
python3-pygpgme-0.3-22.fc26.s390x
pinentry-0.9.7-3.fc26.s390x
perl-Test-Harness-3.39-1.fc26.noarch
qemu-sanity-check-nodeps-1.1.5-6.fc26.s390x
libldb-1.1.29-5.fc26.s390x
nss-util-devel-3.34.0-1.0.fc26.s390x
python2-2.7.14-4.fc26.s390x
libwayland-cursor-1.13.0-3.fc26.s390x
pulseaudio-libs-devel-11.1-7.fc26.s390x
json-c-0.12.1-5.fc26.s390x
kernel-headers-4.15.4-200.fc26.s390x
libgcrypt-1.8.2-1.fc26.s390x
libgo-devel-7.3.1-2.fc26.s390x
glusterfs-cli-3.10.10-1.fc26.s390x
glusterfs-server-3.10.10-1.fc26.s390x
redhat-rpm-config-64-1.fc26.noarch
ca-certificates-2018.2.22-1.0.fc26.noarch
python2-sphinx-1.5.6-1.fc26.noarch
libtevent-0.9.35-1.fc26.s390x
dnsmasq-2.76-6.fc26.s390x
perl-Module-CoreList-5.20180120-1.fc26.noarch
gpg-pubkey-34ec9cba-54e38751
gpg-pubkey-030d5aed-55b577f0
setup-2.10.5-2.fc26.noarch
lato-fonts-2.015-3.fc26.noarch
web-assets-filesystem-5-5.fc26.noarch
libsepol-2.6-2.fc26.s390x
libcap-2.25-5.fc26.s390x
tcp_wrappers-libs-7.6-85.fc26.s390x
libnl3-3.3.0-1.fc26.s390x
pixman-0.34.0-3.fc26.s390x
lzo-2.08-9.fc26.s390x
perl-5.24.3-395.fc26.s390x
libnl3-cli-3.3.0-1.fc26.s390x
gpm-libs-1.20.7-10.fc26.s390x
iso-codes-3.74-2.fc26.noarch
ipset-6.29-3.fc26.s390x
lua-term-0.07-1.fc25.s390x
libdb-utils-5.3.28-24.fc26.s390x
dbus-glib-0.108-2.fc26.s390x
pam-1.3.0-2.fc26.s390x
avahi-glib-0.6.32-7.fc26.s390x
python2-dateutil-2.6.0-3.fc26.noarch
python3-asn1crypto-0.23.0-1.fc26.noarch
python3-slip-0.6.4-6.fc26.noarch
python-backports-ssl_match_hostname-3.5.0.1-4.fc26.noarch
python2-pyOpenSSL-16.2.0-6.fc26.noarch
python-slip-0.6.4-6.fc26.noarch
nss-pem-1.0.3-3.fc26.s390x
fipscheck-1.5.0-1.fc26.s390x
elfutils-0.169-1.fc26.s390x
cyrus-sasl-lib-2.1.26-32.fc26.s390x
libkadm5-1.15.2-4.fc26.s390x
python3-kerberos-1.2.5-3.fc26.s390x
rpmconf-1.0.19-1.fc26.noarch
libsemanage-2.6-4.fc26.s390x
device-mapper-libs-1.02.137-6.fc26.s390x
yum-3.4.3-512.fc26.noarch
device-mapper-multipath-0.4.9-88.fc26.s390x
net-snmp-5.7.3-17.fc26.s390x
libXtst-1.2.3-2.fc26.s390x
libXxf86vm-1.1.4-4.fc26.s390x
texlive-amsmath-svn41561-33.fc26.2.noarch
texlive-xkeyval-svn35741.2.7a-33.fc26.2.noarch
texlive-bibtex-svn40768-33.fc26.2.noarch
texlive-mfware-svn40768-33.fc26.2.noarch
texlive-wasy-svn35831.0-33.fc26.2.noarch
texlive-bookman-svn31835.0-33.fc26.2.noarch
texlive-babel-english-svn30264.3.3p-33.fc26.2.noarch
texlive-fix2col-svn38770-33.fc26.2.noarch
texlive-mdwtools-svn15878.1.05.4-33.fc26.2.noarch
texlive-tex-gyre-math-svn41264-33.fc26.2.noarch
texlive-luaotfload-svn40902-33.fc26.2.noarch
texlive-showexpl-svn32737.v0.3l-33.fc26.2.noarch
texlive-pstricks-add-svn40744-33.fc26.2.noarch
texlive-l3experimental-svn41163-33.fc26.2.noarch
texlive-xetex-bin-svn41091-33.20160520.fc26.2.s390x
kbd-misc-2.0.4-2.fc26.noarch
libpng-devel-1.6.28-2.fc26.s390x
ghostscript-core-9.20-10.fc26.s390x
libXfixes-devel-5.0.3-2.fc26.s390x
libverto-devel-0.2.6-7.fc26.s390x
mesa-libEGL-devel-17.2.4-2.fc26.s390x
popt-devel-1.16-12.fc26.s390x
readline-devel-7.0-5.fc26.s390x
cyrus-sasl-devel-2.1.26-32.fc26.s390x
sendmail-8.15.2-19.fc26.s390x
systemd-bootchart-231-3.fc26.s390x
perl-IO-Socket-SSL-2.049-1.fc26.noarch
python2-enchant-1.6.10-1.fc26.noarch
perl-generators-1.10-2.fc26.noarch
createrepo-0.10.3-11.fc26.noarch
nss-tools-3.34.0-1.0.fc26.s390x
pulseaudio-libs-glib2-11.1-7.fc26.s390x
dhcp-libs-4.3.5-10.fc26.s390x
libtiff-4.0.9-1.fc26.s390x
python-srpm-macros-3-21.fc26.noarch
libcurl-7.53.1-14.fc26.s390x
gnupg2-2.2.4-1.fc26.s390x
libtalloc-2.1.11-1.fc26.s390x
nfs-utils-2.2.1-4.rc2.fc26.s390x
qt5-srpm-macros-5.9.4-2.fc26.noarch
python2-dnf-plugins-core-2.1.5-4.fc26.noarch
mariadb-libs-10.1.30-2.fc26.s390x
bind-libs-9.11.2-1.P1.fc26.s390x
acpica-tools-20180105-1.fc26.s390x
perl-podlators-4.09-3.fc26.noarch
fontpackages-filesystem-1.44-18.fc26.noarch
vte-profile-0.48.4-1.fc26.s390x
texlive-kpathsea-doc-svn41139-33.fc26.2.noarch
zlib-1.2.11-2.fc26.s390x
readline-7.0-5.fc26.s390x
libattr-2.4.47-18.fc26.s390x
libglvnd-1.0.0-1.fc26.s390x
lz4-libs-1.8.0-1.fc26.s390x
jansson-2.10-2.fc26.s390x
perl-File-Path-2.12-367.fc26.noarch
perl-Unicode-EastAsianWidth-1.33-9.fc26.noarch
hunspell-1.5.4-2.fc26.s390x
libasyncns-0.8-11.fc26.s390x
libnetfilter_conntrack-1.0.6-2.fc26.s390x
perl-Storable-2.56-368.fc26.s390x
autoconf-2.69-24.fc26.noarch
device-mapper-persistent-data-0.6.3-5.fc26.s390x
quota-4.03-9.fc26.s390x
crypto-policies-20170606-1.git7c32281.fc26.noarch
glib2-2.52.3-2.fc26.s390x
python2-idna-2.5-1.fc26.noarch
python2-libcomps-0.1.8-3.fc26.s390x
gsettings-desktop-schemas-3.24.1-1.fc26.s390x
javapackages-tools-4.7.0-17.fc26.noarch
libselinux-python3-2.6-7.fc26.s390x
python-backports-1.0-9.fc26.s390x
python2-cryptography-2.0.2-2.fc26.s390x
libselinux-python-2.6-7.fc26.s390x
Lmod-7.5.3-1.fc26.s390x
fipscheck-lib-1.5.0-1.fc26.s390x
elfutils-libs-0.169-1.fc26.s390x
krb5-libs-1.15.2-4.fc26.s390x
libuser-0.62-6.fc26.s390x
npth-1.5-1.fc26.s390x
packagedb-cli-2.14.1-2.fc26.noarch
ustr-1.0.4-22.fc26.s390x
device-mapper-1.02.137-6.fc26.s390x
polkit-pkla-compat-0.1-8.fc26.s390x
fakeroot-1.22-1.fc26.s390x
libXmu-1.1.2-5.fc26.s390x
cairo-gobject-1.14.10-1.fc26.s390x
texlive-booktabs-svn40846-33.fc26.2.noarch
texlive-dvips-bin-svn40987-33.20160520.fc26.2.s390x
texlive-float-svn15878.1.3d-33.fc26.2.noarch
texlive-tex-svn40793-33.fc26.2.noarch
texlive-fancyref-svn15878.0.9c-33.fc26.2.noarch
texlive-manfnt-font-svn35799.0-33.fc26.2.noarch
texlive-cmap-svn41168-33.fc26.2.noarch
texlive-hyph-utf8-svn41189-33.fc26.2.noarch
texlive-paralist-svn39247-33.fc26.2.noarch
texlive-trimspaces-svn15878.1.1-33.fc26.2.noarch
texlive-tipa-svn29349.1.3-33.fc26.2.noarch
texlive-l3packages-svn41246-33.fc26.2.noarch
texlive-pst-pdf-svn31660.1.1v-33.fc26.2.noarch
texlive-tex-gyre-svn18651.2.004-33.fc26.2.noarch
texlive-beamer-svn36461.3.36-33.fc26.2.noarch
gd-2.2.5-1.fc26.s390x
elfutils-libelf-devel-0.169-1.fc26.s390x
gc-devel-7.6.0-2.fc26.s390x
libXft-devel-2.3.2-5.fc26.s390x
krb5-devel-1.15.2-4.fc26.s390x
rpm-devel-4.13.0.2-1.fc26.s390x
bluez-libs-devel-5.46-6.fc26.s390x
systemtap-3.2-2.fc26.s390x
trousers-0.3.13-7.fc26.s390x
iproute-tc-4.11.0-1.fc26.s390x
libgnome-keyring-3.12.0-8.fc26.s390x
perl-File-ShareDir-1.102-8.fc26.noarch
python2-paramiko-2.2.1-1.fc26.noarch
python2-openidc-client-0.4.0-1.20171113git54dee6e.fc26.noarch
openssh-server-7.5p1-4.fc26.s390x
pulseaudio-libs-11.1-7.fc26.s390x
python2-bodhi-2.12.2-3.fc26.noarch
lua-libs-5.3.4-7.fc26.s390x
dhcp-common-4.3.5-10.fc26.noarch
python3-pip-9.0.1-11.fc26.noarch
python3-sssdconfig-1.16.0-4.fc26.noarch
python2-py-1.4.34-1.fc26.noarch
glibc-common-2.25-13.fc26.s390x
webkitgtk4-jsc-2.18.6-1.fc26.s390x
python3-libs-3.6.4-2.fc26.s390x
glibc-devel-2.25-13.fc26.s390x
pcre2-10.23-13.fc26.s390x
linux-firmware-20171215-82.git2451bb22.fc26.noarch
glusterfs-api-devel-3.10.10-1.fc26.s390x
libfdt-devel-1.4.6-1.fc26.s390x
audit-2.8.2-1.fc26.s390x
perl-Socket-2.027-1.fc26.s390x
nosync-1.0-6.fc26.s390x
gpg-pubkey-95a43f54-5284415a
gpg-pubkey-fdb19c98-56fd6333
gpg-pubkey-64dab85d-57d33e22
firewalld-filesystem-0.4.4.5-1.fc26.noarch
xkeyboard-config-2.21-3.fc26.noarch
texlive-texlive-common-doc-svn40682-33.fc26.2.noarch
ncurses-base-6.0-8.20170212.fc26.noarch
libselinux-2.6-7.fc26.s390x
bzip2-libs-1.0.6-22.fc26.s390x
libdb-5.3.28-24.fc26.s390x
mpfr-3.1.5-3.fc26.s390x
file-libs-5.30-11.fc26.s390x
libunistring-0.9.7-1.fc26.s390x
libxslt-1.1.29-1.fc26.s390x
gdbm-1.13-1.fc26.s390x
libepoxy-1.4.3-1.fc26.s390x
libpsl-0.18.0-1.fc26.s390x
perl-Carp-1.40-366.fc26.noarch
e2fsprogs-libs-1.43.4-2.fc26.s390x
libmnl-1.0.4-2.fc26.s390x
openjpeg2-2.2.0-3.fc26.s390x
perl-PathTools-3.63-367.fc26.s390x
perl-File-Temp-0.230.400-2.fc26.noarch
perl-XML-Parser-2.44-6.fc26.s390x
libss-1.43.4-2.fc26.s390x
ilmbase-2.2.0-8.fc26.s390x
fuse-libs-2.9.7-2.fc26.s390x
libdaemon-0.14-11.fc26.s390x
libbasicobjects-0.1.1-34.fc26.s390x
iptables-1.6.1-2.fc26.s390x
perl-TermReadKey-2.37-2.fc26.s390x
perl-Term-ANSIColor-4.06-2.fc26.noarch
perl-libintl-perl-1.26-2.fc26.s390x
usbredir-0.7.1-3.fc26.s390x
fftw-libs-double-3.3.5-4.fc26.s390x
libiscsi-1.15.0-3.fc26.s390x
ttmkfdir-3.0.9-49.fc26.s390x
texlive-base-2016-33.20160520.fc26.1.noarch
python2-six-1.10.0-9.fc26.noarch
atk-2.24.0-1.fc26.s390x
python2-kitchen-1.2.4-6.fc26.noarch
guile-2.0.14-1.fc26.s390x
desktop-file-utils-0.23-3.fc26.s390x
pyxattr-0.5.3-10.fc26.s390x
shared-mime-info-1.8-2.fc26.s390x
libyaml-0.1.7-2.fc26.s390x
python3-PyYAML-3.12-3.fc26.s390x
openssh-7.5p1-4.fc26.s390x
kernel-core-4.13.16-202.fc26.s390x
perl-Git-2.13.6-2.fc26.noarch
openssl-1.1.0g-1.fc26.s390x
gawk-4.1.4-6.fc26.s390x
gnutls-3.5.16-4.fc26.s390x
openldap-2.4.45-2.fc26.s390x
NetworkManager-libnm-1.8.2-4.fc26.s390x
gnutls-devel-3.5.16-4.fc26.s390x
python2-urllib3-1.20-2.fc26.noarch
sssd-nfs-idmap-1.16.0-4.fc26.s390x
libsss_sudo-1.16.0-4.fc26.s390x
python3-py-1.4.34-1.fc26.noarch
perl-ExtUtils-Command-7.24-3.fc26.noarch
tzdata-2018c-1.fc26.noarch
libcrypt-nss-2.25-13.fc26.s390x
libstdc++-devel-7.3.1-2.fc26.s390x
rpcbind-0.2.4-8.rc3.fc26.s390x
gdb-headless-8.0.1-36.fc26.s390x
python3-dnf-plugins-extras-common-2.0.5-1.fc26.noarch
glibc-headers-2.25-13.fc26.s390x
libfdt-1.4.6-1.fc26.s390x
pcre-utf32-8.41-5.fc26.s390x
wget-1.19.4-1.fc26.s390x
mariadb-common-10.1.30-2.fc26.s390x
glusterfs-extra-xlators-3.10.10-1.fc26.s390x
python2-dnf-plugin-migrate-2.1.5-4.fc26.noarch
pcre2-devel-10.23-13.fc26.s390x
perl-threads-shared-1.58-1.fc26.s390x
gcc-c++-7.3.1-2.fc26.s390x
ImageMagick-libs-6.9.9.27-1.fc26.s390x
poppler-0.52.0-11.fc26.s390x
perl-Data-Dumper-2.161-4.fc26.s390x
python2-dnf-plugins-extras-common-2.0.5-1.fc26.noarch
gcc-debuginfo-7.3.1-2.fc26.s390x
libgudev-232-1.fc26.s390x
python3-javapackages-4.7.0-17.fc26.noarch
python3-ply-3.9-3.fc26.noarch
python3-systemd-234-1.fc26.s390x
python3-requests-2.13.0-1.fc26.noarch
blktrace-1.1.0-4.fc26.s390x
python2-asn1crypto-0.23.0-1.fc26.noarch
python2-cffi-1.9.1-2.fc26.s390x
python2-sphinx_rtd_theme-0.2.4-1.fc26.noarch
lua-json-1.3.2-7.fc26.noarch
libcephfs1-10.2.7-2.fc26.s390x
glib-networking-2.50.0-2.fc26.s390x
elfutils-default-yama-scope-0.169-1.fc26.noarch
libedit-3.1-17.20160618cvs.fc26.s390x
libverto-libev-0.2.6-7.fc26.s390x
libserf-1.3.9-3.fc26.s390x
python2-kerberos-1.2.5-3.fc26.s390x
libsrtp-1.5.4-4.fc26.s390x
lzo-minilzo-2.08-9.fc26.s390x
librepo-1.8.0-1.fc26.s390x
koji-1.14.0-1.fc26.noarch
sg3_utils-1.42-1.fc26.s390x
policycoreutils-2.6-6.fc26.s390x
systemtap-client-3.2-2.fc26.s390x
lvm2-2.02.168-6.fc26.s390x
device-mapper-multipath-libs-0.4.9-88.fc26.s390x
s390utils-cmsfs-1.36.1-3.fc26.s390x
libXdamage-1.1.4-9.fc26.s390x
libXaw-1.0.13-5.fc26.s390x
brltty-5.5-5.fc26.s390x
librsvg2-2.40.18-1.fc26.s390x
texlive-tetex-bin-svn36770.0-33.20160520.fc26.2.noarch
texlive-etex-pkg-svn39355-33.fc26.2.noarch
texlive-graphics-svn41015-33.fc26.2.noarch
texlive-dvips-svn41149-33.fc26.2.noarch
texlive-zapfding-svn31835.0-33.fc26.2.noarch
texlive-footmisc-svn23330.5.5b-33.fc26.2.noarch
texlive-makeindex-svn40768-33.fc26.2.noarch
texlive-pst-ovl-svn40873-33.fc26.2.noarch
texlive-texlive-scripts-svn41433-33.fc26.2.noarch
texlive-ltabptch-svn17533.1.74d-33.fc26.2.noarch
texlive-euro-svn22191.1.1-33.fc26.2.noarch
texlive-mflogo-font-svn36898.1.002-33.fc26.2.noarch
texlive-zapfchan-svn31835.0-33.fc26.2.noarch
texlive-cmextra-svn32831.0-33.fc26.2.noarch
texlive-finstrut-svn21719.0.5-33.fc26.2.noarch
texlive-hyphen-base-svn41138-33.fc26.2.noarch
texlive-marginnote-svn41382-33.fc26.2.noarch
texlive-parallel-svn15878.0-33.fc26.2.noarch
texlive-sepnum-svn20186.2.0-33.fc26.2.noarch
texlive-environ-svn33821.0.3-33.fc26.2.noarch
texlive-type1cm-svn21820.0-33.fc26.2.noarch
texlive-xunicode-svn30466.0.981-33.fc26.2.noarch
texlive-attachfile-svn38830-33.fc26.2.noarch
texlive-fontspec-svn41262-33.fc26.2.noarch
texlive-fancyvrb-svn18492.2.8-33.fc26.2.noarch
texlive-pst-pdf-bin-svn7838.0-33.20160520.fc26.2.noarch
texlive-xcolor-svn41044-33.fc26.2.noarch
texlive-pdfpages-svn40638-33.fc26.2.noarch
texlive-sansmathaccent-svn30187.0-33.fc26.2.noarch
texlive-ucs-svn35853.2.2-33.fc26.2.noarch
texlive-dvipdfmx-bin-svn40273-33.20160520.fc26.2.s390x
libotf-0.9.13-8.fc26.s390x
go-srpm-macros-2-8.fc26.noarch
mesa-libwayland-egl-devel-17.2.4-2.fc26.s390x
ghostscript-9.20-10.fc26.s390x
libcephfs_jni-devel-10.2.7-2.fc26.s390x
libXdamage-devel-1.1.4-9.fc26.s390x
freetype-devel-2.7.1-9.fc26.s390x
ncurses-devel-6.0-8.20170212.fc26.s390x
fontconfig-devel-2.12.6-4.fc26.s390x
cairo-devel-1.14.10-1.fc26.s390x
libselinux-devel-2.6-7.fc26.s390x
guile-devel-2.0.14-1.fc26.s390x
libcap-ng-devel-0.7.8-3.fc26.s390x
bash-completion-2.6-1.fc26.noarch
libXevie-1.0.3-12.fc26.s390x
python-firewall-0.4.4.5-1.fc26.noarch
python3-html5lib-0.999-13.fc26.noarch
python2-simplejson-3.10.0-3.fc26.s390x
flex-2.6.1-3.fc26.s390x
telnet-0.17-69.fc26.s390x
gpg-pubkey-8e1431d5-53bcbac7
emacs-filesystem-25.3-3.fc26.noarch
fontawesome-fonts-4.7.0-2.fc26.noarch
fontawesome-fonts-web-4.7.0-2.fc26.noarch
rpmconf-base-1.0.19-1.fc26.noarch
info-6.3-3.fc26.s390x
sqlite-libs-3.20.1-1.fc26.s390x
texlive-lib-2016-33.20160520.fc26.1.s390x
libicu-57.1-7.fc26.s390x
libcap-ng-0.7.8-3.fc26.s390x
nettle-3.3-2.fc26.s390x
libidn2-2.0.4-1.fc26.s390x
lcms2-2.8-3.fc26.s390x
dbus-libs-1.11.18-1.fc26.s390x
perl-Exporter-5.72-367.fc26.noarch
unzip-6.0-34.fc26.s390x
iproute-4.11.0-1.fc26.s390x
zip-3.0-18.fc26.s390x
perl-constant-1.33-368.fc26.noarch
perl-MIME-Base64-3.15-366.fc26.s390x
lua-posix-33.3.1-4.fc26.s390x
bzip2-1.0.6-22.fc26.s390x
hyphen-2.8.8-6.fc26.s390x
libdvdread-5.0.3-4.fc26.s390x
libcollection-0.7.0-34.fc26.s390x
libdvdnav-5.0.3-5.fc26.s390x
perl-version-0.99.18-1.fc26.s390x
perl-Encode-2.88-6.fc26.s390x
automake-1.15-9.fc26.noarch
plymouth-core-libs-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
hesiod-3.2.1-7.fc26.s390x
jasper-libs-2.0.14-1.fc26.s390x
mozjs17-17.0.0-18.fc26.s390x
fontconfig-2.12.6-4.fc26.s390x
harfbuzz-1.4.4-1.fc26.s390x
alsa-lib-1.1.4.1-1.fc26.s390x
make-4.2.1-2.fc26.s390x
gobject-introspection-1.52.1-1.fc26.s390x
hicolor-icon-theme-0.15-5.fc26.noarch
gdk-pixbuf2-2.36.9-1.fc26.s390x
libgusb-0.2.11-1.fc26.s390x
libdhash-0.5.0-34.fc26.s390x
python2-bcrypt-3.1.4-2.fc26.s390x
PyYAML-3.12-3.fc26.s390x
nss-softokn-freebl-3.34.0-1.0.fc26.s390x
kernel-modules-4.13.16-202.fc26.s390x
git-2.13.6-2.fc26.s390x
openssl-devel-1.1.0g-1.fc26.s390x
copy-jdk-configs-3.3-2.fc26.noarch
python3-setuptools-37.0.0-1.fc26.noarch
kernel-core-4.14.8-200.fc26.s390x
NetworkManager-1.8.2-4.fc26.s390x
libjpeg-turbo-devel-1.5.3-1.fc26.s390x
lua-5.3.4-7.fc26.s390x
boost-thread-1.63.0-10.fc26.s390x
libwebp-0.6.1-1.fc26.s390x
kernel-devel-4.14.8-200.fc26.s390x
perl-autodie-2.29-367.fc26.noarch
tzdata-java-2018c-1.fc26.noarch
glusterfs-3.10.10-1.fc26.s390x
glusterfs-api-3.10.10-1.fc26.s390x
pcre-8.41-5.fc26.s390x
createrepo_c-0.10.0-15.fc26.s390x
mock-core-configs-28.2-1.fc26.noarch
libgfortran-7.3.1-2.fc26.s390x
libdrm-2.4.89-1.fc26.s390x
pcre-utf16-8.41-5.fc26.s390x
vim-common-8.0.1438-1.fc26.s390x
mariadb-config-10.1.30-2.fc26.s390x
python2-gluster-3.10.10-1.fc26.s390x
java-1.8.0-openjdk-1.8.0.161-5.b14.fc26.s390x
libtasn1-devel-4.13-1.fc26.s390x
vim-enhanced-8.0.1438-1.fc26.s390x
gcc-gdb-plugin-7.3.1-2.fc26.s390x
gnupg2-smime-2.2.4-1.fc26.s390x
python2-libxml2-2.9.7-1.fc26.s390x
net-tools-2.0-0.44.20160912git.fc26.s390x
python2-requests-kerberos-0.12.0-1.fc26.noarch
gcc-base-debuginfo-7.3.1-2.fc26.s390x
python3-lxml-4.1.1-1.fc26.s390x
python3-ordered-set-2.0.0-6.fc26.noarch
python3-rpmconf-1.0.19-1.fc26.noarch
python-offtrac-0.1.0-9.fc26.noarch
python2-pycparser-2.14-10.fc26.noarch
python2-sphinx-theme-alabaster-0.7.9-3.fc26.noarch
python2-pysocks-1.6.7-1.fc26.noarch
lua-lpeg-1.0.1-2.fc26.s390x
libproxy-0.4.15-2.fc26.s390x
crontabs-1.11-14.20150630git.fc26.noarch
libev-4.24-2.fc26.s390x
libsigsegv-2.11-1.fc26.s390x
fedora-cert-0.6.0.1-2.fc26.noarch
drpm-0.3.0-6.fc26.s390x
python2-cccolutils-1.5-3.fc26.s390x
m17n-lib-1.7.0-6.fc26.s390x
lsscsi-0.28-4.fc26.s390x
python2-koji-1.14.0-1.fc26.noarch
python3-koji-1.14.0-1.fc26.noarch
python3-gpg-1.8.0-12.fc26.s390x
sg3_utils-libs-1.42-1.fc26.s390x
SDL2-2.0.7-2.fc26.s390x
util-linux-2.30.2-1.fc26.s390x
s390utils-mon_statd-1.36.1-3.fc26.s390x
GConf2-3.2.6-17.fc26.s390x
systemd-container-233-7.fc26.s390x
usermode-1.111-9.fc26.s390x
libXt-1.1.5-4.fc26.s390x
libXpm-3.5.12-2.fc26.s390x
at-spi2-core-2.24.1-1.fc26.s390x
cairo-1.14.10-1.fc26.s390x
texlive-kpathsea-bin-svn40473-33.20160520.fc26.2.s390x
texlive-ifluatex-svn41346-33.fc26.2.noarch
texlive-babel-svn40706-33.fc26.2.noarch
texlive-colortbl-svn29803.v1.0a-33.fc26.2.noarch
texlive-marvosym-svn29349.2.2a-33.fc26.2.noarch
texlive-euler-svn17261.2.5-33.fc26.2.noarch
texlive-latexconfig-svn40274-33.fc26.2.noarch
texlive-plain-svn40274-33.fc26.2.noarch
texlive-texconfig-bin-svn29741.0-33.20160520.fc26.2.noarch
giflib-4.1.6-16.fc26.s390x
texlive-microtype-svn41127-33.fc26.2.noarch
texlive-eurosym-svn17265.1.4_subrfix-33.fc26.2.noarch
texlive-symbol-svn31835.0-33.fc26.2.noarch
texlive-chngcntr-svn17157.1.0a-33.fc26.2.noarch
texlive-euenc-svn19795.0.1h-33.fc26.2.noarch
texlive-luatex-svn40963-33.fc26.2.noarch
texlive-knuth-local-svn38627-33.fc26.2.noarch
texlive-mparhack-svn15878.1.4-33.fc26.2.noarch
texlive-rcs-svn15878.0-33.fc26.2.noarch
texlive-texlive-msg-translations-svn41431-33.fc26.2.noarch
texlive-updmap-map-svn41159-33.fc26.2.noarch
texlive-geometry-svn19716.5.6-33.fc26.2.noarch
texlive-memoir-svn41203-33.fc26.2.noarch
texlive-l3kernel-svn41246-33.fc26.2.noarch
texlive-pst-eps-svn15878.1.0-33.fc26.2.noarch
texlive-pst-text-svn15878.1.00-33.fc26.2.noarch
texlive-amscls-svn36804.0-33.fc26.2.noarch
texlive-pst-slpe-svn24391.1.31-33.fc26.2.noarch
texlive-extsizes-svn17263.1.4a-33.fc26.2.noarch
texlive-xetex-def-svn40327-33.fc26.2.noarch
texlive-collection-latex-svn41011-33.20160520.fc26.2.noarch
gstreamer1-plugins-base-1.12.3-1.fc26.s390x
fpc-srpm-macros-1.1-2.fc26.noarch
xorg-x11-proto-devel-7.7-22.fc26.noarch
urw-fonts-2.4-23.fc26.noarch
atk-devel-2.24.0-1.fc26.s390x
libxcb-devel-1.12-3.fc26.s390x
libXrandr-devel-1.5.1-2.fc26.s390x
libcom_err-devel-1.43.4-2.fc26.s390x
dbus-devel-1.11.18-1.fc26.s390x
libepoxy-devel-1.4.3-1.fc26.s390x
libicu-devel-57.1-7.fc26.s390x
p11-kit-devel-0.23.9-2.fc26.s390x
rpm-build-4.13.0.2-1.fc26.s390x
libssh2-devel-1.8.0-5.fc26.s390x
graphviz-2.40.1-4.fc26.s390x
zlib-static-1.2.11-2.fc26.s390x
mesa-libgbm-devel-17.2.4-2.fc26.s390x
screen-4.6.2-1.fc26.s390x
python-osbs-client-0.39.1-1.fc26.noarch
pyparsing-2.1.10-3.fc26.noarch
python3-pyasn1-0.2.3-1.fc26.noarch
python2-html5lib-0.999-13.fc26.noarch
teamd-1.27-1.fc26.s390x
hardlink-1.3-1.fc26.s390x
chrpath-0.16-4.fc26.s390x
texlive-pdftex-doc-svn41149-33.fc26.2.noarch
nspr-4.17.0-1.fc26.s390x
grep-3.1-1.fc26.s390x
libacl-2.2.52-15.fc26.s390x
cpio-2.12-4.fc26.s390x
libatomic_ops-7.4.4-2.fc26.s390x
p11-kit-0.23.9-2.fc26.s390x
gc-7.6.0-2.fc26.s390x
psmisc-22.21-9.fc26.s390x
systemd-libs-233-7.fc26.s390x
xz-5.2.3-2.fc26.s390x
perl-libs-5.24.3-395.fc26.s390x
libpcap-1.8.1-3.fc26.s390x
perl-macros-5.24.3-395.fc26.s390x
perl-parent-0.236-2.fc26.noarch
perl-Text-Unidecode-1.30-2.fc26.noarch
newt-0.52.20-1.fc26.s390x
libcomps-0.1.8-3.fc26.s390x
libfontenc-1.1.3-4.fc26.s390x
ipcalc-0.2.0-1.fc26.s390x
libnfnetlink-1.0.1-9.fc26.s390x
libref_array-0.1.5-34.fc26.s390x
perl-Term-Cap-1.17-366.fc26.noarch
perl-Digest-1.17-367.fc26.noarch
perl-SelfLoader-1.23-395.fc26.noarch
perl-Pod-Simple-3.35-2.fc26.noarch
perl-URI-1.71-6.fc26.noarch
attr-2.4.47-18.fc26.s390x
gmp-c++-6.1.2-4.fc26.s390x
harfbuzz-icu-1.4.4-1.fc26.s390x
http-parser-2.7.1-5.fc26.s390x
libsodium-1.0.14-1.fc26.s390x
python-gssapi-1.2.0-5.fc26.s390x
nss-softokn-3.34.0-1.0.fc26.s390x
nss-devel-3.34.0-1.0.fc26.s390x
perl-libnet-3.11-1.fc26.noarch
kernel-devel-4.13.16-202.fc26.s390x
python2-libs-2.7.14-4.fc26.s390x
libwayland-client-1.13.0-3.fc26.s390x
python3-dnf-2.7.5-2.fc26.noarch
kernel-modules-4.14.8-200.fc26.s390x
NetworkManager-ppp-1.8.2-4.fc26.s390x
wayland-devel-1.13.0-3.fc26.s390x
kernel-4.14.8-200.fc26.s390x
boost-random-1.63.0-10.fc26.s390x
mailx-12.5-24.fc26.s390x
NetworkManager-glib-1.8.2-4.fc26.s390x
perl-IPC-System-Simple-1.25-12.fc26.noarch
vim-filesystem-8.0.1438-1.fc26.s390x
glusterfs-libs-3.10.10-1.fc26.s390x
sed-4.4-2.fc26.s390x
libassuan-2.5.1-1.fc26.s390x
createrepo_c-libs-0.10.0-15.fc26.s390x
dnf-utils-2.1.5-4.fc26.noarch
libobjc-7.3.1-2.fc26.s390x
dracut-046-8.git20180105.fc26.s390x
libseccomp-2.3.3-1.fc26.s390x
mock-1.4.8-1.fc26.noarch
python-sphinx-locale-1.5.6-1.fc26.noarch
pcre-devel-8.41-5.fc26.s390x
libxml2-devel-2.9.7-1.fc26.s390x
libseccomp-devel-2.3.3-1.fc26.s390x
fedora-upgrade-28.1-1.fc26.noarch
gcc-gfortran-7.3.1-2.fc26.s390x
gdb-8.0.1-36.fc26.s390x
unbound-libs-1.6.8-1.fc26.s390x
man-db-2.7.6.1-9.fc26.s390x
python2-rpm-macros-3-21.fc26.noarch
kernel-devel-4.15.4-200.fc26.s390x
libcroco-0.6.12-1.fc26.s390x
libssh2-1.8.0-5.fc26.s390x
json-glib-1.2.6-1.fc26.s390x
libevent-2.0.22-3.fc26.s390x
gdk-pixbuf2-modules-2.36.9-1.fc26.s390x
colord-libs-1.3.5-1.fc26.s390x
python3-magic-5.30-11.fc26.noarch
python3-gobject-base-3.24.1-1.fc26.s390x
python3-pyroute2-0.4.13-1.fc26.noarch
python3-pysocks-1.6.7-1.fc26.noarch
python2-click-6.7-3.fc26.noarch
python-munch-2.1.0-2.fc26.noarch
python2-ply-3.9-3.fc26.noarch
python2-snowballstemmer-1.2.1-3.fc26.noarch
python-magic-5.30-11.fc26.noarch
python-beautifulsoup4-4.6.0-1.fc26.noarch
python2-gitdb-2.0.3-1.fc26.noarch
librados-devel-10.2.7-2.fc26.s390x
libcacard-2.5.3-1.fc26.s390x
libmodman-2.0.1-13.fc26.s390x
zziplib-0.13.62-8.fc26.s390x
lksctp-tools-1.0.16-6.fc26.s390x
procmail-3.22-44.fc26.s390x
libthai-0.1.25-2.fc26.s390x
libpipeline-1.4.1-3.fc26.s390x
python2-pycurl-7.43.0-8.fc26.s390x
deltarpm-3.6-19.fc26.s390x
subversion-libs-1.9.7-1.fc26.s390x
python-krbV-1.0.90-13.fc26.s390x
m17n-db-1.7.0-8.fc26.noarch
linux-atm-libs-2.5.1-17.fc26.s390x
python2-rpm-4.13.0.2-1.fc26.s390x
python2-librepo-1.8.0-1.fc26.s390x
qrencode-libs-3.4.4-1.fc26.s390x
s390utils-iucvterm-1.36.1-3.fc26.s390x
libsmartcols-2.30.2-1.fc26.s390x
dbus-1.11.18-1.fc26.s390x
systemd-udev-233-7.fc26.s390x
device-mapper-event-1.02.137-6.fc26.s390x
polkit-0.113-8.fc26.s390x
libwmf-lite-0.2.8.4-53.fc26.s390x
libXcomposite-0.4.4-9.fc26.s390x
libXcursor-1.1.14-8.fc26.s390x
at-spi2-atk-2.24.1-1.fc26.s390x
pango-1.40.12-1.fc26.s390x
texlive-metafont-bin-svn40987-33.20160520.fc26.2.s390x
texlive-url-svn32528.3.4-33.fc26.2.noarch
texlive-fp-svn15878.0-33.fc26.2.noarch
texlive-latex-fonts-svn28888.0-33.fc26.2.noarch
texlive-mptopdf-bin-svn18674.0-33.20160520.fc26.2.noarch
texlive-fancybox-svn18304.1.4-33.fc26.2.noarch
texlive-lua-alt-getopt-svn29349.0.7.0-33.fc26.2.noarch
texlive-tex-bin-svn40987-33.20160520.fc26.2.s390x
texlive-texconfig-svn40768-33.fc26.2.noarch
texlive-wasy2-ps-svn35830.0-33.fc26.2.noarch
texlive-psfrag-svn15878.3.04-33.fc26.2.noarch
texlive-helvetic-svn31835.0-33.fc26.2.noarch
texlive-times-svn35058.0-33.fc26.2.noarch
texlive-cite-svn36428.5.5-33.fc26.2.noarch
texlive-fancyhdr-svn15878.3.1-33.fc26.2.noarch
texlive-luatex-bin-svn41091-33.20160520.fc26.2.s390x
texlive-lm-math-svn36915.1.959-33.fc26.2.noarch
texlive-ntgclass-svn15878.2.1a-33.fc26.2.noarch
texlive-sansmath-svn17997.1.1-33.fc26.2.noarch
texlive-textcase-svn15878.0-33.fc26.2.noarch
texlive-unicode-data-svn39808-33.fc26.2.noarch
texlive-breakurl-svn29901.1.40-33.fc26.2.noarch
texlive-latex-svn40218-33.fc26.2.noarch
texlive-lualatex-math-svn40621-33.fc26.2.noarch
texlive-pst-coil-svn37377.1.07-33.fc26.2.noarch
texlive-pst-plot-svn41242-33.fc26.2.noarch
texlive-unicode-math-svn38462-33.fc26.2.noarch
texlive-pst-blur-svn15878.2.0-33.fc26.2.noarch
texlive-cm-super-svn15878.0-33.fc26.2.noarch
texlive-wasysym-svn15878.2.0-33.fc26.2.noarch
texlive-collection-fontsrecommended-svn35830.0-33.20160520.fc26.2.noarch
libXv-1.0.11-2.fc26.s390x
ghc-srpm-macros-1.4.2-5.fc26.noarch
latex2html-2017.2-2.fc26.noarch
libXau-devel-1.0.8-7.fc26.s390x
libXcursor-devel-1.1.14-8.fc26.s390x
graphite2-devel-1.3.10-1.fc26.s390x
pixman-devel-0.34.0-3.fc26.s390x
wayland-protocols-devel-1.9-1.fc26.noarch
mesa-libGLES-devel-17.2.4-2.fc26.s390x
vte291-devel-0.48.4-1.fc26.s390x
ceph-devel-compat-10.2.7-2.fc26.s390x
lzo-devel-2.08-9.fc26.s390x
libiscsi-devel-1.15.0-3.fc26.s390x
avahi-autoipd-0.6.32-7.fc26.s390x
rpm-plugin-systemd-inhibit-4.13.0.2-1.fc26.s390x
python2-ndg_httpsclient-0.4.0-7.fc26.noarch
gettext-0.19.8.1-9.fc26.s390x
btrfs-progs-4.9.1-2.fc26.s390x
fedora-logos-26.0.1-1.fc26.s390x
dejagnu-1.6-2.fc26.noarch
libaio-devel-0.3.110-7.fc26.s390x
dos2unix-7.3.4-2.fc26.s390x
popt-1.16-12.fc26.s390x
tar-1.29-5.fc26.s390x
avahi-libs-0.6.32-7.fc26.s390x
m4-1.4.18-3.fc26.s390x
perl-Time-Local-1.250-2.fc26.noarch
libmetalink-0.1.3-2.fc26.s390x
jbigkit-libs-2.1-6.fc26.s390x
netpbm-10.80.00-2.fc26.s390x
perl-Digest-MD5-2.55-3.fc26.s390x
perl-Getopt-Long-2.49.1-2.fc26.noarch
libglvnd-opengl-1.0.0-1.fc26.s390x
libattr-devel-2.4.47-18.fc26.s390x
teckit-2.5.1-16.fc26.s390x
python3-six-1.10.0-9.fc26.noarch
python3-libcomps-0.1.8-3.fc26.s390x
python3-pyparsing-2.1.10-3.fc26.noarch
python2-markupsafe-0.23-13.fc26.s390x
python2-mock-2.0.0-4.fc26.noarch
python2-yubico-1.3.2-7.fc26.noarch
python2-smmap-2.0.3-1.fc26.noarch
librbd-devel-10.2.7-2.fc26.s390x
libnghttp2-1.21.1-1.fc26.s390x
ykpers-1.18.0-2.fc26.s390x
python3-librepo-1.8.0-1.fc26.s390x
systemtap-runtime-3.2-2.fc26.s390x
geoclue2-2.4.5-4.fc26.s390x
initscripts-9.72-1.fc26.s390x
plymouth-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
ebtables-2.0.10-22.fc26.s390x
gssproxy-0.7.0-9.fc26.s390x
libXext-1.3.3-5.fc26.s390x
mesa-libEGL-17.2.4-2.fc26.s390x
texlive-texlive.infra-bin-svn40312-33.20160520.fc26.2.s390x
texlive-thumbpdf-svn34621.3.16-33.fc26.2.noarch
texlive-carlisle-svn18258.0-33.fc26.2.noarch
texlive-gsftopk-svn40768-33.fc26.2.noarch
texlive-pdftex-svn41149-33.fc26.2.noarch
texlive-crop-svn15878.1.5-33.fc26.2.noarch
texlive-pxfonts-svn15878.0-33.fc26.2.noarch
texlive-enctex-svn34957.0-33.fc26.2.noarch
texlive-kastrup-svn15878.0-33.fc26.2.noarch
texlive-pspicture-svn15878.0-33.fc26.2.noarch
texlive-varwidth-svn24104.0.92-33.fc26.2.noarch
texlive-currfile-svn40725-33.fc26.2.noarch
texlive-pst-grad-svn15878.1.06-33.fc26.2.noarch
texlive-latex-bin-svn41438-33.fc26.2.noarch
texlive-ltxmisc-svn21927.0-33.fc26.2.noarch
lasi-1.1.2-7.fc26.s390x
adwaita-icon-theme-3.24.0-2.fc26.noarch
xz-devel-5.2.3-2.fc26.s390x
xorg-x11-fonts-Type1-7.5-17.fc26.noarch
libXi-devel-1.7.9-2.fc26.s390x
at-spi2-atk-devel-2.24.1-1.fc26.s390x
pango-devel-1.40.12-1.fc26.s390x
libcacard-devel-2.5.3-1.fc26.s390x
subversion-1.9.7-1.fc26.s390x
sudo-1.8.21p2-1.fc26.s390x
pykickstart-2.35-2.fc26.noarch
e2fsprogs-1.43.4-2.fc26.s390x
libbsd-0.8.3-3.fc26.s390x
c-ares-1.13.0-1.fc26.s390x
python2-pyxdg-0.25-12.fc26.noarch
nss-softokn-freebl-devel-3.34.0-1.0.fc26.s390x
strace-4.20-1.fc26.s390x
valgrind-3.13.0-12.fc26.s390x
libsss_idmap-1.16.0-4.fc26.s390x
gnutls-c++-3.5.16-4.fc26.s390x
libwayland-server-1.13.0-3.fc26.s390x
dhcp-client-4.3.5-10.fc26.s390x
man-pages-4.09-4.fc26.noarch
libffi-devel-3.1-12.fc26.s390x
libxml2-2.9.7-1.fc26.s390x
kmod-25-1.fc26.s390x
dnf-plugins-core-2.1.5-4.fc26.noarch
kmod-libs-25-1.fc26.s390x
pigz-2.4-1.fc26.s390x
pkgconf-pkg-config-1.3.12-2.fc26.s390x
libdrm-devel-2.4.89-1.fc26.s390x
gcc-go-7.3.1-2.fc26.s390x
system-python-3.6.4-2.fc26.s390x
python-rpm-macros-3-21.fc26.noarch
gpg-pubkey-a29cb19c-53bcbba6
quota-nls-4.03-9.fc26.noarch
xz-libs-5.2.3-2.fc26.s390x
gmp-6.1.2-4.fc26.s390x
file-5.30-11.fc26.s390x
libusbx-1.0.21-2.fc26.s390x
binutils-2.27-28.fc26.s390x
perl-Errno-1.25-395.fc26.s390x
perl-HTTP-Tiny-0.070-2.fc26.noarch
xml-common-0.6.3-45.fc26.noarch
opus-1.2.1-1.fc26.s390x
flac-libs-1.3.2-2.fc26.s390x
libacl-devel-2.2.52-15.fc26.s390x
coreutils-common-8.27-7.fc26.s390x
cracklib-2.9.6-5.fc26.s390x
pyliblzma-0.5.3-17.fc26.s390x
libnotify-0.7.7-2.fc26.s390x
python3-idna-2.5-1.fc26.noarch
python3-pyOpenSSL-16.2.0-6.fc26.noarch
python2-pbr-1.10.0-4.fc26.noarch
pyusb-1.0.0-4.fc26.noarch
librbd1-10.2.7-2.fc26.s390x
libnfs-1.9.8-3.fc26.s390x
libsolv-0.6.30-2.fc26.s390x
python3-pycurl-7.43.0-8.fc26.s390x
libyubikey-1.13-3.fc26.s390x
rpmlint-1.10-5.fc26.noarch
python2-pygpgme-0.3-22.fc26.s390x
s390utils-base-1.36.1-3.fc26.s390x
ppp-2.4.7-11.fc26.s390x
s390utils-cpuplugd-1.36.1-3.fc26.s390x
libXrender-0.9.10-2.fc26.s390x
libglvnd-gles-1.0.0-1.fc26.s390x
texlive-texlive.infra-svn41280-33.fc26.2.noarch
texlive-lm-svn28119.2.004-33.fc26.2.noarch
texlive-babelbib-svn25245.1.31-33.fc26.2.noarch
texlive-index-svn24099.4.1beta-33.fc26.2.noarch
texlive-pdftex-bin-svn40987-33.20160520.fc26.2.s390x
texlive-csquotes-svn39538-33.fc26.2.noarch
texlive-rsfs-svn15878.0-33.fc26.2.noarch
texlive-etex-svn37057.0-33.fc26.2.noarch
texlive-knuth-lib-svn35820.0-33.fc26.2.noarch
texlive-pst-math-svn34786.0.63-33.fc26.2.noarch
texlive-utopia-svn15878.0-33.fc26.2.noarch
texlive-eso-pic-svn37925.2.0g-33.fc26.2.noarch
texlive-pst-fill-svn15878.1.01-33.fc26.2.noarch
texlive-latex-bin-bin-svn14050.0-33.20160520.fc26.2.noarch
texlive-jknapltx-svn19440.0-33.fc26.2.noarch
texlive-collection-latexrecommended-svn35765.0-33.20160520.fc26.2.noarch
adwaita-cursor-theme-3.24.0-2.fc26.noarch
xorg-x11-fonts-ISO8859-1-100dpi-7.5-17.fc26.noarch
libXcomposite-devel-0.4.4-9.fc26.s390x
at-spi2-core-devel-2.24.1-1.fc26.s390x
harfbuzz-devel-1.4.4-1.fc26.s390x
rpmdevtools-8.10-2.fc26.noarch
texi2html-5.0-5.fc26.noarch
libnfs-devel-1.9.8-3.fc26.s390x
firewalld-0.4.4.5-1.fc26.noarch
wpa_supplicant-2.6-12.fc26.s390x
systemtap-sdt-devel-3.2-2.fc26.s390x
newt-python-0.52.20-1.fc26.s390x
perl-Mozilla-CA-20160104-4.fc26.noarch
pth-2.0.7-28.fc26.s390x
python3-pyxdg-0.25-12.fc26.noarch
nss-softokn-devel-3.34.0-1.0.fc26.s390x
timedatex-0.4-3.fc26.s390x
libjpeg-turbo-1.5.3-1.fc26.s390x
libsss_nss_idmap-1.16.0-4.fc26.s390x
dnf-yum-2.7.5-2.fc26.noarch
libuv-devel-1.11.0-1.fc26.s390x
libstdc++-7.3.1-2.fc26.s390x
libgo-7.3.1-2.fc26.s390x
python3-dnf-plugins-core-2.1.5-4.fc26.noarch
gtk3-3.22.21-3.fc26.s390x
perl-threads-2.21-1.fc26.s390x
pkgconf-m4-1.3.12-2.fc26.noarch
gtk3-devel-3.22.21-3.fc26.s390x
gcc-objc-7.3.1-2.fc26.s390x
curl-7.53.1-14.fc26.s390x
vim-minimal-8.0.1438-1.fc26.s390x
python-async-0.6.1-9.fc22.s390x
poppler-data-0.4.7-7.fc26.noarch
ocaml-srpm-macros-4-2.fc26.noarch
libuuid-2.30.2-1.fc26.s390x
libgpg-error-1.25-2.fc26.s390x
graphite2-1.3.10-1.fc26.s390x
perl-Text-Tabs+Wrap-2013.0523-366.fc26.noarch
perl-Error-0.17024-8.fc26.noarch
which-2.21-2.fc26.s390x
libXau-1.0.8-7.fc26.s390x
orc-0.4.27-1.fc26.s390x
perl-Pod-Perldoc-3.28-1.fc26.noarch
libsndfile-1.0.28-6.fc26.s390x
patch-2.7.5-4.fc26.s390x
gzip-1.8-2.fc26.s390x
python-ipaddress-1.0.16-4.fc26.noarch
yum-metadata-parser-1.1.4-18.fc26.s390x
python3-dbus-1.2.4-6.fc26.s390x
python3-cryptography-2.0.2-2.fc26.s390x
python3-kickstart-2.35-2.fc26.noarch
python2-imagesize-0.7.1-5.fc26.noarch
python2-jinja2-2.9.6-1.fc26.noarch
libradosstriper-devel-10.2.7-2.fc26.s390x
soundtouch-1.9.2-4.fc26.s390x
libndp-1.6-2.fc26.s390x
rpm-4.13.0.2-1.fc26.s390x
rest-0.8.0-2.fc26.s390x
libvisual-0.4.0-21.fc26.s390x
python2-hawkey-0.11.1-1.fc26.s390x
fakeroot-libs-1.22-1.fc26.s390x
device-mapper-event-libs-1.02.137-6.fc26.s390x
cyrus-sasl-2.1.26-32.fc26.s390x
cronie-anacron-1.5.1-5.fc26.s390x
libpath_utils-0.2.1-34.fc26.s390x
libX11-common-1.6.5-2.fc26.noarch
libXft-2.3.2-5.fc26.s390x
gtk2-2.24.31-4.fc26.s390x
texlive-etoolbox-svn38031.2.2a-33.fc26.2.noarch
texlive-multido-svn18302.1.42-33.fc26.2.noarch
texlive-glyphlist-svn28576.0-33.fc26.2.noarch
texlive-setspace-svn24881.6.7a-33.fc26.2.noarch
texlive-mathtools-svn38833-33.fc26.2.noarch
texlive-ncntrsbk-svn31835.0-33.fc26.2.noarch
texlive-dvisvgm-def-svn41011-33.fc26.2.noarch
texlive-ifetex-svn24853.1.2-33.fc26.2.noarch
texlive-parskip-svn19963.2.0-33.fc26.2.noarch
texlive-bera-svn20031.0-33.fc26.2.noarch
texlive-pgf-svn40966-33.fc26.2.noarch
texlive-auto-pst-pdf-svn23723.0.6-33.fc26.2.noarch
texlive-ctable-svn38672-33.fc26.2.noarch
texlive-typehtml-svn17134.0-33.fc26.2.noarch
mesa-libGLES-17.2.4-2.fc26.s390x
vte291-0.48.4-1.fc26.s390x
libcephfs_jni1-10.2.7-2.fc26.s390x
bzip2-devel-1.0.6-22.fc26.s390x
expat-devel-2.2.4-1.fc26.s390x
libsepol-devel-2.6-2.fc26.s390x
glib2-static-2.52.3-2.fc26.s390x
virglrenderer-devel-0.6.0-1.20170210git76b3da97b.fc26.s390x
parted-3.2-24.fc26.s390x
python3-beautifulsoup4-4.6.0-1.fc26.noarch
python-bunch-1.0.1-10.fc26.noarch
lz4-1.8.0-1.fc26.s390x
nss-util-3.34.0-1.0.fc26.s390x
openssh-clients-7.5p1-4.fc26.s390x
chrony-3.2-1.fc26.s390x
dnf-conf-2.7.5-2.fc26.noarch
sssd-client-1.16.0-4.fc26.s390x
bodhi-client-2.12.2-3.fc26.noarch
libuv-1.11.0-1.fc26.s390x
glibc-2.25-13.fc26.s390x
libgomp-7.3.1-2.fc26.s390x
cmake-rpm-macros-3.10.1-11.fc26.noarch
gtk-update-icon-cache-3.22.21-3.fc26.s390x
pcre2-utf32-10.23-13.fc26.s390x
kernel-modules-4.15.4-200.fc26.s390x
libcurl-devel-7.53.1-14.fc26.s390x
webkitgtk4-2.18.6-1.fc26.s390x
libstdc++-static-7.3.1-2.fc26.s390x
rsync-3.1.3-2.fc26.s390x
hawkey-0.6.4-3.fc25.s390x
perl-srpm-macros-1-21.fc26.noarch
expat-2.2.4-1.fc26.s390x
chkconfig-1.10-1.fc26.s390x
findutils-4.6.0-12.fc26.s390x
mesa-libwayland-egl-17.2.4-2.fc26.s390x
procps-ng-3.3.10-13.fc26.s390x
mesa-libglapi-17.2.4-2.fc26.s390x
perl-Unicode-Normalize-1.25-366.fc26.s390x
perl-IO-Socket-IP-0.39-1.fc26.noarch
hunspell-en-US-0.20140811.1-6.fc26.noarch
libxcb-1.12-3.fc26.s390x
perl-Pod-Escapes-1.07-366.fc26.noarch
perl-Pod-Usage-1.69-2.fc26.noarch
libtheora-1.1.1-15.fc26.s390x
tcp_wrappers-7.6-85.fc26.s390x
coreutils-8.27-7.fc26.s390x
libmount-2.30.2-1.fc26.s390x
python2-iniparse-0.4-24.fc26.noarch
python2-decorator-4.0.11-2.fc26.noarch
ModemManager-glib-1.6.10-1.fc26.s390x
python3-decorator-4.0.11-2.fc26.noarch
python3-cffi-1.9.1-2.fc26.s390x
python-bugzilla-cli-2.1.0-1.fc26.noarch
python2-funcsigs-1.0.2-5.fc26.noarch
python2-babel-2.3.4-5.fc26.noarch
python-bugzilla-2.1.0-1.fc26.noarch
libradosstriper1-10.2.7-2.fc26.s390x
snappy-1.1.4-3.fc26.s390x
libmpcdec-1.2.6-17.fc26.s390x
rpm-libs-4.13.0.2-1.fc26.s390x
python-urlgrabber-3.10.1-11.fc26.noarch
sysfsutils-2.1.0-20.fc26.s390x
python3-hawkey-0.11.1-1.fc26.s390x
ethtool-4.13-1.fc26.s390x
iputils-20161105-5.fc26.s390x
plymouth-scripts-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
cronie-1.5.1-5.fc26.s390x
libini_config-1.3.1-34.fc26.s390x
libX11-1.6.5-2.fc26.s390x
libglvnd-egl-1.0.0-1.fc26.s390x
texlive-kpathsea-svn41139-33.fc26.2.noarch
texlive-thumbpdf-bin-svn6898.0-33.20160520.fc26.2.noarch
texlive-subfig-svn15878.1.3-33.fc26.2.noarch
texlive-gsftopk-bin-svn40473-33.20160520.fc26.2.s390x
texlive-tex-ini-files-svn40533-33.fc26.2.noarch
texlive-qstest-svn15878.0-33.fc26.2.noarch
texlive-palatino-svn31835.0-33.fc26.2.noarch
texlive-ec-svn25033.1.0-33.fc26.2.noarch
texlive-iftex-svn29654.0.2-33.fc26.2.noarch
texlive-pslatex-svn16416.0-33.fc26.2.noarch
texlive-algorithms-svn38085.0.1-33.fc26.2.noarch
texlive-filehook-svn24280.0.5d-33.fc26.2.noarch
texlive-pst-node-svn40743-33.fc26.2.noarch
texlive-rotating-svn16832.2.16b-33.fc26.2.noarch
texlive-seminar-svn34011.1.62-33.fc26.2.noarch
libuuid-devel-2.30.2-1.fc26.s390x
libXinerama-devel-1.1.3-7.fc26.s390x
emacs-common-25.3-3.fc26.s390x
fedora-packager-0.6.0.1-2.fc26.noarch
snappy-devel-1.1.4-3.fc26.s390x
authconfig-7.0.1-2.fc26.s390x
newt-python3-0.52.20-1.fc26.s390x
python-decoratortools-1.8-13.fc26.noarch
python-systemd-doc-234-1.fc26.s390x
openssl-libs-1.1.0g-1.fc26.s390x
git-core-2.13.6-2.fc26.s390x
libsss_certmap-1.16.0-4.fc26.s390x
lsof-4.89-5.fc26.s390x
glibc-all-langpacks-2.25-13.fc26.s390x
audit-libs-2.8.2-1.fc26.s390x
python3-3.6.4-2.fc26.s390x
gcc-7.3.1-2.fc26.s390x
pcre2-utf16-10.23-13.fc26.s390x
kernel-core-4.15.4-200.fc26.s390x
pcre-static-8.41-5.fc26.s390x
dracut-config-rescue-046-8.git20180105.fc26.s390x
webkitgtk4-plugin-process-gtk2-2.18.6-1.fc26.s390x
perl-Time-HiRes-1.9753-1.fc26.s390x
haveged-1.9.1-6.fc26.s390x
gpg-pubkey-a0a7badb-52844296
gpg-pubkey-e372e838-56fd7943
gpg-pubkey-3b921d09-57a87096
google-roboto-slab-fonts-1.100263-0.5.20150923git.fc26.noarch
libreport-filesystem-2.9.1-3.fc26.s390x
libcom_err-1.43.4-2.fc26.s390x
libffi-3.1-12.fc26.s390x
keyutils-libs-1.5.10-1.fc26.s390x
diffutils-3.5-3.fc26.s390x
apr-util-1.5.4-6.fc26.s390x
bluez-libs-5.46-6.fc26.s390x
libksba-1.3.5-3.fc26.s390x
ncurses-6.0-8.20170212.fc26.s390x
gsm-1.0.17-1.fc26.s390x
libteam-1.27-1.fc26.s390x
perl-Fedora-VSP-0.001-5.fc26.noarch
libusb-0.1.5-8.fc26.s390x
acl-2.2.52-15.fc26.s390x
dwz-0.12-3.fc26.s390x
libblkid-2.30.2-1.fc26.s390x
polkit-libs-0.113-8.fc26.s390x
dbus-python-1.2.4-6.fc26.s390x
gts-0.7.6-30.20121130.fc26.s390x
libfdisk-2.30.2-1.fc26.s390x
python3-pycparser-2.14-10.fc26.noarch
python3-bugzilla-2.1.0-1.fc26.noarch
python2-docutils-0.13.1-4.fc26.noarch
pytz-2016.10-4.fc26.noarch
python2-requests-2.13.0-1.fc26.noarch
libcephfs-devel-10.2.7-2.fc26.s390x
ncurses-c++-libs-6.0-8.20170212.fc26.s390x
GeoIP-1.6.11-1.fc26.s390x
liblockfile-1.09-5.fc26.s390x
rpm-plugin-selinux-4.13.0.2-1.fc26.s390x
systemtap-devel-3.2-2.fc26.s390x
libsysfs-2.1.0-20.fc26.s390x
libdnf-0.11.1-1.fc26.s390x
mesa-libgbm-17.2.4-2.fc26.s390x
lvm2-libs-2.02.168-6.fc26.s390x
libXfixes-5.0.3-2.fc26.s390x
brlapi-0.6.6-5.fc26.s390x
texlive-metafont-svn40793-33.fc26.2.noarch
texlive-graphics-cfg-svn40269-33.fc26.2.noarch
texlive-mptopdf-svn41282-33.fc26.2.noarch
texlive-makeindex-bin-svn40473-33.20160520.fc26.2.s390x
texlive-texlive-scripts-bin-svn29741.0-33.20160520.fc26.2.noarch
texlive-sauerj-svn15878.0-33.fc26.2.noarch
texlive-txfonts-svn15878.0-33.fc26.2.noarch
texlive-filecontents-svn24250.1.3-33.fc26.2.noarch
texlive-lualibs-svn40370-33.fc26.2.noarch
texlive-section-svn20180.0-33.fc26.2.noarch
texlive-ucharcat-svn38907-33.fc26.2.noarch
texlive-hyperref-svn41396-33.fc26.2.noarch
texlive-pst-3d-svn17257.1.10-33.fc26.2.noarch
texlive-oberdiek-svn41346-33.fc26.2.noarch
texlive-ae-svn15878.1.4-33.fc26.2.noarch
texlive-collection-basic-svn41149-33.20160520.fc26.2.noarch
gnat-srpm-macros-4-2.fc26.noarch
glib2-devel-2.52.3-2.fc26.s390x
netpbm-progs-10.80.00-2.fc26.s390x
libXxf86vm-devel-1.1.4-4.fc26.s390x
nettle-devel-3.3-2.fc26.s390x
cairo-gobject-devel-1.14.10-1.fc26.s390x
fedora-rpm-macros-26-2.fc26.noarch
elfutils-devel-0.169-1.fc26.s390x
libidn-devel-1.33-2.fc26.s390x
s390utils-1.36.1-3.fc26.s390x
libtool-2.4.6-17.fc26.s390x
python3-cssselect-0.9.2-4.fc26.noarch
python2-cssselect-0.9.2-4.fc26.noarch
bison-3.0.4-6.fc26.s390x
rootfiles-8.1-20.fc26.noarch
git-core-doc-2.13.6-2.fc26.s390x
boost-system-1.63.0-10.fc26.s390x
gnutls-dane-3.5.16-4.fc26.s390x
python3-urllib3-1.20-2.fc26.noarch
libsss_autofs-1.16.0-4.fc26.s390x
libgcc-7.3.1-2.fc26.s390x
system-python-libs-3.6.4-2.fc26.s390x
pcre-cpp-8.41-5.fc26.s390x
python3-distro-1.2.0-1.fc26.noarch
libnfsidmap-2.2.1-4.rc2.fc26.s390x
selinux-policy-3.13.1-260.18.fc26.noarch
glusterfs-devel-3.10.10-1.fc26.s390x
kernel-4.15.4-200.fc26.s390x
glibc-static-2.25-13.fc26.s390x
xapian-core-libs-1.4.5-1.fc26.s390x
publicsuffix-list-dafsa-20171228-1.fc26.noarch
=== TEST BEGIN ===
Using CC: /home/fam/bin/cc
Install prefix    /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install
BIOS directory    /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/share/qemu
firmware path     /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/share/qemu-firmware
binary directory  /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/bin
library directory /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/lib
module directory  /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/lib/qemu
libexec directory /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/libexec
include directory /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/include
config directory  /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/etc
local state directory   /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/var
Manual directory  /var/tmp/patchew-tester-tmp-3_ytlhdd/src/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /var/tmp/patchew-tester-tmp-3_ytlhdd/src
GIT binary        git
GIT submodules    ui/keycodemapdb capstone
C compiler        /home/fam/bin/cc
Host C compiler   cc
C++ compiler      c++
Objective-C compiler /home/fam/bin/cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1   -Werror -DHAS_LIBSSH2_SFTP_FSYNC -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include  -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wexpansion-to-defined -Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -I/usr/include/p11-kit-1     -I/usr/include/libpng16  -I/usr/include/libdrm  -I$(SRC_PATH)/capstone/include
LDFLAGS           -Wl,--warn-common -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          s390x
host big endian   yes
target list       aarch64-softmmu alpha-softmmu arm-softmmu cris-softmmu hppa-softmmu i386-softmmu lm32-softmmu m68k-softmmu microblazeel-softmmu microblaze-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu mips-softmmu moxie-softmmu nios2-softmmu or1k-softmmu ppc64-softmmu ppcemb-softmmu ppc-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu sh4eb-softmmu sh4-softmmu sparc64-softmmu sparc-softmmu tricore-softmmu unicore32-softmmu x86_64-softmmu xtensaeb-softmmu xtensa-softmmu aarch64_be-linux-user aarch64-linux-user alpha-linux-user armeb-linux-user arm-linux-user cris-linux-user hppa-linux-user i386-linux-user m68k-linux-user microblazeel-linux-user microblaze-linux-user mips64el-linux-user mips64-linux-user mipsel-linux-user mips-linux-user mipsn32el-linux-user mipsn32-linux-user nios2-linux-user or1k-linux-user ppc64abi32-linux-user ppc64le-linux-user ppc64-linux-user ppc-linux-user riscv32-linux-user riscv64-linux-user s390x-linux-user sh4eb-linux-user sh4-linux-user sparc32plus-linux-user sparc64-linux-user sparc-linux-user tilegx-linux-user x86_64-linux-user xtensaeb-linux-user xtensa-linux-user
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
SDL support       yes (2.0.7)
GTK support       yes (3.22.21)
GTK GL support    yes
VTE support       yes (0.48.4)
TLS priority      NORMAL
GNUTLS support    yes
GNUTLS rnd        yes
libgcrypt         no
libgcrypt kdf     no
nettle            yes (3.3)
nettle kdf        yes
libtasn1          yes
curses support    yes
virgl support     yes
curl support      yes
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    yes
Multipath support no
VNC support       yes
VNC SASL support  yes
VNC JPEG support  yes
VNC PNG support   yes
xen support       no
brlapi support    yes
bluez  support    yes
Documentation     yes
PIE               no
vde support       no
netmap support    no
Linux AIO support yes
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
HAX support       no
HVF support       no
WHPX support      no
TCG support       yes
TCG debug enabled no
TCG interpreter   no
malloc trim support yes
RDMA support      no
fdt support       yes
membarrier        no
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
posix_memalign    yes
libcap-ng support yes
vhost-net support yes
vhost-crypto support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends    log
spice support     no 
rbd support       yes
xfsctl support    no
smartcard support yes
libusb            yes
usb net redir     yes
OpenGL support    yes
OpenGL dmabufs    yes
libiscsi support  yes
libnfs support    yes
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   yes
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
crypto afalg      no
GlusterFS support yes
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   yes
TPM passthrough   no
TPM emulator      yes
QOM debugging     yes
Live block migration yes
lzo support       yes
snappy support    yes
bzip2 support     yes
NUMA host support no
libxml2           yes
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
VxHS block device no
capstone          git
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     alpha-softmmu/config-devices.mak.tmp
  GEN     arm-softmmu/config-devices.mak.tmp
  GEN     cris-softmmu/config-devices.mak.tmp
  GEN     cris-softmmu/config-devices.mak
  GEN     alpha-softmmu/config-devices.mak
  GEN     hppa-softmmu/config-devices.mak.tmp
  GEN     arm-softmmu/config-devices.mak
  GEN     i386-softmmu/config-devices.mak.tmp
  GEN     aarch64-softmmu/config-devices.mak
  GEN     lm32-softmmu/config-devices.mak.tmp
  GEN     m68k-softmmu/config-devices.mak.tmp
  GEN     lm32-softmmu/config-devices.mak
  GEN     m68k-softmmu/config-devices.mak
  GEN     hppa-softmmu/config-devices.mak
  GEN     i386-softmmu/config-devices.mak
  GEN     microblazeel-softmmu/config-devices.mak.tmp
  GEN     microblaze-softmmu/config-devices.mak.tmp
  GEN     mips64el-softmmu/config-devices.mak.tmp
  GEN     mips64-softmmu/config-devices.mak.tmp
  GEN     microblaze-softmmu/config-devices.mak
  GEN     microblazeel-softmmu/config-devices.mak
  GEN     mipsel-softmmu/config-devices.mak.tmp
  GEN     mips-softmmu/config-devices.mak.tmp
  GEN     mips64el-softmmu/config-devices.mak
  GEN     moxie-softmmu/config-devices.mak.tmp
  GEN     mips64-softmmu/config-devices.mak
  GEN     nios2-softmmu/config-devices.mak.tmp
  GEN     moxie-softmmu/config-devices.mak
  GEN     mipsel-softmmu/config-devices.mak
  GEN     or1k-softmmu/config-devices.mak.tmp
  GEN     mips-softmmu/config-devices.mak
  GEN     ppc64-softmmu/config-devices.mak.tmp
  GEN     nios2-softmmu/config-devices.mak
  GEN     ppcemb-softmmu/config-devices.mak.tmp
  GEN     ppc-softmmu/config-devices.mak.tmp
  GEN     or1k-softmmu/config-devices.mak
  GEN     riscv32-softmmu/config-devices.mak.tmp
  GEN     riscv32-softmmu/config-devices.mak
  GEN     riscv64-softmmu/config-devices.mak.tmp
  GEN     ppc-softmmu/config-devices.mak
  GEN     ppcemb-softmmu/config-devices.mak
  GEN     ppc64-softmmu/config-devices.mak
  GEN     s390x-softmmu/config-devices.mak.tmp
  GEN     sh4eb-softmmu/config-devices.mak.tmp
  GEN     sh4-softmmu/config-devices.mak.tmp
  GEN     riscv64-softmmu/config-devices.mak
  GEN     sparc64-softmmu/config-devices.mak.tmp
  GEN     s390x-softmmu/config-devices.mak
  GEN     sparc-softmmu/config-devices.mak.tmp
  GEN     sh4-softmmu/config-devices.mak
  GEN     sh4eb-softmmu/config-devices.mak
  GEN     tricore-softmmu/config-devices.mak.tmp
  GEN     sparc64-softmmu/config-devices.mak
  GEN     unicore32-softmmu/config-devices.mak.tmp
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     sparc-softmmu/config-devices.mak
  GEN     tricore-softmmu/config-devices.mak
  GEN     xtensaeb-softmmu/config-devices.mak.tmp
  GEN     xtensa-softmmu/config-devices.mak.tmp
  GEN     unicore32-softmmu/config-devices.mak
  GEN     xtensaeb-softmmu/config-devices.mak
  GEN     x86_64-softmmu/config-devices.mak
  GEN     aarch64_be-linux-user/config-devices.mak.tmp
  GEN     aarch64-linux-user/config-devices.mak.tmp
  GEN     xtensa-softmmu/config-devices.mak
  GEN     alpha-linux-user/config-devices.mak.tmp
  GEN     armeb-linux-user/config-devices.mak.tmp
  GEN     aarch64_be-linux-user/config-devices.mak
  GEN     aarch64-linux-user/config-devices.mak
  GEN     arm-linux-user/config-devices.mak.tmp
  GEN     cris-linux-user/config-devices.mak.tmp
  GEN     alpha-linux-user/config-devices.mak
  GEN     hppa-linux-user/config-devices.mak.tmp
  GEN     armeb-linux-user/config-devices.mak
  GEN     cris-linux-user/config-devices.mak
  GEN     arm-linux-user/config-devices.mak
  GEN     i386-linux-user/config-devices.mak.tmp
  GEN     m68k-linux-user/config-devices.mak.tmp
  GEN     microblazeel-linux-user/config-devices.mak.tmp
  GEN     hppa-linux-user/config-devices.mak
  GEN     m68k-linux-user/config-devices.mak
  GEN     i386-linux-user/config-devices.mak
  GEN     microblaze-linux-user/config-devices.mak.tmp
  GEN     mips64el-linux-user/config-devices.mak.tmp
  GEN     mips64-linux-user/config-devices.mak.tmp
  GEN     microblazeel-linux-user/config-devices.mak
  GEN     mipsel-linux-user/config-devices.mak.tmp
  GEN     mips64-linux-user/config-devices.mak
  GEN     microblaze-linux-user/config-devices.mak
  GEN     mips64el-linux-user/config-devices.mak
  GEN     mipsel-linux-user/config-devices.mak
  GEN     mips-linux-user/config-devices.mak.tmp
  GEN     mipsn32el-linux-user/config-devices.mak.tmp
  GEN     mipsn32-linux-user/config-devices.mak.tmp
  GEN     nios2-linux-user/config-devices.mak.tmp
  GEN     mipsn32el-linux-user/config-devices.mak
  GEN     mips-linux-user/config-devices.mak
  GEN     nios2-linux-user/config-devices.mak
  GEN     or1k-linux-user/config-devices.mak.tmp
  GEN     mipsn32-linux-user/config-devices.mak
  GEN     ppc64abi32-linux-user/config-devices.mak.tmp
  GEN     ppc64le-linux-user/config-devices.mak.tmp
  GEN     ppc64-linux-user/config-devices.mak.tmp
  GEN     or1k-linux-user/config-devices.mak
  GEN     ppc64abi32-linux-user/config-devices.mak
  GEN     ppc-linux-user/config-devices.mak.tmp
  GEN     ppc64le-linux-user/config-devices.mak
  GEN     riscv32-linux-user/config-devices.mak.tmp
  GEN     riscv64-linux-user/config-devices.mak.tmp
  GEN     ppc64-linux-user/config-devices.mak
  GEN     ppc-linux-user/config-devices.mak
  GEN     s390x-linux-user/config-devices.mak.tmp
  GEN     sh4eb-linux-user/config-devices.mak.tmp
  GEN     riscv64-linux-user/config-devices.mak
  GEN     riscv32-linux-user/config-devices.mak
  GEN     sh4-linux-user/config-devices.mak.tmp
  GEN     s390x-linux-user/config-devices.mak
  GEN     sparc32plus-linux-user/config-devices.mak.tmp
  GEN     sh4eb-linux-user/config-devices.mak
  GEN     sparc64-linux-user/config-devices.mak.tmp
  GEN     sh4-linux-user/config-devices.mak
  GEN     sparc-linux-user/config-devices.mak.tmp
  GEN     tilegx-linux-user/config-devices.mak.tmp
  GEN     sparc32plus-linux-user/config-devices.mak
  GEN     x86_64-linux-user/config-devices.mak.tmp
  GEN     sparc64-linux-user/config-devices.mak
  GEN     sparc-linux-user/config-devices.mak
  GEN     xtensaeb-linux-user/config-devices.mak.tmp
  GEN     tilegx-linux-user/config-devices.mak
  GEN     xtensa-linux-user/config-devices.mak.tmp
  GEN     x86_64-linux-user/config-devices.mak
  GEN     xtensaeb-linux-user/config-devices.mak
  GEN     config-host.h
  GEN     xtensa-linux-user/config-devices.mak
  GIT     ui/keycodemapdb capstone
  GEN     qemu-options.def
  GEN     qapi-gen
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.h
  GEN     trace/generated-helpers.c
  GEN     module_block.h
  GEN     tests/test-qapi-gen
  GEN     trace-root.h
  GEN     util/trace.h
  GEN     crypto/trace.h
  GEN     io/trace.h
  GEN     migration/trace.h
Submodule 'capstone' (git://git.qemu.org/capstone.git) registered for path 'capstone'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
  GEN     block/trace.h
  GEN     chardev/trace.h
Cloning into '/var/tmp/patchew-tester-tmp-3_ytlhdd/src/capstone'...
  GEN     hw/block/trace.h
  GEN     hw/block/dataplane/trace.h
  GEN     hw/char/trace.h
  GEN     hw/intc/trace.h
  GEN     hw/net/trace.h
  GEN     hw/rdma/trace.h
  GEN     hw/rdma/vmw/trace.h
  GEN     hw/virtio/trace.h
  GEN     hw/audio/trace.h
  GEN     hw/misc/trace.h
  GEN     hw/misc/macio/trace.h
  GEN     hw/usb/trace.h
  GEN     hw/scsi/trace.h
  GEN     hw/nvram/trace.h
  GEN     hw/display/trace.h
  GEN     hw/input/trace.h
  GEN     hw/timer/trace.h
  GEN     hw/dma/trace.h
  GEN     hw/sparc/trace.h
  GEN     hw/sparc64/trace.h
  GEN     hw/sd/trace.h
  GEN     hw/isa/trace.h
  GEN     hw/mem/trace.h
  GEN     hw/i386/trace.h
  GEN     hw/i386/xen/trace.h
  GEN     hw/9pfs/trace.h
  GEN     hw/ppc/trace.h
  GEN     hw/pci/trace.h
  GEN     hw/pci-host/trace.h
  GEN     hw/s390x/trace.h
  GEN     hw/vfio/trace.h
  GEN     hw/acpi/trace.h
  GEN     hw/arm/trace.h
  GEN     hw/alpha/trace.h
  GEN     hw/hppa/trace.h
  GEN     hw/xen/trace.h
  GEN     hw/ide/trace.h
  GEN     hw/tpm/trace.h
  GEN     ui/trace.h
  GEN     audio/trace.h
  GEN     net/trace.h
  GEN     target/arm/trace.h
  GEN     target/i386/trace.h
  GEN     target/mips/trace.h
  GEN     target/sparc/trace.h
  GEN     target/s390x/trace.h
  GEN     target/ppc/trace.h
  GEN     qom/trace.h
  GEN     linux-user/trace.h
  GEN     qapi/trace.h
  GEN     accel/tcg/trace.h
  GEN     accel/kvm/trace.h
  GEN     nbd/trace.h
  GEN     scsi/trace.h
  GEN     trace-root.c
  GEN     util/trace.c
  GEN     crypto/trace.c
  GEN     io/trace.c
  GEN     migration/trace.c
  GEN     block/trace.c
  GEN     chardev/trace.c
  GEN     hw/block/trace.c
  GEN     hw/block/dataplane/trace.c
  GEN     hw/char/trace.c
  GEN     hw/intc/trace.c
  GEN     hw/net/trace.c
  GEN     hw/rdma/trace.c
  GEN     hw/rdma/vmw/trace.c
  GEN     hw/virtio/trace.c
  GEN     hw/audio/trace.c
  GEN     hw/misc/trace.c
  GEN     hw/misc/macio/trace.c
  GEN     hw/usb/trace.c
  GEN     hw/scsi/trace.c
  GEN     hw/nvram/trace.c
  GEN     hw/display/trace.c
  GEN     hw/input/trace.c
  GEN     hw/timer/trace.c
  GEN     hw/dma/trace.c
  GEN     hw/sparc/trace.c
  GEN     hw/sparc64/trace.c
  GEN     hw/sd/trace.c
  GEN     hw/isa/trace.c
  GEN     hw/mem/trace.c
  GEN     hw/i386/trace.c
  GEN     hw/i386/xen/trace.c
  GEN     hw/9pfs/trace.c
  GEN     hw/ppc/trace.c
  GEN     hw/pci/trace.c
  GEN     hw/pci-host/trace.c
  GEN     hw/s390x/trace.c
  GEN     hw/vfio/trace.c
  GEN     hw/acpi/trace.c
  GEN     hw/arm/trace.c
  GEN     hw/alpha/trace.c
  GEN     hw/hppa/trace.c
  GEN     hw/xen/trace.c
  GEN     hw/ide/trace.c
  GEN     hw/tpm/trace.c
  GEN     ui/trace.c
  GEN     audio/trace.c
  GEN     net/trace.c
  GEN     target/arm/trace.c
  GEN     target/i386/trace.c
  GEN     target/mips/trace.c
  GEN     target/sparc/trace.c
  GEN     target/s390x/trace.c
  GEN     target/ppc/trace.c
  GEN     qom/trace.c
  GEN     linux-user/trace.c
  GEN     qapi/trace.c
  GEN     accel/tcg/trace.c
  GEN     accel/kvm/trace.c
  GEN     nbd/trace.c
  GEN     scsi/trace.c
  GEN     config-all-devices.mak
Cloning into '/var/tmp/patchew-tester-tmp-3_ytlhdd/src/ui/keycodemapdb'...
  GEN     ui/input-keymap-atset1-to-qcode.c
  GEN     ui/input-keymap-linux-to-qcode.c
  GEN     ui/input-keymap-qcode-to-atset1.c
  GEN     ui/input-keymap-qcode-to-atset2.c
  GEN     ui/input-keymap-qcode-to-atset3.c
  GEN     ui/input-keymap-qcode-to-linux.c
  CC      cs.o
  GEN     ui/input-keymap-qcode-to-qnum.c
  GEN     ui/input-keymap-qcode-to-sun.c
  GEN     ui/input-keymap-qnum-to-qcode.c
  GEN     ui/input-keymap-usb-to-qcode.c
  GEN     ui/input-keymap-win32-to-qcode.c
  GEN     ui/input-keymap-x11-to-qcode.c
  GEN     ui/input-keymap-xorgevdev-to-qcode.c
  GEN     ui/input-keymap-xorgkbd-to-qcode.c
  GEN     ui/input-keymap-xorgxquartz-to-qcode.c
  GEN     ui/input-keymap-xorgxwin-to-qcode.c
  CC      utils.o
  CC      SStream.o
  CC      MCInstrDesc.o
  CC      MCRegisterInfo.o
  CC      arch/ARM/ARMDisassembler.o
  CC      arch/ARM/ARMInstPrinter.o
  CC      arch/ARM/ARMMapping.o
  CC      arch/ARM/ARMModule.o
  CC      arch/AArch64/AArch64BaseInfo.o
  CC      arch/AArch64/AArch64Disassembler.o
  CC      arch/AArch64/AArch64InstPrinter.o
  CC      arch/AArch64/AArch64Mapping.o
  CC      arch/AArch64/AArch64Module.o
  CC      arch/Mips/MipsDisassembler.o
  CC      arch/Mips/MipsInstPrinter.o
  CC      arch/Mips/MipsMapping.o
  CC      arch/Mips/MipsModule.o
  CC      arch/PowerPC/PPCDisassembler.o
  CC      arch/PowerPC/PPCInstPrinter.o
  CC      arch/PowerPC/PPCMapping.o
  CC      arch/PowerPC/PPCModule.o
  CC      arch/Sparc/SparcDisassembler.o
  CC      arch/Sparc/SparcInstPrinter.o
  CC      arch/Sparc/SparcMapping.o
  CC      arch/Sparc/SparcModule.o
  CC      arch/SystemZ/SystemZDisassembler.o
  CC      arch/SystemZ/SystemZInstPrinter.o
  CC      arch/SystemZ/SystemZMapping.o
  CC      arch/SystemZ/SystemZModule.o
  CC      arch/SystemZ/SystemZMCTargetDesc.o
  CC      arch/X86/X86DisassemblerDecoder.o
  CC      arch/X86/X86Disassembler.o
  CC      arch/X86/X86IntelInstPrinter.o
  CC      arch/X86/X86ATTInstPrinter.o
  CC      arch/X86/X86Mapping.o
  CC      arch/X86/X86Module.o
  CC      arch/XCore/XCoreDisassembler.o
  CC      arch/XCore/XCoreInstPrinter.o
  CC      arch/XCore/XCoreMapping.o
  CC      arch/XCore/XCoreModule.o
  CC      MCInst.o
  AR      libcapstone.a
ar: creating /var/tmp/patchew-tester-tmp-3_ytlhdd/src/build/capstone/libcapstone.a
  GEN     docs/version.texi
  GEN     qemu-options.texi
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qemu-monitor.texi
  GEN     qemu-img-cmds.texi
  GEN     qemu-monitor-info.texi
  GEN     qemu-img.1
  GEN     qemu-nbd.8
  GEN     qemu-ga.8
  GEN     qga/qapi-generated/qapi-gen
  GEN     docs/qemu-block-drivers.7
  GEN     fsdev/virtfs-proxy-helper.1
  CC      qapi/qapi-builtin-types.o
  CC      qapi/qapi-types.o
  CC      qapi/qapi-types-block-core.o
  CC      qapi/qapi-types-block.o
  CC      qapi/qapi-types-char.o
  CC      qapi/qapi-types-common.o
  CC      qapi/qapi-types-crypto.o
  CC      qapi/qapi-types-introspect.o
  CC      qapi/qapi-types-migration.o
  CC      qapi/qapi-types-misc.o
  CC      qapi/qapi-types-net.o
  CC      qapi/qapi-types-rocker.o
  CC      qapi/qapi-types-run-state.o
  CC      qapi/qapi-types-sockets.o
  CC      qapi/qapi-types-tpm.o
  CC      qapi/qapi-types-trace.o
  CC      qapi/qapi-types-transaction.o
  CC      qapi/qapi-types-ui.o
  CC      qapi/qapi-builtin-visit.o
  CC      qapi/qapi-visit.o
  CC      qapi/qapi-visit-block-core.o
  CC      qapi/qapi-visit-block.o
  CC      qapi/qapi-visit-char.o
  CC      qapi/qapi-visit-common.o
  CC      qapi/qapi-visit-crypto.o
  CC      qapi/qapi-visit-introspect.o
  CC      qapi/qapi-visit-migration.o
  CC      qapi/qapi-visit-misc.o
  CC      qapi/qapi-visit-net.o
  CC      qapi/qapi-visit-rocker.o
  CC      qapi/qapi-visit-run-state.o
  CC      qapi/qapi-visit-sockets.o
  CC      qapi/qapi-visit-tpm.o
  CC      qapi/qapi-visit-trace.o
  CC      qapi/qapi-visit-transaction.o
  CC      qapi/qapi-visit-ui.o
  CC      qapi/qapi-events.o
  CC      qapi/qapi-events-block-core.o
  CC      qapi/qapi-events-block.o
  CC      qapi/qapi-events-char.o
  CC      qapi/qapi-events-common.o
  CC      qapi/qapi-events-crypto.o
  CC      qapi/qapi-events-introspect.o
  CC      qapi/qapi-events-migration.o
  CC      qapi/qapi-events-misc.o
  CC      qapi/qapi-events-net.o
  CC      qapi/qapi-events-rocker.o
  CC      qapi/qapi-events-run-state.o
  CC      qapi/qapi-events-sockets.o
  CC      qapi/qapi-events-tpm.o
  CC      qapi/qapi-events-trace.o
  CC      qapi/qapi-events-transaction.o
  CC      qapi/qapi-events-ui.o
  CC      qapi/qapi-introspect.o
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qobject-input-visitor.o
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/string-input-visitor.o
  CC      qapi/string-output-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-event.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qobject/qnum.o
  CC      qobject/qstring.o
  CC      qobject/qdict.o
  CC      qobject/qlist.o
  CC      qobject/qbool.o
  CC      qobject/qlit.o
  CC      qobject/qjson.o
  CC      qobject/qobject.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      qobject/json-parser.o
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/lockcnt.o
  CC      util/aiocb.o
  CC      util/async.o
  CC      util/aio-wait.o
  CC      util/thread-pool.o
  CC      util/qemu-timer.o
  CC      util/main-loop.o
  CC      util/iohandler.o
  CC      util/aio-posix.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/mmap-alloc.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/qemu-thread-posix.o
  CC      util/memfd.o
  CC      util/envlist.o
  CC      util/path.o
  CC      util/module.o
  CC      util/host-utils.o
  CC      util/bitmap.o
  CC      util/bitops.o
  CC      util/hbitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/cacheinfo.o
  CC      util/error.o
  CC      util/qemu-error.o
  CC      util/id.o
  CC      util/iov.o
  CC      util/qemu-config.o
  CC      util/qemu-sockets.o
  CC      util/uri.o
  CC      util/notify.o
  CC      util/qemu-option.o
  CC      util/qemu-progress.o
  CC      util/keyval.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/uuid.o
  CC      util/throttle.o
  CC      util/getauxval.o
  CC      util/readline.o
  CC      util/rcu.o
  CC      util/qemu-coroutine.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/buffer.o
  CC      util/timed-average.o
  CC      util/base64.o
  CC      util/log.o
  CC      util/pagesize.o
  CC      util/qdist.o
  CC      util/qht.o
  CC      util/range.o
  CC      util/stats64.o
  CC      util/systemd.o
  CC      util/vfio-helpers.o
  CC      trace-root.o
  CC      util/trace.o
  CC      crypto/trace.o
  CC      io/trace.o
  CC      migration/trace.o
  CC      block/trace.o
  CC      chardev/trace.o
  CC      hw/block/trace.o
  CC      hw/block/dataplane/trace.o
  CC      hw/char/trace.o
  CC      hw/intc/trace.o
  CC      hw/net/trace.o
  CC      hw/rdma/trace.o
  CC      hw/rdma/vmw/trace.o
  CC      hw/virtio/trace.o
  CC      hw/audio/trace.o
  CC      hw/misc/trace.o
  CC      hw/misc/macio/trace.o
  CC      hw/usb/trace.o
  CC      hw/scsi/trace.o
  CC      hw/nvram/trace.o
  CC      hw/display/trace.o
  CC      hw/input/trace.o
  CC      hw/timer/trace.o
  CC      hw/dma/trace.o
  CC      hw/sparc/trace.o
  CC      hw/sparc64/trace.o
  CC      hw/sd/trace.o
  CC      hw/isa/trace.o
  CC      hw/mem/trace.o
  CC      hw/i386/trace.o
  CC      hw/i386/xen/trace.o
  CC      hw/9pfs/trace.o
  CC      hw/ppc/trace.o
  CC      hw/pci/trace.o
  CC      hw/pci-host/trace.o
  CC      hw/s390x/trace.o
  CC      hw/vfio/trace.o
  CC      hw/acpi/trace.o
  CC      hw/arm/trace.o
  CC      hw/alpha/trace.o
  CC      hw/hppa/trace.o
  CC      hw/xen/trace.o
  CC      hw/ide/trace.o
  CC      hw/tpm/trace.o
  CC      ui/trace.o
  CC      audio/trace.o
  CC      net/trace.o
  CC      target/arm/trace.o
  CC      target/i386/trace.o
  CC      target/mips/trace.o
  CC      target/sparc/trace.o
  CC      target/s390x/trace.o
  CC      target/ppc/trace.o
  CC      qom/trace.o
  CC      linux-user/trace.o
  CC      qapi/trace.o
  CC      accel/tcg/trace.o
  CC      accel/kvm/trace.o
  CC      nbd/trace.o
  CC      scsi/trace.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/error-printf.o
  CC      stubs/fdset.o
  CC      stubs/gdbstub.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/linux-aio.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/change-state-handler.o
  CC      stubs/monitor.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/tpm.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vm-stop.o
  CC      stubs/vmstate.o
  CC      stubs/qmp_pc_dimm.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/vmgenid.o
  CC      stubs/xen-common.o
  CC      stubs/xen-hvm.o
  CC      stubs/pci-host-piix.o
  CC      stubs/ram-block.o
  CC      qemu-keymap.o
  CC      ui/input-keymap.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      block.o
  CC      blockjob.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw-format.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/vmdk.o
  CC      block/cloop.o
  CC      block/bochs.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/dmg.o
  CC      block/qcow2.o
  CC      block/qcow2-refcount.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qcow2-bitmap.o
  CC      block/qed.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/qed-check.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.o
  CC      block/quorum.o
  CC      block/parallels.o
  CC      block/blkdebug.o
  CC      block/blkverify.o
  CC      block/blkreplay.o
  CC      block/block-backend.o
  CC      block/snapshot.o
  CC      block/qapi.o
  CC      block/file-posix.o
  CC      block/linux-aio.o
  CC      block/null.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/create.o
  CC      block/throttle-groups.o
  CC      block/nvme.o
  CC      block/nbd.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/iscsi-opts.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/write-threshold.o
  CC      block/backup.o
  CC      block/replication.o
  CC      block/throttle.o
  CC      block/crypto.o
  CC      nbd/server.o
  CC      nbd/client.o
  CC      nbd/common.o
  CC      scsi/utils.o
  CC      scsi/pr-manager.o
  CC      scsi/pr-manager-helper.o
  CC      block/iscsi.o
  CC      block/nfs.o
  CC      block/curl.o
  CC      block/rbd.o
  CC      block/gluster.o
  CC      block/ssh.o
  CC      block/dmg-bz2.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-nettle.o
  CC      crypto/hmac.o
  CC      crypto/hmac-nettle.o
  CC      crypto/aes.o
  CC      crypto/desrfb.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-gnutls.o
  CC      crypto/pbkdf.o
  CC      crypto/pbkdf-nettle.o
  CC      crypto/ivgen.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-qcow.o
  CC      crypto/block-luks.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-file.o
  CC      io/channel-socket.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/dns-resolver.o
  CC      io/net-listener.o
  CC      io/task.o
  CC      qom/object.o
  CC      qom/container.o
  CC      qom/qom-qobject.o
  CC      qom/object_interfaces.o
  GEN     qemu-img-cmds.h
  CC      qemu-io.o
  CC      fsdev/virtfs-proxy-helper.o
  CC      fsdev/9p-marshal.o
  CC      fsdev/9p-iov-marshal.o
  CC      scsi/qemu-pr-helper.o
  CC      qemu-bridge-helper.o
  CC      blockdev.o
  CC      bootdevice.o
  CC      blockdev-nbd.o
  CC      iothread.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      os-posix.o
  CC      bt-host.o
  CC      bt-vhci.o
  CC      dma-helpers.o
  CC      vl.o
  CC      tpm.o
  CC      qemu-seccomp.o
  CC      device_tree.o
  CC      qapi/qapi-commands.o
  CC      qapi/qapi-commands-block-core.o
  CC      qapi/qapi-commands-block.o
  CC      qapi/qapi-commands-char.o
  CC      qapi/qapi-commands-common.o
  CC      qapi/qapi-commands-crypto.o
  CC      qapi/qapi-commands-introspect.o
  CC      qapi/qapi-commands-migration.o
  CC      qapi/qapi-commands-misc.o
  CC      qapi/qapi-commands-net.o
  CC      qapi/qapi-commands-rocker.o
  CC      qapi/qapi-commands-run-state.o
  CC      qapi/qapi-commands-sockets.o
  CC      qapi/qapi-commands-tpm.o
  CC      qapi/qapi-commands-trace.o
  CC      qapi/qapi-commands-transaction.o
  CC      qapi/qapi-commands-ui.o
  CC      qmp.o
  CC      hmp.o
  CC      cpus-common.o
  CC      audio/audio.o
  CC      audio/noaudio.o
  CC      audio/wavaudio.o
  CC      audio/mixeng.o
  CC      audio/wavcapture.o
  CC      backends/rng.o
  CC      backends/rng-egd.o
  CC      backends/rng-random.o
  CC      backends/tpm.o
  CC      backends/hostmem.o
  CC      backends/hostmem-ram.o
  CC      backends/hostmem-file.o
  CC      backends/cryptodev.o
  CC      backends/cryptodev-builtin.o
  CC      backends/cryptodev-vhost.o
  CC      backends/cryptodev-vhost-user.o
  CC      backends/hostmem-memfd.o
  CC      block/stream.o
  CC      chardev/msmouse.o
  CC      chardev/wctablet.o
  CC      chardev/testdev.o
  CC      chardev/baum.o
  CC      disas/alpha.o
  CC      disas/arm.o
  CXX     disas/arm-a64.o
  CC      disas/cris.o
  CC      disas/hppa.o
  CC      disas/i386.o
  CC      disas/m68k.o
  CC      disas/microblaze.o
  CC      disas/mips.o
  CC      disas/nios2.o
  CC      disas/moxie.o
  CC      disas/ppc.o
  CC      disas/riscv.o
  CC      disas/s390.o
  CC      disas/sh4.o
  CC      disas/sparc.o
  CC      disas/lm32.o
  CC      disas/xtensa.o
  CXX     disas/libvixl/vixl/utils.o
  CXX     disas/libvixl/vixl/compiler-intrinsics.o
  CXX     disas/libvixl/vixl/a64/instructions-a64.o
  CXX     disas/libvixl/vixl/a64/decoder-a64.o
  CXX     disas/libvixl/vixl/a64/disasm-a64.o
  CC      fsdev/qemu-fsdev.o
  CC      fsdev/qemu-fsdev-opts.o
  CC      fsdev/qemu-fsdev-throttle.o
  CC      fsdev/qemu-fsdev-dummy.o
  CC      hw/9pfs/9p.o
  CC      hw/9pfs/9p-util.o
  CC      hw/9pfs/9p-local.o
  CC      hw/9pfs/9p-xattr.o
  CC      hw/9pfs/9p-xattr-user.o
  CC      hw/9pfs/9p-posix-acl.o
  CC      hw/9pfs/coth.o
  CC      hw/9pfs/cofs.o
  CC      hw/9pfs/codir.o
  CC      hw/9pfs/cofile.o
  CC      hw/9pfs/coxattr.o
  CC      hw/9pfs/9p-synth.o
  CC      hw/9pfs/9p-handle.o
  CC      hw/9pfs/9p-proxy.o
  CC      hw/acpi/core.o
  CC      hw/acpi/piix4.o
  CC      hw/acpi/pcihp.o
  CC      hw/acpi/ich9.o
  CC      hw/acpi/tco.o
  CC      hw/acpi/cpu_hotplug.o
  CC      hw/acpi/memory_hotplug.o
  CC      hw/acpi/cpu.o
  CC      hw/acpi/nvdimm.o
  CC      hw/acpi/vmgenid.o
  CC      hw/acpi/acpi_interface.o
  CC      hw/acpi/bios-linker-loader.o
  CC      hw/acpi/aml-build.o
  CC      hw/acpi/ipmi.o
  CC      hw/acpi/acpi-stub.o
  CC      hw/acpi/ipmi-stub.o
  CC      hw/audio/sb16.o
  CC      hw/audio/es1370.o
  CC      hw/audio/ac97.o
  CC      hw/audio/fmopl.o
  CC      hw/audio/adlib.o
  CC      hw/audio/gus.o
  CC      hw/audio/gusemu_hal.o
  CC      hw/audio/gusemu_mixer.o
  CC      hw/audio/cs4231a.o
  CC      hw/audio/intel-hda.o
  CC      hw/audio/hda-codec.o
  CC      hw/audio/pcspk.o
  CC      hw/audio/wm8750.o
  CC      hw/audio/pl041.o
  CC      hw/audio/lm4549.o
  CC      hw/audio/cs4231.o
  CC      hw/audio/marvell_88w8618.o
  CC      hw/audio/milkymist-ac97.o
  CC      hw/audio/soundhw.o
  CC      hw/block/block.o
  CC      hw/block/cdrom.o
  CC      hw/block/hd-geometry.o
  CC      hw/block/fdc.o
  CC      hw/block/m25p80.o
  CC      hw/block/nand.o
  CC      hw/block/pflash_cfi01.o
  CC      hw/block/pflash_cfi02.o
  CC      hw/block/ecc.o
  CC      hw/block/onenand.o
  CC      hw/block/nvme.o
  CC      hw/bt/core.o
  CC      hw/bt/l2cap.o
  CC      hw/bt/sdp.o
  CC      hw/bt/hci.o
  CC      hw/bt/hid.o
  CC      hw/bt/hci-csr.o
  CC      hw/char/ipoctal232.o
  CC      hw/char/escc.o
  CC      hw/char/parallel.o
  CC      hw/char/parallel-isa.o
  CC      hw/char/pl011.o
  CC      hw/char/serial.o
  CC      hw/char/serial-isa.o
  CC      hw/char/serial-pci.o
  CC      hw/char/virtio-console.o
  CC      hw/char/xilinx_uartlite.o
  CC      hw/char/cadence_uart.o
  CC      hw/char/cmsdk-apb-uart.o
  CC      hw/char/etraxfs_ser.o
  CC      hw/char/debugcon.o
  CC      hw/char/grlib_apbuart.o
  CC      hw/char/imx_serial.o
  CC      hw/char/lm32_juart.o
  CC      hw/char/lm32_uart.o
  CC      hw/char/milkymist-uart.o
  CC      hw/char/sclpconsole.o
  CC      hw/char/sclpconsole-lm.o
  CC      hw/core/qdev.o
  CC      hw/core/qdev-properties.o
  CC      hw/core/bus.o
  CC      hw/core/reset.o
  CC      hw/core/qdev-fw.o
  CC      hw/core/fw-path-provider.o
  CC      hw/core/irq.o
  CC      hw/core/hotplug.o
  CC      hw/core/nmi.o
  CC      hw/core/empty_slot.o
  CC      hw/core/stream.o
  CC      hw/core/ptimer.o
  CC      hw/core/sysbus.o
  CC      hw/core/machine.o
  CC      hw/core/loader.o
  CC      hw/core/loader-fit.o
  CC      hw/core/qdev-properties-system.o
  CC      hw/core/register.o
  CC      hw/core/or-irq.o
  CC      hw/core/split-irq.o
  CC      hw/core/platform-bus.o
  CC      hw/cpu/core.o
  CC      hw/display/ads7846.o
  CC      hw/display/cirrus_vga.o
  CC      hw/display/g364fb.o
  CC      hw/display/jazz_led.o
  CC      hw/display/pl110.o
  CC      hw/display/sii9022.o
  CC      hw/display/ssd0303.o
  CC      hw/display/ssd0323.o
  CC      hw/display/vga-pci.o
  CC      hw/display/vga-isa.o
  CC      hw/display/vga-isa-mm.o
  CC      hw/display/vmware_vga.o
  CC      hw/display/blizzard.o
  CC      hw/display/exynos4210_fimd.o
  CC      hw/display/framebuffer.o
  CC      hw/display/milkymist-vgafb.o
  CC      hw/display/tc6393xb.o
  CC      hw/display/milkymist-tmu2.o
  CC      hw/dma/puv3_dma.o
  CC      hw/dma/rc4030.o
  CC      hw/dma/pl080.o
  CC      hw/dma/pl330.o
  CC      hw/dma/i82374.o
  CC      hw/dma/i8257.o
  CC      hw/dma/xilinx_axidma.o
  CC      hw/dma/xlnx-zynq-devcfg.o
  CC      hw/dma/etraxfs_dma.o
  CC      hw/dma/sparc32_dma.o
  CC      hw/gpio/max7310.o
  CC      hw/gpio/pl061.o
  CC      hw/gpio/puv3_gpio.o
  CC      hw/gpio/zaurus.o
  CC      hw/gpio/mpc8xxx.o
  CC      hw/gpio/gpio_key.o
  CC      hw/i2c/core.o
  CC      hw/i2c/smbus.o
  CC      hw/i2c/smbus_eeprom.o
  CC      hw/i2c/i2c-ddc.o
  CC      hw/i2c/versatile_i2c.o
  CC      hw/i2c/smbus_ich9.o
  CC      hw/i2c/pm_smbus.o
  CC      hw/i2c/bitbang_i2c.o
  CC      hw/i2c/exynos4210_i2c.o
  CC      hw/i2c/imx_i2c.o
  CC      hw/i2c/aspeed_i2c.o
  CC      hw/ide/core.o
  CC      hw/ide/atapi.o
  CC      hw/ide/qdev.o
  CC      hw/ide/pci.o
  CC      hw/ide/isa.o
  CC      hw/ide/piix.o
  CC      hw/ide/cmd646.o
  CC      hw/ide/macio.o
  CC      hw/ide/mmio.o
  CC      hw/ide/via.o
  CC      hw/ide/microdrive.o
  CC      hw/ide/ahci.o
  CC      hw/ide/ich.o
  CC      hw/ide/ahci-allwinner.o
  CC      hw/ide/sii3112.o
  CC      hw/input/adb.o
  CC      hw/input/adb-mouse.o
  CC      hw/input/adb-kbd.o
  CC      hw/input/hid.o
  CC      hw/input/lm832x.o
  CC      hw/input/pckbd.o
  CC      hw/input/pl050.o
  CC      hw/input/ps2.o
  CC      hw/input/stellaris_input.o
  CC      hw/input/tsc2005.o
  CC      hw/input/virtio-input.o
  CC      hw/input/virtio-input-hid.o
  CC      hw/input/virtio-input-host.o
  CC      hw/intc/heathrow_pic.o
  CC      hw/intc/i8259_common.o
  CC      hw/intc/i8259.o
  CC      hw/intc/pl190.o
  CC      hw/intc/puv3_intc.o
  CC      hw/intc/xilinx_intc.o
  CC      hw/intc/xlnx-pmu-iomod-intc.o
  CC      hw/intc/xlnx-zynqmp-ipi.o
  CC      hw/intc/etraxfs_pic.o
  CC      hw/intc/imx_avic.o
  CC      hw/intc/imx_gpcv2.o
  CC      hw/intc/lm32_pic.o
  CC      hw/intc/realview_gic.o
  CC      hw/intc/slavio_intctl.o
  CC      hw/intc/ioapic_common.o
  CC      hw/intc/arm_gic_common.o
  CC      hw/intc/arm_gic.o
  CC      hw/intc/arm_gicv2m.o
  CC      hw/intc/arm_gicv3_common.o
  CC      hw/intc/arm_gicv3.o
  CC      hw/intc/arm_gicv3_dist.o
  CC      hw/intc/arm_gicv3_redist.o
  CC      hw/intc/arm_gicv3_its_common.o
  CC      hw/intc/openpic.o
  CC      hw/intc/intc.o
  CC      hw/ipack/ipack.o
  CC      hw/ipack/tpci200.o
  CC      hw/ipmi/ipmi.o
  CC      hw/ipmi/ipmi_bmc_sim.o
  CC      hw/ipmi/ipmi_bmc_extern.o
  CC      hw/ipmi/isa_ipmi_kcs.o
  CC      hw/ipmi/isa_ipmi_bt.o
  CC      hw/isa/isa-bus.o
  CC      hw/isa/isa-superio.o
  CC      hw/isa/smc37c669-superio.o
  CC      hw/isa/apm.o
  CC      hw/isa/i82378.o
  CC      hw/isa/pc87312.o
  CC      hw/isa/piix4.o
  CC      hw/isa/vt82c686.o
  CC      hw/mem/pc-dimm.o
  CC      hw/mem/nvdimm.o
  CC      hw/misc/applesmc.o
  CC      hw/misc/max111x.o
  CC      hw/misc/tmp105.o
  CC      hw/misc/tmp421.o
  CC      hw/misc/debugexit.o
  CC      hw/misc/sga.o
  CC      hw/misc/pc-testdev.o
  CC      hw/misc/pci-testdev.o
  CC      hw/misc/edu.o
  CC      hw/misc/unimp.o
  CC      hw/misc/vmcoreinfo.o
  CC      hw/misc/arm_l2x0.o
  CC      hw/misc/arm_integrator_debug.o
  CC      hw/misc/a9scu.o
  CC      hw/misc/arm11scu.o
  CC      hw/misc/mos6522.o
  CC      hw/misc/puv3_pm.o
  CC      hw/misc/macio/macio.o
  CC      hw/misc/macio/cuda.o
  CC      hw/misc/macio/mac_dbdma.o
  CC      hw/net/dp8393x.o
  CC      hw/net/ne2000.o
  CC      hw/net/eepro100.o
  CC      hw/net/pcnet-pci.o
  CC      hw/net/pcnet.o
  CC      hw/net/e1000.o
  CC      hw/net/e1000x_common.o
  CC      hw/net/net_tx_pkt.o
  CC      hw/net/net_rx_pkt.o
  CC      hw/net/e1000e.o
  CC      hw/net/e1000e_core.o
  CC      hw/net/rtl8139.o
  CC      hw/net/vmxnet3.o
  CC      hw/net/smc91c111.o
  CC      hw/net/lan9118.o
  CC      hw/net/ne2000-isa.o
  CC      hw/net/opencores_eth.o
  CC      hw/net/xgmac.o
  CC      hw/net/mipsnet.o
  CC      hw/net/xilinx_axienet.o
  CC      hw/net/allwinner_emac.o
  CC      hw/net/imx_fec.o
  CC      hw/net/cadence_gem.o
  CC      hw/net/stellaris_enet.o
  CC      hw/net/lance.o
  CC      hw/net/sunhme.o
  CC      hw/net/ftgmac100.o
  CC      hw/net/sungem.o
  CC      hw/net/rocker/rocker.o
  CC      hw/net/rocker/rocker_fp.o
  CC      hw/net/rocker/rocker_desc.o
  CC      hw/net/rocker/rocker_world.o
  CC      hw/net/rocker/rocker_of_dpa.o
  CC      hw/net/can/can_sja1000.o
  CC      hw/net/can/can_kvaser_pci.o
  CC      hw/net/can/can_pcm3680_pci.o
  CC      hw/net/can/can_mioe3680_pci.o
  CC      hw/nvram/ds1225y.o
  CC      hw/nvram/eeprom93xx.o
  CC      hw/nvram/eeprom_at24c.o
  CC      hw/nvram/fw_cfg.o
  CC      hw/nvram/chrp_nvram.o
  CC      hw/nvram/mac_nvram.o
  CC      hw/pci-bridge/pci_bridge_dev.o
  CC      hw/pci-bridge/pcie_root_port.o
  CC      hw/pci-bridge/gen_pcie_root_port.o
  CC      hw/pci-bridge/pcie_pci_bridge.o
  CC      hw/pci-bridge/pci_expander_bridge.o
  CC      hw/pci-bridge/xio3130_upstream.o
  CC      hw/pci-bridge/xio3130_downstream.o
  CC      hw/pci-bridge/ioh3420.o
  CC      hw/pci-bridge/i82801b11.o
  CC      hw/pci-bridge/dec.o
  CC      hw/pci-bridge/simba.o
  CC      hw/pci-host/pam.o
  CC      hw/pci-host/prep.o
  CC      hw/pci-host/grackle.o
  CC      hw/pci-host/uninorth.o
  CC      hw/pci-host/ppce500.o
  CC      hw/pci-host/versatile.o
  CC      hw/pci-host/sabre.o
  CC      hw/pci-host/bonito.o
  CC      hw/pci-host/piix.o
  CC      hw/pci-host/q35.o
  CC      hw/pci-host/gpex.o
  CC      hw/pci-host/xilinx-pcie.o
  CC      hw/pci-host/designware.o
  CC      hw/pci/pci.o
  CC      hw/pci/pci_bridge.o
  CC      hw/pci/msix.o
  CC      hw/pci/msi.o
  CC      hw/pci/shpc.o
  CC      hw/pci/slotid_cap.o
  CC      hw/pci/pci_host.o
  CC      hw/pci/pcie_host.o
  CC      hw/pci/pcie.o
  CC      hw/pci/pcie_aer.o
  CC      hw/pci/pcie_port.o
  CC      hw/pci/pci-stub.o
  CC      hw/pcmcia/pcmcia.o
  CC      hw/scsi/scsi-disk.o
  CC      hw/scsi/scsi-generic.o
  CC      hw/scsi/scsi-bus.o
  CC      hw/scsi/lsi53c895a.o
  CC      hw/scsi/mptsas.o
  CC      hw/scsi/mptconfig.o
  CC      hw/scsi/mptendian.o
  CC      hw/scsi/megasas.o
  CC      hw/scsi/vmw_pvscsi.o
  CC      hw/scsi/esp.o
  CC      hw/scsi/esp-pci.o
  CC      hw/sd/pl181.o
  CC      hw/sd/ssi-sd.o
  CC      hw/sd/sd.o
  CC      hw/sd/core.o
  CC      hw/sd/sdmmc-internal.o
  CC      hw/sd/sdhci.o
  CC      hw/smbios/smbios.o
  CC      hw/smbios/smbios_type_38.o
  CC      hw/smbios/smbios-stub.o
  CC      hw/smbios/smbios_type_38-stub.o
  CC      hw/ssi/pl022.o
  CC      hw/ssi/ssi.o
  CC      hw/ssi/xilinx_spi.o
  CC      hw/ssi/xilinx_spips.o
  CC      hw/ssi/aspeed_smc.o
  CC      hw/ssi/stm32f2xx_spi.o
  CC      hw/ssi/mss-spi.o
  CC      hw/timer/arm_timer.o
  CC      hw/timer/arm_mptimer.o
  CC      hw/timer/armv7m_systick.o
  CC      hw/timer/a9gtimer.o
  CC      hw/timer/cadence_ttc.o
  CC      hw/timer/ds1338.o
  CC      hw/timer/hpet.o
  CC      hw/timer/i8254_common.o
  CC      hw/timer/i8254.o
  CC      hw/timer/m48t59.o
  CC      hw/timer/m48t59-isa.o
  CC      hw/timer/pl031.o
  CC      hw/timer/puv3_ost.o
  CC      hw/timer/twl92230.o
  CC      hw/timer/xilinx_timer.o
  CC      hw/timer/slavio_timer.o
  CC      hw/timer/etraxfs_timer.o
  CC      hw/timer/grlib_gptimer.o
  CC      hw/timer/imx_epit.o
  CC      hw/timer/imx_gpt.o
  CC      hw/timer/lm32_timer.o
  CC      hw/timer/milkymist-sysctl.o
  CC      hw/timer/xlnx-zynqmp-rtc.o
  CC      hw/timer/stm32f2xx_timer.o
  CC      hw/timer/aspeed_timer.o
  CC      hw/timer/sun4v-rtc.o
  CC      hw/timer/cmsdk-apb-timer.o
  CC      hw/timer/mss-timer.o
  CC      hw/tpm/tpm_util.o
  CC      hw/tpm/tpm_tis.o
  CC      hw/tpm/tpm_crb.o
  CC      hw/tpm/tpm_emulator.o
  CC      hw/usb/core.o
  CC      hw/usb/combined-packet.o
  CC      hw/usb/bus.o
  CC      hw/usb/libhw.o
  CC      hw/usb/desc.o
  CC      hw/usb/desc-msos.o
  CC      hw/usb/hcd-uhci.o
  CC      hw/usb/hcd-ohci.o
  CC      hw/usb/hcd-ehci.o
  CC      hw/usb/hcd-ehci-pci.o
  CC      hw/usb/hcd-ehci-sysbus.o
  CC      hw/usb/hcd-xhci.o
  CC      hw/usb/hcd-xhci-nec.o
  CC      hw/usb/hcd-musb.o
  CC      hw/usb/dev-hub.o
  CC      hw/usb/dev-hid.o
  CC      hw/usb/dev-wacom.o
  CC      hw/usb/dev-storage.o
  CC      hw/usb/dev-uas.o
  CC      hw/usb/dev-audio.o
  CC      hw/usb/dev-serial.o
  CC      hw/usb/dev-network.o
  CC      hw/usb/dev-bluetooth.o
  CC      hw/usb/dev-smartcard-reader.o
  CC      hw/usb/ccid-card-passthru.o
  CC      hw/usb/ccid-card-emulated.o
  CC      hw/usb/dev-mtp.o
  CC      hw/usb/redirect.o
  CC      hw/usb/quirks.o
  CC      hw/usb/host-libusb.o
  CC      hw/usb/host-stub.o
  CC      hw/virtio/virtio-rng.o
  CC      hw/virtio/virtio-pci.o
  CC      hw/virtio/virtio-bus.o
  CC      hw/virtio/virtio-mmio.o
  CC      hw/virtio/vhost-stub.o
  CC      hw/watchdog/watchdog.o
  CC      hw/watchdog/wdt_i6300esb.o
  CC      hw/watchdog/wdt_ib700.o
  CC      hw/watchdog/wdt_diag288.o
  CC      hw/watchdog/wdt_aspeed.o
  CC      migration/migration.o
  CC      migration/socket.o
  CC      migration/fd.o
  CC      migration/exec.o
  CC      migration/tls.o
  CC      migration/channel.o
  CC      migration/savevm.o
  CC      migration/colo-comm.o
  CC      migration/colo.o
  CC      migration/colo-failover.o
  CC      migration/vmstate.o
  CC      migration/vmstate-types.o
  CC      migration/page_cache.o
  CC      migration/qemu-file.o
  CC      migration/global_state.o
  CC      migration/qemu-file-channel.o
  CC      migration/xbzrle.o
  CC      migration/postcopy-ram.o
  CC      migration/qjson.o
  CC      migration/block-dirty-bitmap.o
  CC      migration/block.o
  CC      net/net.o
  CC      net/queue.o
  CC      net/checksum.o
  CC      net/util.o
  CC      net/hub.o
  CC      net/socket.o
  CC      net/dump.o
  CC      net/eth.o
  CC      net/l2tpv3.o
  CC      net/vhost-user.o
  CC      net/slirp.o
  CC      net/filter.o
  CC      net/filter-buffer.o
  CC      net/filter-mirror.o
  CC      net/colo-compare.o
  CC      net/colo.o
  CC      net/filter-rewriter.o
  CC      net/filter-replay.o
  CC      net/tap.o
  CC      net/tap-linux.o
  CC      net/can/can_core.o
  CC      net/can/can_host.o
  CC      net/can/can_socketcan.o
  CC      qom/cpu.o
  CC      replay/replay.o
  CC      replay/replay-internal.o
  CC      replay/replay-events.o
  CC      replay/replay-time.o
  CC      replay/replay-input.o
  CC      replay/replay-char.o
  CC      replay/replay-snapshot.o
  CC      replay/replay-net.o
  CC      replay/replay-audio.o
  CC      slirp/cksum.o
  CC      slirp/if.o
  CC      slirp/ip_icmp.o
  CC      slirp/ip6_icmp.o
  CC      slirp/ip6_input.o
  CC      slirp/ip6_output.o
  CC      slirp/ip_input.o
  CC      slirp/ip_output.o
  CC      slirp/dnssearch.o
  CC      slirp/dhcpv6.o
  CC      slirp/slirp.o
  CC      slirp/mbuf.o
  CC      slirp/misc.o
  CC      slirp/sbuf.o
  CC      slirp/socket.o
  CC      slirp/tcp_input.o
  CC      slirp/tcp_output.o
  CC      slirp/tcp_subr.o
  CC      slirp/tcp_timer.o
  CC      slirp/udp.o
  CC      slirp/udp6.o
  CC      slirp/bootp.o
  CC      slirp/tftp.o
  CC      slirp/arp_table.o
  CC      slirp/ndp_table.o
  CC      slirp/ncsi.o
  CC      ui/keymaps.o
  CC      ui/console.o
  CC      ui/cursor.o
  CC      ui/qemu-pixman.o
  CC      ui/input.o
  CC      ui/input-legacy.o
  CC      ui/input-linux.o
  CC      ui/vnc.o
  CC      ui/vnc-enc-zlib.o
  CC      ui/vnc-enc-hextile.o
  CC      ui/vnc-enc-tight.o
  CC      ui/vnc-palette.o
  CC      ui/vnc-enc-zrle.o
  CC      ui/vnc-auth-vencrypt.o
  CC      ui/vnc-auth-sasl.o
  CC      ui/vnc-ws.o
  CC      ui/vnc-jobs.o
  CC      ui/x_keymap.o
  VERT    ui/shader/texture-blit-vert.h
  VERT    ui/shader/texture-blit-flip-vert.h
  CC      ui/console-gl.o
  FRAG    ui/shader/texture-blit-frag.h
  CC      ui/egl-helpers.o
  CC      ui/egl-context.o
  CC      ui/egl-headless.o
  CC      audio/ossaudio.o
  CC      ui/sdl2.o
  CC      ui/sdl2-input.o
  CC      ui/sdl2-2d.o
  CC      ui/sdl2-gl.o
  CC      ui/gtk.o
  CC      ui/gtk-egl.o
  CC      ui/gtk-gl-area.o
  CC      ui/curses.o
  CC      chardev/char.o
  CC      chardev/char-fd.o
  CC      chardev/char-fe.o
  CC      chardev/char-file.o
  CC      chardev/char-io.o
  CC      chardev/char-mux.o
  CC      chardev/char-null.o
  CC      chardev/char-parallel.o
  CC      chardev/char-pipe.o
  CC      chardev/char-pty.o
  CC      chardev/char-ringbuf.o
  CC      chardev/char-serial.o
  CC      chardev/char-socket.o
  CC      chardev/char-stdio.o
  CC      chardev/char-udp.o
  CCAS    s390-ccw/start.o
  CC      s390-ccw/main.o
  CC      s390-ccw/bootmap.o
  CC      s390-ccw/sclp.o
  CC      s390-ccw/virtio.o
  CC      s390-ccw/virtio-scsi.o
  LINK    tests/qemu-iotests/socket_scm_helper
  GEN     qemu-doc.html
  GEN     qemu-doc.txt
  CC      s390-ccw/virtio-blkdev.o
  GEN     qemu.1
  GEN     docs/interop/qemu-qmp-ref.html
  GEN     docs/interop/qemu-qmp-ref.txt
  CC      s390-ccw/libc.o
  CC      s390-ccw/menu.o
s390-netboot.img not built since roms/SLOF/ is not available.
  GEN     docs/interop/qemu-qmp-ref.7
  BUILD   s390-ccw/s390-ccw.elf
  STRIP   s390-ccw/s390-ccw.img
  CC      qga/commands.o
  CC      qga/guest-agent-command-state.o
  CC      qga/main.o
  CC      qga/commands-posix.o
  CC      qga/channel-posix.o
  CC      qga/qapi-generated/qga-qapi-types.o
  CC      qga/qapi-generated/qga-qapi-visit.o
  CC      qga/qapi-generated/qga-qapi-commands.o
  AR      libqemuutil.a
  CC      qemu-img.o
  CC      ui/shader.o
  GEN     docs/interop/qemu-ga-ref.html
  GEN     docs/interop/qemu-ga-ref.txt
  GEN     docs/interop/qemu-ga-ref.7
  LINK    qemu-ga
  LINK    qemu-keymap
  LINK    ivshmem-client
  LINK    ivshmem-server
  LINK    qemu-nbd
  LINK    qemu-io
  LINK    fsdev/virtfs-proxy-helper
  LINK    scsi/qemu-pr-helper
  LINK    qemu-bridge-helper
  GEN     cris-softmmu/hmp-commands.h
  GEN     alpha-softmmu/hmp-commands.h
  GEN     aarch64-softmmu/hmp-commands.h
  GEN     cris-softmmu/hmp-commands-info.h
  GEN     cris-softmmu/config-target.h
  GEN     alpha-softmmu/hmp-commands-info.h
  GEN     alpha-softmmu/config-target.h
  CC      cris-softmmu/exec.o
  GEN     aarch64-softmmu/hmp-commands-info.h
  GEN     aarch64-softmmu/config-target.h
  CC      aarch64-softmmu/exec.o
  GEN     arm-softmmu/hmp-commands.h
  GEN     arm-softmmu/hmp-commands-info.h
  GEN     arm-softmmu/config-target.h
  CC      alpha-softmmu/exec.o
  CC      arm-softmmu/exec.o
  CC      cris-softmmu/tcg/tcg.o
  CC      alpha-softmmu/tcg/tcg.o
  CC      arm-softmmu/tcg/tcg.o
  CC      aarch64-softmmu/tcg/tcg.o
  CC      alpha-softmmu/tcg/tcg-op.o
  CC      cris-softmmu/tcg/tcg-op.o
  CC      aarch64-softmmu/tcg/tcg-op.o
  CC      arm-softmmu/tcg/tcg-op.o
  CC      alpha-softmmu/tcg/tcg-op-vec.o
  CC      cris-softmmu/tcg/tcg-op-vec.o
  CC      alpha-softmmu/tcg/tcg-op-gvec.o
  CC      arm-softmmu/tcg/tcg-op-vec.o
  CC      cris-softmmu/tcg/tcg-op-gvec.o
  CC      aarch64-softmmu/tcg/tcg-op-vec.o
  CC      aarch64-softmmu/tcg/tcg-op-gvec.o
  CC      arm-softmmu/tcg/tcg-op-gvec.o
  CC      cris-softmmu/tcg/tcg-common.o
  CC      alpha-softmmu/tcg/tcg-common.o
  CC      cris-softmmu/tcg/optimize.o
  CC      alpha-softmmu/tcg/optimize.o
  CC      cris-softmmu/fpu/softfloat.o
  CC      arm-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/tcg/optimize.o
  CC      arm-softmmu/tcg/optimize.o
  CC      alpha-softmmu/fpu/softfloat.o
  CC      aarch64-softmmu/fpu/softfloat.o
  CC      arm-softmmu/fpu/softfloat.o
  CC      cris-softmmu/fpu/hostfloat.o
  CC      cris-softmmu/disas.o
  CC      alpha-softmmu/fpu/hostfloat.o
  CC      aarch64-softmmu/fpu/hostfloat.o
  CC      arm-softmmu/fpu/hostfloat.o
  CC      alpha-softmmu/disas.o
  CC      aarch64-softmmu/disas.o
  CC      cris-softmmu/arch_init.o
  CC      arm-softmmu/disas.o
  CC      cris-softmmu/cpus.o
  CC      alpha-softmmu/arch_init.o
  GEN     aarch64-softmmu/gdbstub-xml.c
  GEN     arm-softmmu/gdbstub-xml.c
  CC      alpha-softmmu/cpus.o
  CC      arm-softmmu/arch_init.o
  CC      cris-softmmu/monitor.o
  CC      aarch64-softmmu/arch_init.o
  CC      arm-softmmu/cpus.o
  CC      aarch64-softmmu/cpus.o
  CC      alpha-softmmu/monitor.o
  CC      aarch64-softmmu/monitor.o
  CC      arm-softmmu/monitor.o
  CC      cris-softmmu/gdbstub.o
  CC      alpha-softmmu/gdbstub.o
  CC      aarch64-softmmu/gdbstub.o
  CC      cris-softmmu/balloon.o
  CC      arm-softmmu/gdbstub.o
  CC      cris-softmmu/ioport.o
  CC      alpha-softmmu/balloon.o
  CC      arm-softmmu/balloon.o
  CC      alpha-softmmu/ioport.o
  CC      aarch64-softmmu/balloon.o
  CC      cris-softmmu/numa.o
  CC      arm-softmmu/ioport.o
  CC      alpha-softmmu/numa.o
  CC      aarch64-softmmu/ioport.o
  CC      arm-softmmu/numa.o
  CC      cris-softmmu/qtest.o
  CC      alpha-softmmu/qtest.o
  CC      aarch64-softmmu/numa.o
  CC      arm-softmmu/qtest.o
  CC      cris-softmmu/memory.o
  CC      alpha-softmmu/memory.o
  CC      aarch64-softmmu/qtest.o
  CC      arm-softmmu/memory.o
  CC      aarch64-softmmu/memory.o
  CC      cris-softmmu/memory_mapping.o
  CC      alpha-softmmu/memory_mapping.o
  CC      arm-softmmu/memory_mapping.o
  CC      cris-softmmu/dump.o
  CC      alpha-softmmu/dump.o
  CC      arm-softmmu/dump.o
  CC      aarch64-softmmu/memory_mapping.o
  CC      cris-softmmu/migration/ram.o
  CC      alpha-softmmu/migration/ram.o
  CC      arm-softmmu/migration/ram.o
  CC      aarch64-softmmu/dump.o
  CC      cris-softmmu/accel/accel.o
  CC      alpha-softmmu/accel/accel.o
  CC      cris-softmmu/accel/stubs/hax-stub.o
  CC      aarch64-softmmu/migration/ram.o
  CC      alpha-softmmu/accel/stubs/hax-stub.o
  CC      cris-softmmu/accel/stubs/hvf-stub.o
  CC      alpha-softmmu/accel/stubs/hvf-stub.o
  CC      arm-softmmu/accel/accel.o
  CC      cris-softmmu/accel/stubs/whpx-stub.o
  CC      arm-softmmu/accel/stubs/hax-stub.o
  CC      alpha-softmmu/accel/stubs/whpx-stub.o
  CC      arm-softmmu/accel/stubs/hvf-stub.o
  CC      cris-softmmu/accel/stubs/kvm-stub.o
  CC      alpha-softmmu/accel/stubs/kvm-stub.o
  CC      arm-softmmu/accel/stubs/whpx-stub.o
  CC      aarch64-softmmu/accel/accel.o
  CC      cris-softmmu/accel/tcg/tcg-all.o
  CC      alpha-softmmu/accel/tcg/tcg-all.o
  CC      arm-softmmu/accel/stubs/kvm-stub.o
  CC      cris-softmmu/accel/tcg/cputlb.o
  CC      aarch64-softmmu/accel/stubs/hax-stub.o
  CC      alpha-softmmu/accel/tcg/cputlb.o
  CC      arm-softmmu/accel/tcg/tcg-all.o
  CC      aarch64-softmmu/accel/stubs/hvf-stub.o
  CC      arm-softmmu/accel/tcg/cputlb.o
  CC      aarch64-softmmu/accel/stubs/whpx-stub.o
  CC      aarch64-softmmu/accel/stubs/kvm-stub.o
  CC      aarch64-softmmu/accel/tcg/tcg-all.o
  CC      cris-softmmu/accel/tcg/tcg-runtime.o
  CC      alpha-softmmu/accel/tcg/tcg-runtime.o
  CC      cris-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      aarch64-softmmu/accel/tcg/cputlb.o
  CC      alpha-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      arm-softmmu/accel/tcg/tcg-runtime.o
  CC      cris-softmmu/accel/tcg/cpu-exec.o
  CC      alpha-softmmu/accel/tcg/cpu-exec.o
  CC      arm-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      cris-softmmu/accel/tcg/cpu-exec-common.o
  CC      alpha-softmmu/accel/tcg/cpu-exec-common.o
  CC      cris-softmmu/accel/tcg/translate-all.o
  CC      aarch64-softmmu/accel/tcg/tcg-runtime.o
  CC      alpha-softmmu/accel/tcg/translate-all.o
  CC      aarch64-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      cris-softmmu/accel/tcg/translator.o
  CC      arm-softmmu/accel/tcg/cpu-exec.o
  CC      alpha-softmmu/accel/tcg/translator.o
  CC      cris-softmmu/hw/core/generic-loader.o
  CC      arm-softmmu/accel/tcg/cpu-exec-common.o
  CC      cris-softmmu/hw/core/null-machine.o
  CC      alpha-softmmu/hw/9pfs/virtio-9p-device.o
  CC      arm-softmmu/accel/tcg/translate-all.o
  CC      aarch64-softmmu/accel/tcg/cpu-exec.o
  CC      cris-softmmu/hw/misc/mmio_interface.o
  CC      alpha-softmmu/hw/block/virtio-blk.o
  CC      aarch64-softmmu/accel/tcg/cpu-exec-common.o
  CC      arm-softmmu/accel/tcg/translator.o
  CC      cris-softmmu/hw/net/etraxfs_eth.o
  CC      alpha-softmmu/hw/block/vhost-user-blk.o
  CC      aarch64-softmmu/accel/tcg/translate-all.o
  CC      cris-softmmu/hw/net/vhost_net.o
  CC      arm-softmmu/hw/9pfs/virtio-9p-device.o
  CC      alpha-softmmu/hw/block/dataplane/virtio-blk.o
  CC      cris-softmmu/hw/net/rocker/qmp-norocker.o
  CC      arm-softmmu/hw/adc/stm32f2xx_adc.o
  CC      aarch64-softmmu/accel/tcg/translator.o
  CC      cris-softmmu/hw/vfio/common.o
  CC      alpha-softmmu/hw/char/virtio-serial-bus.o
  CC      arm-softmmu/hw/block/virtio-blk.o
  CC      aarch64-softmmu/hw/9pfs/virtio-9p-device.o
  CC      alpha-softmmu/hw/core/generic-loader.o
  CC      cris-softmmu/hw/vfio/platform.o
  CC      arm-softmmu/hw/block/vhost-user-blk.o
  CC      alpha-softmmu/hw/core/null-machine.o
  CC      aarch64-softmmu/hw/adc/stm32f2xx_adc.o
  CC      aarch64-softmmu/hw/block/virtio-blk.o
  CC      arm-softmmu/hw/block/dataplane/virtio-blk.o
  CC      alpha-softmmu/hw/display/vga.o
  CC      cris-softmmu/hw/vfio/spapr.o
  CC      arm-softmmu/hw/char/exynos4210_uart.o
  CC      cris-softmmu/hw/cris/boot.o
  CC      aarch64-softmmu/hw/block/vhost-user-blk.o
  CC      arm-softmmu/hw/char/omap_uart.o
  CC      cris-softmmu/hw/cris/axis_dev88.o
  CC      arm-softmmu/hw/char/digic-uart.o
  CC      aarch64-softmmu/hw/block/dataplane/virtio-blk.o
  CC      alpha-softmmu/hw/display/virtio-gpu.o
  CC      cris-softmmu/target/cris/translate.o
  CC      arm-softmmu/hw/char/stm32f2xx_usart.o
  CC      aarch64-softmmu/hw/char/exynos4210_uart.o
  CC      arm-softmmu/hw/char/bcm2835_aux.o
  CC      aarch64-softmmu/hw/char/omap_uart.o
  CC      alpha-softmmu/hw/display/virtio-gpu-3d.o
  CC      arm-softmmu/hw/char/virtio-serial-bus.o
  CC      aarch64-softmmu/hw/char/digic-uart.o
  CC      alpha-softmmu/hw/display/virtio-gpu-pci.o
  CC      aarch64-softmmu/hw/char/stm32f2xx_usart.o
  CC      arm-softmmu/hw/core/generic-loader.o
  CC      aarch64-softmmu/hw/char/bcm2835_aux.o
  CC      cris-softmmu/target/cris/op_helper.o
  CC      arm-softmmu/hw/core/null-machine.o
  CC      alpha-softmmu/hw/misc/ivshmem.o
  CC      aarch64-softmmu/hw/char/virtio-serial-bus.o
  CC      arm-softmmu/hw/cpu/arm11mpcore.o
  CC      cris-softmmu/target/cris/helper.o
  CC      alpha-softmmu/hw/misc/mmio_interface.o
  CC      cris-softmmu/target/cris/cpu.o
  CC      arm-softmmu/hw/cpu/realview_mpcore.o
  CC      cris-softmmu/target/cris/gdbstub.o
  CC      aarch64-softmmu/hw/core/generic-loader.o
  CC      alpha-softmmu/hw/net/virtio-net.o
  CC      arm-softmmu/hw/cpu/a9mpcore.o
  CC      aarch64-softmmu/hw/core/null-machine.o
  CC      cris-softmmu/target/cris/mmu.o
  CC      arm-softmmu/hw/cpu/a15mpcore.o
  CC      cris-softmmu/target/cris/machine.o
  CC      aarch64-softmmu/hw/cpu/arm11mpcore.o
  GEN     trace/generated-helpers.c
  CC      cris-softmmu/trace/control-target.o
  CC      alpha-softmmu/hw/net/vhost_net.o
  CC      arm-softmmu/hw/display/omap_dss.o
  CC      aarch64-softmmu/hw/cpu/realview_mpcore.o
  CC      alpha-softmmu/hw/scsi/virtio-scsi.o
  CC      cris-softmmu/trace/generated-helpers.o
  CC      aarch64-softmmu/hw/cpu/a9mpcore.o
  LINK    cris-softmmu/qemu-system-cris
  CC      arm-softmmu/hw/display/omap_lcdc.o
  CC      aarch64-softmmu/hw/cpu/a15mpcore.o
  CC      alpha-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      alpha-softmmu/hw/scsi/vhost-scsi-common.o
  CC      aarch64-softmmu/hw/display/omap_dss.o
  CC      arm-softmmu/hw/display/pxa2xx_lcd.o
  CC      alpha-softmmu/hw/scsi/vhost-scsi.o
  CC      aarch64-softmmu/hw/display/omap_lcdc.o
  CC      alpha-softmmu/hw/scsi/vhost-user-scsi.o
  CC      aarch64-softmmu/hw/display/pxa2xx_lcd.o
  CC      alpha-softmmu/hw/timer/mc146818rtc.o
  CC      arm-softmmu/hw/display/bcm2835_fb.o
  CC      alpha-softmmu/hw/vfio/common.o
  CC      alpha-softmmu/hw/vfio/pci.o
  CC      arm-softmmu/hw/display/vga.o
  CC      aarch64-softmmu/hw/display/bcm2835_fb.o
  CC      aarch64-softmmu/hw/display/vga.o
  GEN     hppa-softmmu/hmp-commands.h
  GEN     hppa-softmmu/hmp-commands-info.h
  GEN     hppa-softmmu/config-target.h
  CC      alpha-softmmu/hw/vfio/pci-quirks.o
  CC      hppa-softmmu/exec.o
  CC      arm-softmmu/hw/display/virtio-gpu.o
  CC      alpha-softmmu/hw/vfio/display.o
  CC      aarch64-softmmu/hw/display/virtio-gpu.o
  CC      alpha-softmmu/hw/vfio/platform.o
  CC      arm-softmmu/hw/display/virtio-gpu-3d.o
  CC      aarch64-softmmu/hw/display/virtio-gpu-3d.o
  CC      alpha-softmmu/hw/vfio/spapr.o
  CC      hppa-softmmu/tcg/tcg.o
  CC      arm-softmmu/hw/display/virtio-gpu-pci.o
  CC      alpha-softmmu/hw/virtio/virtio.o
  CC      aarch64-softmmu/hw/display/virtio-gpu-pci.o
  CC      arm-softmmu/hw/dma/omap_dma.o
  CC      aarch64-softmmu/hw/display/dpcd.o
  CC      alpha-softmmu/hw/virtio/virtio-balloon.o
  CC      arm-softmmu/hw/dma/soc_dma.o
  CC      aarch64-softmmu/hw/display/xlnx_dp.o
  CC      alpha-softmmu/hw/virtio/vhost.o
  CC      arm-softmmu/hw/dma/pxa2xx_dma.o
  CC      hppa-softmmu/tcg/tcg-op.o
  CC      aarch64-softmmu/hw/dma/xlnx_dpdma.o
  CC      arm-softmmu/hw/dma/bcm2835_dma.o
  CC      alpha-softmmu/hw/virtio/vhost-backend.o
  CC      aarch64-softmmu/hw/dma/omap_dma.o
  CC      alpha-softmmu/hw/virtio/vhost-user.o
  CC      arm-softmmu/hw/gpio/omap_gpio.o
  CC      alpha-softmmu/hw/virtio/vhost-vsock.o
  CC      aarch64-softmmu/hw/dma/soc_dma.o
  CC      hppa-softmmu/tcg/tcg-op-vec.o
  CC      arm-softmmu/hw/gpio/imx_gpio.o
  CC      aarch64-softmmu/hw/dma/pxa2xx_dma.o
  CC      arm-softmmu/hw/gpio/bcm2835_gpio.o
  CC      alpha-softmmu/hw/virtio/virtio-crypto.o
  CC      arm-softmmu/hw/i2c/omap_i2c.o
  CC      hppa-softmmu/tcg/tcg-op-gvec.o
  CC      alpha-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      aarch64-softmmu/hw/dma/bcm2835_dma.o
  CC      arm-softmmu/hw/input/pxa2xx_keypad.o
  CC      aarch64-softmmu/hw/gpio/omap_gpio.o
  CC      arm-softmmu/hw/input/tsc210x.o
  CC      alpha-softmmu/hw/alpha/dp264.o
  CC      aarch64-softmmu/hw/gpio/imx_gpio.o
  CC      arm-softmmu/hw/intc/armv7m_nvic.o
  CC      alpha-softmmu/hw/alpha/pci.o
  CC      aarch64-softmmu/hw/gpio/bcm2835_gpio.o
  CC      alpha-softmmu/hw/alpha/typhoon.o
  CC      hppa-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/hw/i2c/omap_i2c.o
  CC      hppa-softmmu/tcg/optimize.o
  CC      alpha-softmmu/target/alpha/machine.o
  CC      arm-softmmu/hw/intc/exynos4210_gic.o
  CC      aarch64-softmmu/hw/input/pxa2xx_keypad.o
  CC      alpha-softmmu/target/alpha/translate.o
  CC      arm-softmmu/hw/intc/exynos4210_combiner.o
  CC      aarch64-softmmu/hw/input/tsc210x.o
  CC      hppa-softmmu/fpu/softfloat.o
  CC      arm-softmmu/hw/intc/omap_intc.o
  CC      aarch64-softmmu/hw/intc/armv7m_nvic.o
  CC      alpha-softmmu/target/alpha/helper.o
  CC      arm-softmmu/hw/intc/bcm2835_ic.o
  CC      aarch64-softmmu/hw/intc/exynos4210_gic.o
  CC      alpha-softmmu/target/alpha/cpu.o
  CC      arm-softmmu/hw/intc/bcm2836_control.o
  CC      aarch64-softmmu/hw/intc/exynos4210_combiner.o
  CC      alpha-softmmu/target/alpha/int_helper.o
  CC      arm-softmmu/hw/intc/allwinner-a10-pic.o
  CC      aarch64-softmmu/hw/intc/omap_intc.o
  CC      alpha-softmmu/target/alpha/fpu_helper.o
  CC      arm-softmmu/hw/intc/aspeed_vic.o
  CC      alpha-softmmu/target/alpha/vax_helper.o
  CC      aarch64-softmmu/hw/intc/bcm2835_ic.o
  CC      arm-softmmu/hw/intc/arm_gicv3_cpuif.o
  CC      aarch64-softmmu/hw/intc/bcm2836_control.o
  CC      alpha-softmmu/target/alpha/sys_helper.o
  CC      aarch64-softmmu/hw/intc/allwinner-a10-pic.o
  CC      alpha-softmmu/target/alpha/mem_helper.o
  CC      aarch64-softmmu/hw/intc/aspeed_vic.o
  CC      hppa-softmmu/fpu/hostfloat.o
  CC      alpha-softmmu/target/alpha/gdbstub.o
  CC      arm-softmmu/hw/misc/ivshmem.o
  CC      aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
  GEN     trace/generated-helpers.c
  CC      alpha-softmmu/trace/control-target.o
  CC      hppa-softmmu/disas.o
  CC      alpha-softmmu/trace/generated-helpers.o
  CC      arm-softmmu/hw/misc/arm_sysctl.o
  CC      arm-softmmu/hw/misc/cbus.o
  LINK    alpha-softmmu/qemu-system-alpha
  CC      hppa-softmmu/arch_init.o
  CC      arm-softmmu/hw/misc/exynos4210_pmu.o
  CC      aarch64-softmmu/hw/misc/ivshmem.o
  CC      hppa-softmmu/cpus.o
  CC      arm-softmmu/hw/misc/exynos4210_clk.o
  CC      aarch64-softmmu/hw/misc/arm_sysctl.o
  CC      arm-softmmu/hw/misc/exynos4210_rng.o
  CC      aarch64-softmmu/hw/misc/cbus.o
  CC      hppa-softmmu/monitor.o
  CC      arm-softmmu/hw/misc/imx_ccm.o
  CC      aarch64-softmmu/hw/misc/exynos4210_pmu.o
  CC      arm-softmmu/hw/misc/imx31_ccm.o
  CC      aarch64-softmmu/hw/misc/exynos4210_clk.o
  CC      aarch64-softmmu/hw/misc/exynos4210_rng.o
  GEN     i386-softmmu/hmp-commands.h
  GEN     i386-softmmu/hmp-commands-info.h
  GEN     i386-softmmu/config-target.h
  CC      i386-softmmu/exec.o
  CC      aarch64-softmmu/hw/misc/imx_ccm.o
  CC      aarch64-softmmu/hw/misc/imx31_ccm.o
  CC      aarch64-softmmu/hw/misc/imx25_ccm.o
  CC      hppa-softmmu/gdbstub.o
  CC      aarch64-softmmu/hw/misc/imx6_ccm.o
  CC      aarch64-softmmu/hw/misc/imx6_src.o
  CC      aarch64-softmmu/hw/misc/imx7_ccm.o
  CC      hppa-softmmu/balloon.o
  CC      aarch64-softmmu/hw/misc/imx2_wdt.o
  CC      hppa-softmmu/ioport.o
  CC      aarch64-softmmu/hw/misc/imx7_snvs.o
  CC      hppa-softmmu/numa.o
  CC      aarch64-softmmu/hw/misc/imx7_gpr.o
  CC      i386-softmmu/tcg/tcg.o
  CC      aarch64-softmmu/hw/misc/mst_fpga.o
  CC      hppa-softmmu/qtest.o
  CC      aarch64-softmmu/hw/misc/omap_clk.o
  CC      aarch64-softmmu/hw/misc/omap_gpmc.o
  CC      hppa-softmmu/memory.o
  CC      aarch64-softmmu/hw/misc/omap_l4.o
  CC      aarch64-softmmu/hw/misc/omap_sdrc.o
  CC      aarch64-softmmu/hw/misc/omap_tap.o
  CC      aarch64-softmmu/hw/misc/bcm2835_mbox.o
  CC      aarch64-softmmu/hw/misc/bcm2835_property.o
  CC      hppa-softmmu/memory_mapping.o
  CC      i386-softmmu/tcg/tcg-op.o
  CC      hppa-softmmu/dump.o
  CC      aarch64-softmmu/hw/misc/bcm2835_rng.o
  CC      aarch64-softmmu/hw/misc/zynq_slcr.o
  CC      aarch64-softmmu/hw/misc/zynq-xadc.o
  CC      hppa-softmmu/migration/ram.o
  CC      aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
  CC      aarch64-softmmu/hw/misc/mps2-fpgaio.o
  CC      aarch64-softmmu/hw/misc/mps2-scc.o
  CC      aarch64-softmmu/hw/misc/tz-ppc.o
  CC      hppa-softmmu/accel/accel.o
  CC      aarch64-softmmu/hw/misc/iotkit-secctl.o
  CC      i386-softmmu/tcg/tcg-op-vec.o
  CC      hppa-softmmu/accel/stubs/hax-stub.o
  CC      hppa-softmmu/accel/stubs/hvf-stub.o
  CC      aarch64-softmmu/hw/misc/auxbus.o
  CC      hppa-softmmu/accel/stubs/whpx-stub.o
  CC      aarch64-softmmu/hw/misc/aspeed_scu.o
  CC      i386-softmmu/tcg/tcg-op-gvec.o
  CC      hppa-softmmu/accel/stubs/kvm-stub.o
  CC      aarch64-softmmu/hw/misc/aspeed_sdmc.o
  CC      hppa-softmmu/accel/tcg/tcg-all.o
  CC      aarch64-softmmu/hw/misc/mmio_interface.o
  CC      hppa-softmmu/accel/tcg/cputlb.o
  CC      aarch64-softmmu/hw/misc/msf2-sysreg.o
  CC      aarch64-softmmu/hw/net/virtio-net.o
  CC      i386-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/hw/net/vhost_net.o
  CC      i386-softmmu/tcg/optimize.o
  CC      aarch64-softmmu/hw/pcmcia/pxa2xx.o
  CC      hppa-softmmu/accel/tcg/tcg-runtime.o
  CC      aarch64-softmmu/hw/scsi/virtio-scsi.o
  CC      hppa-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      i386-softmmu/fpu/softfloat.o
  CC      aarch64-softmmu/hw/scsi/vhost-scsi-common.o
  CC      aarch64-softmmu/hw/scsi/vhost-scsi.o
  CC      hppa-softmmu/accel/tcg/cpu-exec.o
  CC      aarch64-softmmu/hw/scsi/vhost-user-scsi.o
  CC      aarch64-softmmu/hw/sd/omap_mmc.o
  CC      hppa-softmmu/accel/tcg/cpu-exec-common.o
  CC      hppa-softmmu/accel/tcg/translate-all.o
  CC      aarch64-softmmu/hw/sd/pxa2xx_mmci.o
  CC      aarch64-softmmu/hw/sd/bcm2835_sdhost.o
  CC      hppa-softmmu/accel/tcg/translator.o
  CC      aarch64-softmmu/hw/ssi/omap_spi.o
  CC      hppa-softmmu/hw/9pfs/virtio-9p-device.o
  CC      aarch64-softmmu/hw/ssi/imx_spi.o
  CC      hppa-softmmu/hw/block/virtio-blk.o
  CC      aarch64-softmmu/hw/timer/exynos4210_mct.o
  CC      aarch64-softmmu/hw/timer/exynos4210_pwm.o
  CC      hppa-softmmu/hw/block/vhost-user-blk.o
  CC      aarch64-softmmu/hw/timer/exynos4210_rtc.o
  CC      hppa-softmmu/hw/block/dataplane/virtio-blk.o
  CC      aarch64-softmmu/hw/timer/omap_gptimer.o
  CC      hppa-softmmu/hw/char/virtio-serial-bus.o
  CC      aarch64-softmmu/hw/timer/omap_synctimer.o
  CC      aarch64-softmmu/hw/timer/pxa2xx_timer.o
  CC      i386-softmmu/fpu/hostfloat.o
  CC      hppa-softmmu/hw/core/generic-loader.o
  CC      aarch64-softmmu/hw/timer/digic-timer.o
  CC      hppa-softmmu/hw/core/null-machine.o
  CC      i386-softmmu/disas.o
  CC      aarch64-softmmu/hw/timer/allwinner-a10-pit.o
  CC      hppa-softmmu/hw/display/vga.o
  CC      aarch64-softmmu/hw/usb/tusb6010.o
  GEN     i386-softmmu/gdbstub-xml.c
  CC      i386-softmmu/arch_init.o
  CC      aarch64-softmmu/hw/usb/chipidea.o
  CC      i386-softmmu/cpus.o
  CC      aarch64-softmmu/hw/vfio/common.o
  CC      i386-softmmu/monitor.o
  CC      hppa-softmmu/hw/display/virtio-gpu.o
  CC      aarch64-softmmu/hw/vfio/pci.o
  CC      hppa-softmmu/hw/display/virtio-gpu-3d.o
  CC      hppa-softmmu/hw/display/virtio-gpu-pci.o
  CC      i386-softmmu/gdbstub.o
  CC      aarch64-softmmu/hw/vfio/pci-quirks.o
  CC      hppa-softmmu/hw/display/virtio-vga.o
  CC      hppa-softmmu/hw/misc/ivshmem.o
  CC      i386-softmmu/balloon.o
  CC      aarch64-softmmu/hw/vfio/display.o
  CC      i386-softmmu/ioport.o
  CC      hppa-softmmu/hw/misc/mmio_interface.o
  CC      aarch64-softmmu/hw/vfio/platform.o
  CC      i386-softmmu/numa.o
  CC      hppa-softmmu/hw/net/virtio-net.o
  CC      i386-softmmu/qtest.o
  CC      aarch64-softmmu/hw/vfio/calxeda-xgmac.o
  CC      hppa-softmmu/hw/net/vhost_net.o
  CC      i386-softmmu/memory.o
  CC      aarch64-softmmu/hw/vfio/amd-xgbe.o
  CC      hppa-softmmu/hw/scsi/virtio-scsi.o
  CC      aarch64-softmmu/hw/vfio/spapr.o
  CC      hppa-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      aarch64-softmmu/hw/virtio/virtio.o
  CC      hppa-softmmu/hw/scsi/vhost-scsi-common.o
  CC      hppa-softmmu/hw/scsi/vhost-scsi.o
  CC      i386-softmmu/memory_mapping.o
  CC      hppa-softmmu/hw/scsi/vhost-user-scsi.o
  CC      i386-softmmu/dump.o
  CC      hppa-softmmu/hw/timer/mc146818rtc.o
  CC      aarch64-softmmu/hw/virtio/virtio-balloon.o
  CC      aarch64-softmmu/hw/virtio/vhost.o
  CC      i386-softmmu/migration/ram.o
  CC      hppa-softmmu/hw/vfio/common.o
  CC      aarch64-softmmu/hw/virtio/vhost-backend.o
  CC      hppa-softmmu/hw/vfio/pci.o
  CC      aarch64-softmmu/hw/virtio/vhost-user.o
  CC      i386-softmmu/accel/accel.o
  CC      i386-softmmu/accel/stubs/hax-stub.o
  CC      i386-softmmu/accel/stubs/hvf-stub.o
  CC      aarch64-softmmu/hw/virtio/vhost-vsock.o
  CC      i386-softmmu/accel/stubs/whpx-stub.o
  CC      aarch64-softmmu/hw/virtio/virtio-crypto.o
  CC      i386-softmmu/accel/stubs/kvm-stub.o
  CC      hppa-softmmu/hw/vfio/pci-quirks.o
  CC      i386-softmmu/accel/tcg/tcg-all.o
  CC      aarch64-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      i386-softmmu/accel/tcg/cputlb.o
  CC      aarch64-softmmu/hw/arm/boot.o
  CC      hppa-softmmu/hw/vfio/display.o
  CC      aarch64-softmmu/hw/arm/virt.o
  CC      hppa-softmmu/hw/vfio/platform.o
  CC      hppa-softmmu/hw/vfio/spapr.o
  CC      aarch64-softmmu/hw/arm/sysbus-fdt.o
  CC      i386-softmmu/accel/tcg/tcg-runtime.o
  CC      hppa-softmmu/hw/virtio/virtio.o
  CC      i386-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      aarch64-softmmu/hw/arm/virt-acpi-build.o
  CC      aarch64-softmmu/hw/arm/digic_boards.o
  CC      aarch64-softmmu/hw/arm/exynos4_boards.o
  CC      hppa-softmmu/hw/virtio/virtio-balloon.o
  CC      aarch64-softmmu/hw/arm/highbank.o
  CC      i386-softmmu/accel/tcg/cpu-exec.o
  CC      hppa-softmmu/hw/virtio/vhost.o
  CC      aarch64-softmmu/hw/arm/integratorcp.o
  CC      i386-softmmu/accel/tcg/cpu-exec-common.o
  CC      i386-softmmu/accel/tcg/translate-all.o
  CC      aarch64-softmmu/hw/arm/mainstone.o
  CC      hppa-softmmu/hw/virtio/vhost-backend.o
  CC      aarch64-softmmu/hw/arm/musicpal.o
  CC      hppa-softmmu/hw/virtio/vhost-user.o
  CC      i386-softmmu/accel/tcg/translator.o
  CC      aarch64-softmmu/hw/arm/netduino2.o
  CC      i386-softmmu/hw/9pfs/virtio-9p-device.o
  CC      hppa-softmmu/hw/virtio/vhost-vsock.o
  CC      aarch64-softmmu/hw/arm/nseries.o
  CC      i386-softmmu/hw/block/virtio-blk.o
  CC      hppa-softmmu/hw/virtio/virtio-crypto.o
  CC      hppa-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      i386-softmmu/hw/block/vhost-user-blk.o
  CC      aarch64-softmmu/hw/arm/omap_sx1.o
  CC      i386-softmmu/hw/block/dataplane/virtio-blk.o
  CC      hppa-softmmu/hw/hppa/machine.o
  CC      aarch64-softmmu/hw/arm/palm.o
  CC      i386-softmmu/hw/char/virtio-serial-bus.o
  CC      hppa-softmmu/hw/hppa/pci.o
  CC      aarch64-softmmu/hw/arm/gumstix.o
  CC      hppa-softmmu/hw/hppa/dino.o
  CC      aarch64-softmmu/hw/arm/spitz.o
  CC      i386-softmmu/hw/core/generic-loader.o
  CC      hppa-softmmu/target/hppa/translate.o
  CC      i386-softmmu/hw/core/null-machine.o
  CC      i386-softmmu/hw/display/vga.o
  CC      aarch64-softmmu/hw/arm/tosa.o
  CC      aarch64-softmmu/hw/arm/z2.o
  CC      aarch64-softmmu/hw/arm/realview.o
  CC      i386-softmmu/hw/display/virtio-gpu.o
  CC      aarch64-softmmu/hw/arm/stellaris.o
  CC      hppa-softmmu/target/hppa/helper.o
  CC      aarch64-softmmu/hw/arm/collie.o
  CC      hppa-softmmu/target/hppa/cpu.o
  CC      i386-softmmu/hw/display/virtio-gpu-3d.o
  CC      aarch64-softmmu/hw/arm/vexpress.o
  CC      hppa-softmmu/target/hppa/op_helper.o
  CC      aarch64-softmmu/hw/arm/versatilepb.o
  CC      i386-softmmu/hw/display/virtio-gpu-pci.o
  CC      hppa-softmmu/target/hppa/gdbstub.o
  CC      aarch64-softmmu/hw/arm/xilinx_zynq.o
  CC      hppa-softmmu/target/hppa/mem_helper.o
  CC      i386-softmmu/hw/display/virtio-vga.o
  CC      hppa-softmmu/target/hppa/int_helper.o
  CC      aarch64-softmmu/hw/arm/armv7m.o
  CC      hppa-softmmu/target/hppa/machine.o
  CC      i386-softmmu/hw/intc/apic.o
  CC      aarch64-softmmu/hw/arm/exynos4210.o
  GEN     trace/generated-helpers.c
  CC      hppa-softmmu/trace/control-target.o
  CC      aarch64-softmmu/hw/arm/pxa2xx.o
  CC      hppa-softmmu/trace/generated-helpers.o
  CC      i386-softmmu/hw/intc/apic_common.o
  LINK    hppa-softmmu/qemu-system-hppa
  CC      i386-softmmu/hw/intc/ioapic.o
  CC      i386-softmmu/hw/isa/lpc_ich9.o
  CC      aarch64-softmmu/hw/arm/pxa2xx_gpio.o
  CC      i386-softmmu/hw/misc/ivshmem.o
  CC      aarch64-softmmu/hw/arm/pxa2xx_pic.o
  CC      aarch64-softmmu/hw/arm/digic.o
  CC      i386-softmmu/hw/misc/pvpanic.o
  CC      aarch64-softmmu/hw/arm/omap1.o
  CC      i386-softmmu/hw/misc/mmio_interface.o
  CC      i386-softmmu/hw/net/virtio-net.o
  CC      aarch64-softmmu/hw/arm/omap2.o
  CC      arm-softmmu/hw/misc/imx25_ccm.o
  CC      aarch64-softmmu/hw/arm/strongarm.o
  GEN     lm32-softmmu/hmp-commands.h
  GEN     lm32-softmmu/hmp-commands-info.h
  GEN     lm32-softmmu/config-target.h
  CC      lm32-softmmu/exec.o
  CC      aarch64-softmmu/hw/arm/allwinner-a10.o
  CC      aarch64-softmmu/hw/arm/cubieboard.o
  CC      aarch64-softmmu/hw/arm/bcm2835_peripherals.o
  CC      aarch64-softmmu/hw/arm/bcm2836.o
  CC      aarch64-softmmu/hw/arm/raspi.o
  CC      aarch64-softmmu/hw/arm/stm32f205_soc.o
  CC      lm32-softmmu/tcg/tcg.o
  CC      aarch64-softmmu/hw/arm/xlnx-zynqmp.o
  CC      aarch64-softmmu/hw/arm/xlnx-zcu102.o
  CC      aarch64-softmmu/hw/arm/fsl-imx25.o
  CC      aarch64-softmmu/hw/arm/imx25_pdk.o
  CC      aarch64-softmmu/hw/arm/fsl-imx31.o
  CC      lm32-softmmu/tcg/tcg-op.o
  CC      aarch64-softmmu/hw/arm/kzm.o
  CC      aarch64-softmmu/hw/arm/fsl-imx6.o
  CC      aarch64-softmmu/hw/arm/sabrelite.o
  CC      aarch64-softmmu/hw/arm/aspeed_soc.o
  CC      aarch64-softmmu/hw/arm/aspeed.o
  CC      aarch64-softmmu/hw/arm/mps2.o
  CC      lm32-softmmu/tcg/tcg-op-vec.o
  CC      aarch64-softmmu/hw/arm/mps2-tz.o
  CC      aarch64-softmmu/hw/arm/msf2-soc.o
  CC      lm32-softmmu/tcg/tcg-op-gvec.o
  CC      aarch64-softmmu/hw/arm/msf2-som.o
  CC      aarch64-softmmu/hw/arm/iotkit.o
  CC      aarch64-softmmu/hw/arm/fsl-imx7.o
  CC      aarch64-softmmu/hw/arm/mcimx7d-sabre.o
  CC      lm32-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/target/arm/arm-semi.o
  CC      lm32-softmmu/tcg/optimize.o
  CC      aarch64-softmmu/target/arm/machine.o
  CC      aarch64-softmmu/target/arm/psci.o
  CC      lm32-softmmu/fpu/softfloat.o
  CC      aarch64-softmmu/target/arm/arch_dump.o
  CC      aarch64-softmmu/target/arm/monitor.o
  CC      aarch64-softmmu/target/arm/kvm-stub.o
  CC      aarch64-softmmu/target/arm/translate.o
  CC      lm32-softmmu/fpu/hostfloat.o
  CC      lm32-softmmu/disas.o
  CC      lm32-softmmu/arch_init.o
  CC      lm32-softmmu/cpus.o
  CC      lm32-softmmu/monitor.o
  CC      lm32-softmmu/gdbstub.o
  CC      lm32-softmmu/balloon.o
  CC      aarch64-softmmu/target/arm/op_helper.o
  CC      lm32-softmmu/ioport.o
  CC      lm32-softmmu/numa.o
  CC      lm32-softmmu/qtest.o
  CC      aarch64-softmmu/target/arm/helper.o
  CC      lm32-softmmu/memory.o
  CC      lm32-softmmu/memory_mapping.o
  CC      lm32-softmmu/dump.o
  CC      lm32-softmmu/migration/ram.o
  CC      lm32-softmmu/accel/accel.o
  CC      lm32-softmmu/accel/stubs/hax-stub.o
  CC      lm32-softmmu/accel/stubs/hvf-stub.o
  CC      aarch64-softmmu/target/arm/cpu.o
  CC      lm32-softmmu/accel/stubs/whpx-stub.o
  CC      lm32-softmmu/accel/stubs/kvm-stub.o
  CC      lm32-softmmu/accel/tcg/tcg-all.o
  CC      aarch64-softmmu/target/arm/neon_helper.o
  CC      lm32-softmmu/accel/tcg/cputlb.o
  CC      aarch64-softmmu/target/arm/iwmmxt_helper.o
  CC      lm32-softmmu/accel/tcg/tcg-runtime.o
  CC      lm32-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      aarch64-softmmu/target/arm/vec_helper.o
  CC      aarch64-softmmu/target/arm/gdbstub.o
  CC      aarch64-softmmu/target/arm/cpu64.o
  CC      lm32-softmmu/accel/tcg/cpu-exec.o
  CC      aarch64-softmmu/target/arm/translate-a64.o
  CC      lm32-softmmu/accel/tcg/cpu-exec-common.o
  CC      lm32-softmmu/accel/tcg/translate-all.o
  CC      lm32-softmmu/accel/tcg/translator.o
  CC      lm32-softmmu/hw/core/generic-loader.o
  CC      lm32-softmmu/hw/core/null-machine.o
  CC      lm32-softmmu/hw/input/milkymist-softusb.o
  CC      lm32-softmmu/hw/misc/milkymist-hpdmc.o
  CC      lm32-softmmu/hw/misc/milkymist-pfpu.o
  CC      lm32-softmmu/hw/misc/mmio_interface.o
  CC      lm32-softmmu/hw/net/milkymist-minimac2.o
  CC      lm32-softmmu/hw/net/vhost_net.o
  CC      lm32-softmmu/hw/net/rocker/qmp-norocker.o
  CC      lm32-softmmu/hw/sd/milkymist-memcard.o
  CC      lm32-softmmu/hw/vfio/common.o
  CC      lm32-softmmu/hw/vfio/platform.o
  CC      lm32-softmmu/hw/vfio/spapr.o
  CC      aarch64-softmmu/target/arm/helper-a64.o
  CC      lm32-softmmu/hw/lm32/lm32_boards.o
  CC      aarch64-softmmu/target/arm/gdbstub64.o
  CC      lm32-softmmu/hw/lm32/milkymist.o
  CC      aarch64-softmmu/target/arm/crypto_helper.o
  CC      lm32-softmmu/target/lm32/translate.o
  CC      aarch64-softmmu/target/arm/arm-powerctl.o
  GEN     trace/generated-helpers.c
  CC      aarch64-softmmu/trace/control-target.o
  CC      aarch64-softmmu/gdbstub-xml.o
  CC      aarch64-softmmu/trace/generated-helpers.o
  CC      lm32-softmmu/target/lm32/op_helper.o
  LINK    aarch64-softmmu/qemu-system-aarch64
  CC      lm32-softmmu/target/lm32/helper.o
  CC      lm32-softmmu/target/lm32/cpu.o
  CC      lm32-softmmu/target/lm32/gdbstub.o
  CC      lm32-softmmu/target/lm32/lm32-semi.o
  CC      lm32-softmmu/target/lm32/machine.o
  GEN     trace/generated-helpers.c
  CC      lm32-softmmu/trace/control-target.o
  CC      lm32-softmmu/trace/generated-helpers.o
  LINK    lm32-softmmu/qemu-system-lm32
  GEN     m68k-softmmu/hmp-commands.h
  GEN     m68k-softmmu/hmp-commands-info.h
  GEN     m68k-softmmu/config-target.h
  CC      m68k-softmmu/exec.o
  CC      i386-softmmu/hw/net/vhost_net.o
  CC      i386-softmmu/hw/scsi/virtio-scsi.o
  GEN     microblazeel-softmmu/hmp-commands.h
  GEN     microblazeel-softmmu/hmp-commands-info.h
  GEN     microblazeel-softmmu/config-target.h
  CC      microblazeel-softmmu/exec.o
  CC      i386-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      i386-softmmu/hw/scsi/vhost-scsi-common.o
  CC      i386-softmmu/hw/scsi/vhost-scsi.o
  CC      i386-softmmu/hw/scsi/vhost-user-scsi.o
  CC      m68k-softmmu/tcg/tcg.o
  CC      i386-softmmu/hw/timer/mc146818rtc.o
  CC      i386-softmmu/hw/vfio/common.o
  CC      microblazeel-softmmu/tcg/tcg.o
  CC      i386-softmmu/hw/vfio/pci.o
  CC      m68k-softmmu/tcg/tcg-op.o
  CC      i386-softmmu/hw/vfio/pci-quirks.o
  CC      microblazeel-softmmu/tcg/tcg-op.o
  CC      i386-softmmu/hw/vfio/display.o
  CC      m68k-softmmu/tcg/tcg-op-vec.o
  CC      i386-softmmu/hw/vfio/platform.o
  CC      m68k-softmmu/tcg/tcg-op-gvec.o
  CC      microblazeel-softmmu/tcg/tcg-op-vec.o
  CC      i386-softmmu/hw/vfio/spapr.o
  CC      microblazeel-softmmu/tcg/tcg-op-gvec.o
  CC      i386-softmmu/hw/virtio/virtio.o
  CC      m68k-softmmu/tcg/tcg-common.o
  CC      i386-softmmu/hw/virtio/virtio-balloon.o
  CC      m68k-softmmu/tcg/optimize.o
  CC      microblazeel-softmmu/tcg/tcg-common.o
  CC      i386-softmmu/hw/virtio/vhost.o
  CC      microblazeel-softmmu/tcg/optimize.o
  CC      m68k-softmmu/fpu/softfloat.o
  CC      i386-softmmu/hw/virtio/vhost-backend.o
  CC      microblazeel-softmmu/fpu/softfloat.o
  CC      i386-softmmu/hw/virtio/vhost-user.o
  CC      i386-softmmu/hw/virtio/vhost-vsock.o
  CC      i386-softmmu/hw/virtio/virtio-crypto.o
  CC      i386-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      i386-softmmu/hw/i386/multiboot.o
  CC      i386-softmmu/hw/i386/pc.o
  CC      i386-softmmu/hw/i386/pc_piix.o
  CC      m68k-softmmu/fpu/hostfloat.o
  CC      i386-softmmu/hw/i386/pc_q35.o
  CC      m68k-softmmu/disas.o
  CC      i386-softmmu/hw/i386/pc_sysfw.o
  CC      microblazeel-softmmu/fpu/hostfloat.o
  GEN     m68k-softmmu/gdbstub-xml.c
  CC      i386-softmmu/hw/i386/x86-iommu.o
  CC      m68k-softmmu/arch_init.o
  CC      microblazeel-softmmu/disas.o
  CC      m68k-softmmu/cpus.o
  CC      i386-softmmu/hw/i386/intel_iommu.o
  CC      microblazeel-softmmu/arch_init.o
  CC      microblazeel-softmmu/cpus.o
  CC      m68k-softmmu/monitor.o
  CC      microblazeel-softmmu/monitor.o
  CC      i386-softmmu/hw/i386/amd_iommu.o
  CC      i386-softmmu/hw/i386/vmport.o
  CC      i386-softmmu/hw/i386/vmmouse.o
  CC      m68k-softmmu/gdbstub.o
  CC      i386-softmmu/hw/i386/kvmvapic.o
  CC      microblazeel-softmmu/gdbstub.o
  CC      m68k-softmmu/balloon.o
  CC      i386-softmmu/hw/i386/acpi-build.o
  CC      m68k-softmmu/ioport.o
  CC      microblazeel-softmmu/balloon.o
  CC      m68k-softmmu/numa.o
  CC      microblazeel-softmmu/ioport.o
  CC      m68k-softmmu/qtest.o
  CC      i386-softmmu/target/i386/helper.o
  CC      microblazeel-softmmu/numa.o
  CC      m68k-softmmu/memory.o
  CC      microblazeel-softmmu/qtest.o
  CC      i386-softmmu/target/i386/cpu.o
  CC      microblazeel-softmmu/memory.o
  CC      i386-softmmu/target/i386/gdbstub.o
  CC      i386-softmmu/target/i386/xsave_helper.o
  CC      m68k-softmmu/memory_mapping.o
  CC      i386-softmmu/target/i386/translate.o
  CC      m68k-softmmu/dump.o
  CC      microblazeel-softmmu/memory_mapping.o
  CC      microblazeel-softmmu/dump.o
  CC      m68k-softmmu/migration/ram.o
  CC      microblazeel-softmmu/migration/ram.o
  CC      m68k-softmmu/accel/accel.o
  CC      m68k-softmmu/accel/stubs/hax-stub.o
  CC      m68k-softmmu/accel/stubs/hvf-stub.o
  CC      microblazeel-softmmu/accel/accel.o
  CC      m68k-softmmu/accel/stubs/whpx-stub.o
  CC      microblazeel-softmmu/accel/stubs/hax-stub.o
  CC      m68k-softmmu/accel/stubs/kvm-stub.o
  CC      microblazeel-softmmu/accel/stubs/hvf-stub.o
  CC      m68k-softmmu/accel/tcg/tcg-all.o
  CC      microblazeel-softmmu/accel/stubs/whpx-stub.o
  CC      m68k-softmmu/accel/tcg/cputlb.o
  CC      microblazeel-softmmu/accel/stubs/kvm-stub.o
  CC      microblazeel-softmmu/accel/tcg/tcg-all.o
  CC      microblazeel-softmmu/accel/tcg/cputlb.o
  CC      m68k-softmmu/accel/tcg/tcg-runtime.o
  CC      m68k-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      microblazeel-softmmu/accel/tcg/tcg-runtime.o
  CC      microblazeel-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      m68k-softmmu/accel/tcg/cpu-exec.o
  CC      i386-softmmu/target/i386/bpt_helper.o
  CC      m68k-softmmu/accel/tcg/cpu-exec-common.o
  CC      microblazeel-softmmu/accel/tcg/cpu-exec.o
  CC      m68k-softmmu/accel/tcg/translate-all.o
  CC      i386-softmmu/target/i386/cc_helper.o
  CC      microblazeel-softmmu/accel/tcg/cpu-exec-common.o
  CC      i386-softmmu/target/i386/excp_helper.o
  CC      microblazeel-softmmu/accel/tcg/translate-all.o
  CC      m68k-softmmu/accel/tcg/translator.o
  CC      i386-softmmu/target/i386/fpu_helper.o
  CC      m68k-softmmu/hw/char/mcf_uart.o
  CC      microblazeel-softmmu/accel/tcg/translator.o
  CC      m68k-softmmu/hw/core/generic-loader.o
  CC      microblazeel-softmmu/hw/core/generic-loader.o
  CC      m68k-softmmu/hw/core/null-machine.o
  CC      microblazeel-softmmu/hw/core/null-machine.o
  CC      m68k-softmmu/hw/misc/mmio_interface.o
  CC      microblazeel-softmmu/hw/dma/xlnx_dpdma.o
  CC      m68k-softmmu/hw/net/mcf_fec.o
  CC      m68k-softmmu/hw/net/vhost_net.o
  CC      microblazeel-softmmu/hw/misc/mmio_interface.o
  CC      m68k-softmmu/hw/net/rocker/qmp-norocker.o
  CC      microblazeel-softmmu/hw/net/xilinx_ethlite.o
  CC      m68k-softmmu/hw/vfio/common.o
  CC      microblazeel-softmmu/hw/net/vhost_net.o
  CC      microblazeel-softmmu/hw/net/rocker/qmp-norocker.o
  CC      microblazeel-softmmu/hw/vfio/common.o
  CC      m68k-softmmu/hw/vfio/platform.o
  CC      i386-softmmu/target/i386/int_helper.o
  CC      i386-softmmu/target/i386/mem_helper.o
  CC      m68k-softmmu/hw/vfio/spapr.o
  CC      microblazeel-softmmu/hw/vfio/platform.o
  CC      i386-softmmu/target/i386/misc_helper.o
  CC      m68k-softmmu/hw/m68k/an5206.o
  CC      microblazeel-softmmu/hw/vfio/spapr.o
  CC      m68k-softmmu/hw/m68k/mcf5208.o
  CC      i386-softmmu/target/i386/mpx_helper.o
  CC      m68k-softmmu/hw/m68k/mcf5206.o
  CC      microblazeel-softmmu/hw/microblaze/petalogix_s3adsp1800_mmu.o
  CC      i386-softmmu/target/i386/seg_helper.o
  CC      microblazeel-softmmu/hw/microblaze/petalogix_ml605_mmu.o
  CC      m68k-softmmu/hw/m68k/mcf_intc.o
  CC      m68k-softmmu/target/m68k/m68k-semi.o
  CC      microblazeel-softmmu/hw/microblaze/xlnx-zynqmp-pmu.o
  CC      microblazeel-softmmu/hw/microblaze/boot.o
  CC      m68k-softmmu/target/m68k/translate.o
  CC      microblazeel-softmmu/target/microblaze/translate.o
  CC      i386-softmmu/target/i386/smm_helper.o
  CC      microblazeel-softmmu/target/microblaze/op_helper.o
  CC      i386-softmmu/target/i386/svm_helper.o
  CC      microblazeel-softmmu/target/microblaze/helper.o
  CC      microblazeel-softmmu/target/microblaze/cpu.o
  CC      i386-softmmu/target/i386/machine.o
  CC      microblazeel-softmmu/target/microblaze/gdbstub.o
  CC      i386-softmmu/target/i386/arch_memory_mapping.o
  CC      microblazeel-softmmu/target/microblaze/mmu.o
  CC      i386-softmmu/target/i386/arch_dump.o
  GEN     trace/generated-helpers.c
  CC      microblazeel-softmmu/trace/control-target.o
  CC      i386-softmmu/target/i386/monitor.o
  CC      microblazeel-softmmu/trace/generated-helpers.o
  CC      m68k-softmmu/target/m68k/op_helper.o
  CC      i386-softmmu/target/i386/kvm-stub.o
  LINK    microblazeel-softmmu/qemu-system-microblazeel
  CC      i386-softmmu/target/i386/sev-stub.o
  GEN     trace/generated-helpers.c
  CC      i386-softmmu/trace/control-target.o
  CC      i386-softmmu/gdbstub-xml.o
  CC      i386-softmmu/trace/generated-helpers.o
  CC      m68k-softmmu/target/m68k/helper.o
  LINK    i386-softmmu/qemu-system-i386
  CC      m68k-softmmu/target/m68k/cpu.o
  CC      m68k-softmmu/target/m68k/fpu_helper.o
make[1]: *** No rule to make target 'target/m68k/hostfloat.o', needed by 'qemu-system-m68k'.  Stop.
make[1]: *** Waiting for unfinished jobs....
  CC      m68k-softmmu/target/m68k/softfloat.o
  CC      arm-softmmu/hw/misc/imx6_ccm.o
  CC      arm-softmmu/hw/misc/imx6_src.o
  CC      arm-softmmu/hw/misc/imx7_ccm.o
  CC      arm-softmmu/hw/misc/imx2_wdt.o
  CC      arm-softmmu/hw/misc/imx7_snvs.o
  CC      arm-softmmu/hw/misc/imx7_gpr.o
  CC      arm-softmmu/hw/misc/mst_fpga.o
  CC      arm-softmmu/hw/misc/omap_clk.o
  CC      arm-softmmu/hw/misc/omap_gpmc.o
  CC      arm-softmmu/hw/misc/omap_l4.o
  CC      arm-softmmu/hw/misc/omap_sdrc.o
  CC      arm-softmmu/hw/misc/omap_tap.o
  CC      arm-softmmu/hw/misc/bcm2835_mbox.o
  CC      arm-softmmu/hw/misc/bcm2835_property.o
  CC      arm-softmmu/hw/misc/bcm2835_rng.o
  CC      arm-softmmu/hw/misc/zynq_slcr.o
  CC      arm-softmmu/hw/misc/zynq-xadc.o
  CC      arm-softmmu/hw/misc/stm32f2xx_syscfg.o
  CC      arm-softmmu/hw/misc/mps2-fpgaio.o
  CC      arm-softmmu/hw/misc/mps2-scc.o
  CC      arm-softmmu/hw/misc/tz-ppc.o
  CC      arm-softmmu/hw/misc/iotkit-secctl.o
  CC      arm-softmmu/hw/misc/aspeed_scu.o
  CC      arm-softmmu/hw/misc/aspeed_sdmc.o
  CC      arm-softmmu/hw/misc/mmio_interface.o
  CC      arm-softmmu/hw/misc/msf2-sysreg.o
  CC      arm-softmmu/hw/net/virtio-net.o
  CC      arm-softmmu/hw/net/vhost_net.o
  CC      arm-softmmu/hw/pcmcia/pxa2xx.o
  CC      arm-softmmu/hw/scsi/virtio-scsi.o
  CC      arm-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      arm-softmmu/hw/scsi/vhost-scsi-common.o
  CC      arm-softmmu/hw/scsi/vhost-scsi.o
  CC      arm-softmmu/hw/scsi/vhost-user-scsi.o
  CC      arm-softmmu/hw/sd/omap_mmc.o
  CC      arm-softmmu/hw/sd/pxa2xx_mmci.o
  CC      arm-softmmu/hw/sd/bcm2835_sdhost.o
  CC      arm-softmmu/hw/ssi/omap_spi.o
  CC      arm-softmmu/hw/ssi/imx_spi.o
  CC      arm-softmmu/hw/timer/exynos4210_mct.o
  CC      arm-softmmu/hw/timer/exynos4210_pwm.o
  CC      arm-softmmu/hw/timer/exynos4210_rtc.o
  CC      arm-softmmu/hw/timer/omap_gptimer.o
  CC      arm-softmmu/hw/timer/omap_synctimer.o
  CC      arm-softmmu/hw/timer/pxa2xx_timer.o
  CC      arm-softmmu/hw/timer/digic-timer.o
  CC      arm-softmmu/hw/timer/allwinner-a10-pit.o
  CC      arm-softmmu/hw/usb/tusb6010.o
  CC      arm-softmmu/hw/usb/chipidea.o
  CC      arm-softmmu/hw/vfio/common.o
  CC      arm-softmmu/hw/vfio/pci.o
  CC      arm-softmmu/hw/vfio/pci-quirks.o
  CC      arm-softmmu/hw/vfio/display.o
  CC      arm-softmmu/hw/vfio/platform.o
  CC      arm-softmmu/hw/vfio/calxeda-xgmac.o
  CC      arm-softmmu/hw/vfio/amd-xgbe.o
  CC      arm-softmmu/hw/vfio/spapr.o
  CC      arm-softmmu/hw/virtio/virtio.o
  CC      arm-softmmu/hw/virtio/virtio-balloon.o
  CC      arm-softmmu/hw/virtio/vhost.o
  CC      arm-softmmu/hw/virtio/vhost-backend.o
  CC      arm-softmmu/hw/virtio/vhost-user.o
  CC      arm-softmmu/hw/virtio/vhost-vsock.o
  CC      arm-softmmu/hw/virtio/virtio-crypto.o
  CC      arm-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      arm-softmmu/hw/arm/boot.o
  CC      arm-softmmu/hw/arm/virt.o
  CC      arm-softmmu/hw/arm/sysbus-fdt.o
  CC      arm-softmmu/hw/arm/virt-acpi-build.o
  CC      arm-softmmu/hw/arm/digic_boards.o
  CC      arm-softmmu/hw/arm/exynos4_boards.o
  CC      arm-softmmu/hw/arm/highbank.o
  CC      arm-softmmu/hw/arm/integratorcp.o
  CC      arm-softmmu/hw/arm/mainstone.o
  CC      arm-softmmu/hw/arm/musicpal.o
  CC      arm-softmmu/hw/arm/netduino2.o
  CC      arm-softmmu/hw/arm/nseries.o
  CC      arm-softmmu/hw/arm/omap_sx1.o
  CC      arm-softmmu/hw/arm/palm.o
  CC      arm-softmmu/hw/arm/gumstix.o
  CC      arm-softmmu/hw/arm/spitz.o
  CC      arm-softmmu/hw/arm/tosa.o
  CC      arm-softmmu/hw/arm/z2.o
  CC      arm-softmmu/hw/arm/realview.o
  CC      arm-softmmu/hw/arm/stellaris.o
  CC      arm-softmmu/hw/arm/collie.o
  CC      arm-softmmu/hw/arm/vexpress.o
  CC      arm-softmmu/hw/arm/versatilepb.o
  CC      arm-softmmu/hw/arm/xilinx_zynq.o
  CC      arm-softmmu/hw/arm/armv7m.o
  CC      arm-softmmu/hw/arm/exynos4210.o
  CC      arm-softmmu/hw/arm/pxa2xx.o
  CC      arm-softmmu/hw/arm/pxa2xx_gpio.o
  CC      arm-softmmu/hw/arm/pxa2xx_pic.o
  CC      arm-softmmu/hw/arm/digic.o
  CC      arm-softmmu/hw/arm/omap1.o
  CC      arm-softmmu/hw/arm/omap2.o
  CC      arm-softmmu/hw/arm/strongarm.o
  CC      arm-softmmu/hw/arm/allwinner-a10.o
  CC      arm-softmmu/hw/arm/cubieboard.o
  CC      arm-softmmu/hw/arm/bcm2835_peripherals.o
  CC      arm-softmmu/hw/arm/bcm2836.o
  CC      arm-softmmu/hw/arm/raspi.o
  CC      arm-softmmu/hw/arm/stm32f205_soc.o
  CC      arm-softmmu/hw/arm/fsl-imx25.o
  CC      arm-softmmu/hw/arm/imx25_pdk.o
  CC      arm-softmmu/hw/arm/fsl-imx31.o
  CC      arm-softmmu/hw/arm/kzm.o
  CC      arm-softmmu/hw/arm/fsl-imx6.o
  CC      arm-softmmu/hw/arm/sabrelite.o
  CC      arm-softmmu/hw/arm/aspeed_soc.o
  CC      arm-softmmu/hw/arm/aspeed.o
  CC      arm-softmmu/hw/arm/mps2.o
  CC      arm-softmmu/hw/arm/mps2-tz.o
  CC      arm-softmmu/hw/arm/msf2-soc.o
  CC      arm-softmmu/hw/arm/msf2-som.o
  CC      arm-softmmu/hw/arm/iotkit.o
  CC      arm-softmmu/hw/arm/fsl-imx7.o
  CC      arm-softmmu/hw/arm/mcimx7d-sabre.o
  CC      arm-softmmu/target/arm/arm-semi.o
  CC      arm-softmmu/target/arm/machine.o
  CC      arm-softmmu/target/arm/psci.o
  CC      arm-softmmu/target/arm/arch_dump.o
  CC      arm-softmmu/target/arm/monitor.o
  CC      arm-softmmu/target/arm/kvm-stub.o
  CC      arm-softmmu/target/arm/translate.o
  CC      arm-softmmu/target/arm/op_helper.o
  CC      arm-softmmu/target/arm/helper.o
  CC      arm-softmmu/target/arm/cpu.o
  CC      arm-softmmu/target/arm/neon_helper.o
  CC      arm-softmmu/target/arm/iwmmxt_helper.o
  CC      arm-softmmu/target/arm/vec_helper.o
  CC      arm-softmmu/target/arm/gdbstub.o
  CC      arm-softmmu/target/arm/crypto_helper.o
  CC      arm-softmmu/target/arm/arm-powerctl.o
  GEN     trace/generated-helpers.c
  CC      arm-softmmu/trace/control-target.o
  CC      arm-softmmu/gdbstub-xml.o
  CC      arm-softmmu/trace/generated-helpers.o
make: *** [Makefile:478: subdir-m68k-softmmu] Error 2
make: *** Waiting for unfinished jobs....
  LINK    arm-softmmu/qemu-system-arm
  GEN     microblaze-softmmu/hmp-commands.h
  GEN     microblaze-softmmu/hmp-commands-info.h
  GEN     microblaze-softmmu/config-target.h
  CC      microblaze-softmmu/exec.o
  CC      microblaze-softmmu/tcg/tcg.o
  CC      microblaze-softmmu/tcg/tcg-op.o
  CC      microblaze-softmmu/tcg/tcg-op-vec.o
  CC      microblaze-softmmu/tcg/tcg-op-gvec.o
  CC      microblaze-softmmu/tcg/tcg-common.o
  CC      microblaze-softmmu/tcg/optimize.o
  CC      microblaze-softmmu/fpu/softfloat.o
  CC      microblaze-softmmu/fpu/hostfloat.o
  CC      microblaze-softmmu/disas.o
  CC      microblaze-softmmu/arch_init.o
  CC      microblaze-softmmu/cpus.o
  CC      microblaze-softmmu/monitor.o
  CC      microblaze-softmmu/gdbstub.o
  CC      microblaze-softmmu/balloon.o
  CC      microblaze-softmmu/ioport.o
  CC      microblaze-softmmu/numa.o
  CC      microblaze-softmmu/qtest.o
  CC      microblaze-softmmu/memory.o
  CC      microblaze-softmmu/memory_mapping.o
  CC      microblaze-softmmu/dump.o
  CC      microblaze-softmmu/migration/ram.o
  CC      microblaze-softmmu/accel/accel.o
  CC      microblaze-softmmu/accel/stubs/hax-stub.o
  CC      microblaze-softmmu/accel/stubs/hvf-stub.o
  CC      microblaze-softmmu/accel/stubs/whpx-stub.o
  CC      microblaze-softmmu/accel/stubs/kvm-stub.o
  CC      microblaze-softmmu/accel/tcg/tcg-all.o
  CC      microblaze-softmmu/accel/tcg/cputlb.o
  CC      microblaze-softmmu/accel/tcg/tcg-runtime.o
  CC      microblaze-softmmu/accel/tcg/tcg-runtime-gvec.o
  CC      microblaze-softmmu/accel/tcg/cpu-exec.o
  CC      microblaze-softmmu/accel/tcg/cpu-exec-common.o
  CC      microblaze-softmmu/accel/tcg/translate-all.o
  CC      microblaze-softmmu/accel/tcg/translator.o
  CC      microblaze-softmmu/hw/core/generic-loader.o
  CC      microblaze-softmmu/hw/core/null-machine.o
  CC      microblaze-softmmu/hw/dma/xlnx_dpdma.o
  CC      microblaze-softmmu/hw/misc/mmio_interface.o
  CC      microblaze-softmmu/hw/net/xilinx_ethlite.o
  CC      microblaze-softmmu/hw/net/vhost_net.o
  CC      microblaze-softmmu/hw/net/rocker/qmp-norocker.o
  CC      microblaze-softmmu/hw/vfio/common.o
  CC      microblaze-softmmu/hw/vfio/platform.o
  CC      microblaze-softmmu/hw/vfio/spapr.o
  CC      microblaze-softmmu/hw/microblaze/petalogix_s3adsp1800_mmu.o
  CC      microblaze-softmmu/hw/microblaze/petalogix_ml605_mmu.o
  CC      microblaze-softmmu/hw/microblaze/xlnx-zynqmp-pmu.o
  CC      microblaze-softmmu/hw/microblaze/boot.o
  CC      microblaze-softmmu/target/microblaze/translate.o
  CC      microblaze-softmmu/target/microblaze/op_helper.o
  CC      microblaze-softmmu/target/microblaze/helper.o
  CC      microblaze-softmmu/target/microblaze/cpu.o
  CC      microblaze-softmmu/target/microblaze/gdbstub.o
  CC      microblaze-softmmu/target/microblaze/mmu.o
  GEN     trace/generated-helpers.c
  CC      microblaze-softmmu/trace/control-target.o
  CC      microblaze-softmmu/trace/generated-helpers.o
  LINK    microblaze-softmmu/qemu-system-microblaze
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat Emilio G. Cota
@ 2018-03-21 20:41   ` Laurent Vivier
  2018-03-21 21:45     ` Emilio G. Cota
  2018-03-27 11:49   ` Alex Bennée
  1 sibling, 1 reply; 46+ messages in thread
From: Laurent Vivier @ 2018-03-21 20:41 UTC (permalink / raw)
  To: Emilio G. Cota, qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

Le 21/03/2018 à 21:11, Emilio G. Cota a écrit :
> The appended paves the way for leveraging the host FPU for a subset
> of guest FP operations. For most guest workloads (e.g. FP flags
> aren't ever cleared, inexact occurs often and rounding is set to the
> default [to nearest]) this will yield sizable performance speedups.
> 
> The approach followed here avoids checking the FP exception flags register.
> See the comment at the top of hostfloat.c for details.
> 
> This assumes that QEMU is running on an IEEE754-compliant FPU and
> that the rounding is set to the default (to nearest). The
> implementation-dependent specifics of the FPU should not matter; things
> like tininess detection and snan representation are still dealt with in
> soft-fp. However, this approach will break on most hosts if we compile
> QEMU with flags such as -ffast-math. We control the flags so this should
> be easy to enforce though.
> 
> The licensing in softfloat.h is complicated at best, so to keep things
> simple I'm adding this as a separate, GPL'ed file.
> 
> This patch just adds some boilerplate code; subsequent patches add
> operations, one per commit to ease bisection.
> 
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  Makefile.target           |  2 +-
>  include/fpu/hostfloat.h   | 14 +++++++
>  include/fpu/softfloat.h   |  1 +
>  fpu/hostfloat.c           | 96 +++++++++++++++++++++++++++++++++++++++++++++++
>  target/m68k/Makefile.objs |  2 +-
>  tests/fp-test/Makefile    |  2 +-
>  6 files changed, 114 insertions(+), 3 deletions(-)
>  create mode 100644 include/fpu/hostfloat.h
>  create mode 100644 fpu/hostfloat.c
> 
...
> diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
> index ac61948..2868b11 100644
> --- a/target/m68k/Makefile.objs
> +++ b/target/m68k/Makefile.objs
> @@ -1,5 +1,5 @@
>  obj-y += m68k-semi.o
>  obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += fpu_helper.o softfloat.o
> +obj-y += fpu_helper.o softfloat.o hostfloat.o

I don't think you need to add hostfloat.o here,
the softfloat.o in this list contains function specific to m68k
emulation, it's not the one from fpu/

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat
  2018-03-21 20:41   ` Laurent Vivier
@ 2018-03-21 21:45     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-21 21:45 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Wed, Mar 21, 2018 at 21:41:19 +0100, Laurent Vivier wrote:
> Le 21/03/2018 à 21:11, Emilio G. Cota a écrit :
> > diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
> > index ac61948..2868b11 100644
> > --- a/target/m68k/Makefile.objs
> > +++ b/target/m68k/Makefile.objs
> > @@ -1,5 +1,5 @@
> >  obj-y += m68k-semi.o
> >  obj-y += translate.o op_helper.o helper.o cpu.o
> > -obj-y += fpu_helper.o softfloat.o
> > +obj-y += fpu_helper.o softfloat.o hostfloat.o
> 
> I don't think you need to add hostfloat.o here,
> the softfloat.o in this list contains function specific to m68k
> emulation, it's not the one from fpu/

Aah yes indeed. Didn't consider there might be another softfloat.c =)

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root Emilio G. Cota
@ 2018-03-22  1:29   ` Alex Bennée
  2018-03-22  4:02     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-22  1:29 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> Performance results for fp-bench run under aarch64-linux-user
> on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:
>
> - before:
> sqrt-single: 13.23 MFlops
> sqrt-double: 13.24 MFlops
>
> - after:
> sqrt-single: 15.02 MFlops
> sqrt-double: 15.07 MFlops
>
> Note that sqrt in soft-ft is relatively fast, which means
> that fp-bench is not very sensitive to changes to sqrt's
> emulation speed.

Weird, I thought we had slowed it down quite a bit in the re-factor as
we eschewed the estimate step for an easier to read but slower iterative
process. That's why I chose sqrt for my hostfp hack experiment.

>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  include/fpu/hostfloat.h |  2 ++
>  include/fpu/softfloat.h |  4 ++--
>  fpu/hostfloat.c         | 20 ++++++++++++++++++++
>  fpu/softfloat.c         |  6 ++++--
>  4 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
> index c006576..b1e0689 100644
> --- a/include/fpu/hostfloat.h
> +++ b/include/fpu/hostfloat.h
> @@ -16,11 +16,13 @@ float32 float32_sub(float32 a, float32 b, float_status *status);
>  float32 float32_mul(float32 a, float32 b, float_status *status);
>  float32 float32_div(float32 a, float32 b, float_status *status);
>  float32 float32_muladd(float32 a, float32 b, float32 c, int f, float_status *s);
> +float32 float32_sqrt(float32 a, float_status *status);
>
>  float64 float64_add(float64 a, float64 b, float_status *status);
>  float64 float64_sub(float64 a, float64 b, float_status *status);
>  float64 float64_mul(float64 a, float64 b, float_status *status);
>  float64 float64_div(float64 a, float64 b, float_status *status);
>  float64 float64_muladd(float64 a, float64 b, float64 c, int f, float_status *s);
> +float64 float64_sqrt(float64 a, float_status *status);
>
>  #endif /* HOSTFLOAT_H */
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 866bd3b..8d5a50a 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -348,7 +348,7 @@ float32 soft_float32_mul(float32, float32, float_status *status);
>  float32 soft_float32_div(float32, float32, float_status *status);
>  float32 float32_rem(float32, float32, float_status *status);
>  float32 soft_float32_muladd(float32, float32, float32, int, float_status *s);
> -float32 float32_sqrt(float32, float_status *status);
> +float32 soft_float32_sqrt(float32, float_status *status);
>  float32 float32_exp2(float32, float_status *status);
>  float32 float32_log2(float32, float_status *status);
>  int float32_eq(float32, float32, float_status *status);
> @@ -488,7 +488,7 @@ float64 soft_float64_mul(float64, float64, float_status *status);
>  float64 soft_float64_div(float64, float64, float_status *status);
>  float64 float64_rem(float64, float64, float_status *status);
>  float64 soft_float64_muladd(float64, float64, float64, int, float_status *s);
> -float64 float64_sqrt(float64, float_status *status);
> +float64 soft_float64_sqrt(float64, float_status *status);
>  float64 float64_log2(float64, float_status *status);
>  int float64_eq(float64, float64, float_status *status);
>  int float64_le(float64, float64, float_status *status);
> diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
> index a56b70a..974bd57 100644
> --- a/fpu/hostfloat.c
> +++ b/fpu/hostfloat.c
> @@ -270,3 +270,23 @@ GEN_FPU_DIV(float64_div, float64, double, fabs, DBL_MIN)
>  GEN_FPU_FMA(float32_muladd, float32, float, fmaf, fabsf, FLT_MIN)
>  GEN_FPU_FMA(float64_muladd, float64, double, fma, fabs, DBL_MIN)
>  #undef GEN_FPU_FMA
> +
> +#define GEN_FPU_SQRT(name, soft_t, host_t, host_sqrt_func)              \
> +    soft_t name(soft_t a, float_status *s)                              \
> +    {                                                                   \
> +        soft_t ## _input_flush1(&a, s);                                 \
> +        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
> +                   !soft_t ## _is_neg(a) &&                             \
> +                   s->float_exception_flags & float_flag_inexact &&     \
> +                   s->float_rounding_mode == float_round_nearest_even)) { \
> +            host_t ha = soft_t ## _to_ ## host_t(a);                    \
> +            host_t hr = host_sqrt_func(ha);                             \
> +                                                                        \
> +            return host_t ## _to_ ## soft_t(hr);                        \
> +        }                                                               \
> +        return soft_ ## soft_t ## _sqrt(a, s);                          \
> +    }
> +
> +GEN_FPU_SQRT(float32_sqrt, float32, float, sqrtf)
> +GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt)
> +#undef GEN_FPU_SQRT
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index da81ec9..096b658 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -1980,14 +1980,16 @@ float16 __attribute__((flatten)) float16_sqrt(float16 a, float_status *status)
>      return float16_round_pack_canonical(pr, status);
>  }
>
> -float32 __attribute__((flatten)) float32_sqrt(float32 a, float_status *status)
> +float32 __attribute__((flatten))
> +soft_float32_sqrt(float32 a, float_status *status)
>  {
>      FloatParts pa = float32_unpack_canonical(a, status);
>      FloatParts pr = sqrt_float(pa, status, &float32_params);
>      return float32_round_pack_canonical(pr, status);
>  }
>
> -float64 __attribute__((flatten)) float64_sqrt(float64 a, float_status *status)
> +float64 __attribute__((flatten))
> +soft_float64_sqrt(float64 a, float_status *status)
>  {
>      FloatParts pa = float64_unpack_canonical(a, status);
>      FloatParts pr = sqrt_float(pa, status, &float64_params);


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root
  2018-03-22  1:29   ` Alex Bennée
@ 2018-03-22  4:02     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-22  4:02 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Thu, Mar 22, 2018 at 01:29:23 +0000, Alex Bennée wrote:
> Emilio G. Cota <cota@braap.org> writes:
> 
> > Performance results for fp-bench run under aarch64-linux-user
> > on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:
> >
> > - before:
> > sqrt-single: 13.23 MFlops
> > sqrt-double: 13.24 MFlops
> >
> > - after:
> > sqrt-single: 15.02 MFlops
> > sqrt-double: 15.07 MFlops
> >
> > Note that sqrt in soft-ft is relatively fast, which means
> > that fp-bench is not very sensitive to changes to sqrt's
> > emulation speed.
> 
> Weird, I thought we had slowed it down quite a bit in the re-factor as
> we eschewed the estimate step for an easier to read but slower iterative
> process. That's why I chose sqrt for my hostfp hack experiment.

Yes, my first statement ("soft-ft is relatively fast") is
wrong. Sorry about that, I thought I had deleted it but it
slipped through.

What I should have said (but decided against to keep the commit log
short) is that fp-bench doesn't do a good job in being sensitive
to the performance of the sqrt instruction, so even if got it
to take 0 time we'd still get a small speedup.

Just realised that this happens because ~50% of the inputs are
negative, which will go through some very slow paths. This ends
up showing in perf like this:

# Overhead  Command   Shared Object      Symbol
# ........  ........  .................  ...........................
#
    61.74%  fp-bench  fp-bench           [.] main
    22.58%  fp-bench  libm-2.23.so       [.] __kernel_standard
     6.22%  fp-bench  libm-2.23.so       [.] __kernel_standard_f
     5.21%  fp-bench  libm-2.23.so       [.] __sqrtf
     2.17%  fp-bench  fp-bench           [.] _init
     1.91%  fp-bench  [kernel.kallsyms]  [k] __call_rcu.constprop.70
     0.18%  fp-bench  [kernel.kallsyms]  [k] cpumask_any_but
     0.01%  perf      [kernel.kallsyms]  [k] native_iret
     0.00%  perf      [kernel.kallsyms]  [k] native_write_msr_safe

__sqrtf (which does 'sqrtss %xmm0,%xmm0') only takes 5% of the time!

I just fixed fp-bench to discard negative inputs. This looks
much better: (Note that this is fp-test-x86_64 instead of -aarch64,
which explains why the "before" throughput is different than
the one reported above)

[...]
+fma: (patch 11, i.e. sqrt still in soft-fp)
sqrt-single: 27.11 MFlops
sqrt-double: 27.17 MFlops
+sqrt: (12)
sqrt-single: 66.67 MFlops
sqrt-double: 66.79 MFlops
+cmp: (13)
sqrt-single: 126.46 MFlops
sqrt-double: 126.06 MFlops
+f32f64: (patch 14)
sqrt-single: 122.75 MFlops
sqrt-double: 126.57 MFlops

We get a >2x speedup, which is consistent with the fact
that now perf shows that sqrt takes ~60% of execution time.

Compare does matter here as well because libm is checking
sqrt's result against NaN.

I'll include this fix to fp-bench in v2.

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (14 preceding siblings ...)
  2018-03-21 20:36 ` [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat no-reply
@ 2018-03-22  5:02 ` no-reply
  2018-03-22  8:56 ` Alex Bennée
  16 siblings, 0 replies; 46+ messages in thread
From: no-reply @ 2018-03-22  5:02 UTC (permalink / raw)
  To: cota
  Cc: famz, qemu-devel, peter.maydell, mark.cave-ayland,
	richard.henderson, laurent, pbonzini, alex.bennee, aurelien

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1521663109-32262-1-git-send-email-cota@braap.org
Subject: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
2776883619 hostfloat: support float32_to_float64
dbb0c2a60b hostfloat: support float32/64 comparison
b21bd8b75d hostfloat: support float32/64 square root
40b1723ab1 hostfloat: support float32/64 fused multiply-add
d1ff4b2bcd hostfloat: support float32/64 division
6622d46dfe hostfloat: support float32/64 multiplication
a2e1f5e4c7 hostfloat: support float32/64 addition and subtraction
d25f954555 fpu: introduce hostfloat
4356927b54 softfloat: add float32_is_denormal and float64_is_denormal
4ceef15bf5 softfloat: add float32_is_normal and float64_is_normal
30f0f71fd2 fp-test: add muladd variants
ac7bd8e7f7 softfloat: fix {min, max}nummag for same-abs-value inputs
72f8541c7c tests: add fp-test, a floating point test suite
5718f9fdf4 tests: add fp-bench, a collection of simple floating-point microbenchmarks

=== OUTPUT BEGIN ===
Checking PATCH 1/14: tests: add fp-bench, a collection of simple floating-point microbenchmarks...
ERROR: braces {} are necessary for all arms of this statement
#165: FILE: tests/fp-bench.c:114:
+    } while (!u32_is_normal(r));
[...]

ERROR: braces {} are necessary for all arms of this statement
#177: FILE: tests/fp-bench.c:126:
+    } while (!u64_is_normal(r));
[...]

ERROR: spaces required around that '*' (ctx:WxV)
#187: FILE: tests/fp-bench.c:136:
+    static void NAME(volatile PRECISION *res)                           \
                                         ^

ERROR: Use of volatile is usually wrong, please add a comment
#187: FILE: tests/fp-bench.c:136:
+    static void NAME(volatile PRECISION *res)                           \

ERROR: Use of volatile is usually wrong, please add a comment
#193: FILE: tests/fp-bench.c:142:
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \

ERROR: Use of volatile is usually wrong, please add a comment
#206: FILE: tests/fp-bench.c:155:
+    static void NAME(volatile PRECISION *res)                           \

ERROR: Use of volatile is usually wrong, please add a comment
#213: FILE: tests/fp-bench.c:162:
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \

ERROR: Use of volatile is usually wrong, please add a comment
#214: FILE: tests/fp-bench.c:163:
+            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \

ERROR: Use of volatile is usually wrong, please add a comment
#233: FILE: tests/fp-bench.c:182:
+    static void NAME(volatile PRECISION *res)                           \

ERROR: Use of volatile is usually wrong, please add a comment
#241: FILE: tests/fp-bench.c:190:
+            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \

ERROR: Use of volatile is usually wrong, please add a comment
#242: FILE: tests/fp-bench.c:191:
+            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \

ERROR: Use of volatile is usually wrong, please add a comment
#243: FILE: tests/fp-bench.c:192:
+            volatile PRECISION c = glue(get_random_, PRECISION)(&rc);   \

ERROR: braces {} are necessary for all arms of this statement
#315: FILE: tests/fp-bench.c:264:
+    } while (0)
[...]

total: 13 errors, 0 warnings, 312 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 2/14: tests: add fp-test, a floating point test suite...
ERROR: Macros with complex values should be enclosed in parenthesis
#378: FILE: tests/fp-test/fp-test.c:220:
+#define PR_EXCEPTIONS(x)                                \
+        ((x) & STANDARD_EXCEPTIONS ? "" : "none"),      \
+        (((x) & float_flag_inexact)   ? "x" : ""),      \
+        (((x) & float_flag_underflow) ? "u" : ""),      \
+        (((x) & float_flag_overflow)  ? "o" : ""),      \
+        (((x) & float_flag_divbyzero) ? "z" : ""),      \
+        (((x) & float_flag_invalid)   ? "i" : "")

ERROR: consider using qemu_strtoul in preference to strtoul
#839: FILE: tests/fp-test/fp-test.c:681:
+            significand = strtoul(&p[3], &pos, 16);

ERROR: consider using qemu_strtol in preference to strtol
#844: FILE: tests/fp-test/fp-test.c:686:
+            exponent = strtol(pos, &pos, 10) + 127;

ERROR: consider using qemu_strtoul in preference to strtoul
#869: FILE: tests/fp-test/fp-test.c:711:
+            significand = strtoul(&p[3], &pos, 16);

ERROR: consider using qemu_strtol in preference to strtol
#874: FILE: tests/fp-test/fp-test.c:716:
+            exponent = strtol(pos, &pos, 10) + 1023;

ERROR: consider using qemu_strtof in preference to strtof
#893: FILE: tests/fp-test/fp-test.c:735:
+            float f = strtof(p, &pos);

total: 6 errors, 0 warnings, 1216 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/14: softfloat: fix {min, max}nummag for same-abs-value inputs...
Checking PATCH 4/14: fp-test: add muladd variants...
Checking PATCH 5/14: softfloat: add float32_is_normal and float64_is_normal...
Checking PATCH 6/14: softfloat: add float32_is_denormal and float64_is_denormal...
Checking PATCH 7/14: fpu: introduce hostfloat...
ERROR: spaces required around that '*' (ctx:WxV)
#103: FILE: fpu/hostfloat.c:54:
+    soft_t ## _input_flush__nocheck(soft_t *a, float_status *s)         \
                                                             ^

ERROR: spaces required around that '*' (ctx:WxV)
#113: FILE: fpu/hostfloat.c:64:
+    soft_t ## _input_flush1(soft_t *a, float_status *s)                 \
                                                     ^

ERROR: spaces required around that '*' (ctx:WxV)
#122: FILE: fpu/hostfloat.c:73:
+    soft_t ## _input_flush2(soft_t *a, soft_t *b, float_status *s)      \
                                                                ^

ERROR: spaces required around that '*' (ctx:WxV)
#133: FILE: fpu/hostfloat.c:84:
+                            float_status *s)                            \
                                          ^

total: 4 errors, 0 warnings, 139 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 8/14: hostfloat: support float32/64 addition and subtraction...
ERROR: spaces required around that '*' (ctx:WxV)
#38: FILE: fpu/hostfloat.c:102:
+                              float_status *s)                          \
                                            ^

total: 1 errors, 0 warnings, 123 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/14: hostfloat: support float32/64 multiplication...
ERROR: spaces required around that '*' (ctx:WxV)
#33: FILE: fpu/hostfloat.c:149:
+    soft_t name(soft_t a, soft_t b, float_status *s)                    \
                                                  ^

total: 1 errors, 0 warnings, 83 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/14: hostfloat: support float32/64 division...
ERROR: spaces required around that '*' (ctx:WxV)
#30: FILE: fpu/hostfloat.c:183:
+    soft_t name(soft_t a, soft_t b, float_status *s)                    \
                                                  ^

total: 1 errors, 0 warnings, 74 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 11/14: hostfloat: support float32/64 fused multiply-add...
ERROR: spaces required around that '*' (ctx:WxV)
#37: FILE: fpu/hostfloat.c:215:
+    soft_t name(soft_t a, soft_t b, soft_t c, int flags, float_status *s) \
                                                                       ^

total: 1 errors, 0 warnings, 117 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 12/14: hostfloat: support float32/64 square root...
ERROR: spaces required around that '*' (ctx:WxV)
#34: FILE: fpu/hostfloat.c:275:
+    soft_t name(soft_t a, float_status *s)                              \
                                        ^

total: 1 errors, 0 warnings, 70 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 13/14: hostfloat: support float32/64 comparison...
ERROR: spaces required around that '*' (ctx:WxV)
#22: FILE: fpu/hostfloat.c:296:
+    fpu_ ## name(soft_t a, soft_t b, bool is_quiet, float_status *s)    \
                                                                  ^

ERROR: storage class should be at the beginning of the declaration
#87: FILE: fpu/softfloat.c:1861:
+COMPARE(static, 16)

total: 2 errors, 0 warnings, 120 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 14/14: hostfloat: support float32_to_float64...
ERROR: spaces required around that '*' (ctx:WxV)
#114: FILE: fpu/hostfloat.c:330:
+float64 float32_to_float64(float32 a, float_status *status)
                                                    ^

total: 1 errors, 0 warnings, 39 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction Emilio G. Cota
@ 2018-03-22  5:05   ` Richard Henderson
  2018-03-22  5:57     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Richard Henderson @ 2018-03-22  5:05 UTC (permalink / raw)
  To: Emilio G. Cota, qemu-devel
  Cc: Aurelien Jarno, Peter Maydell, Alex Bennée, Laurent Vivier,
	Paolo Bonzini, Mark Cave-Ayland

On 03/22/2018 04:11 AM, Emilio G. Cota wrote:
> +#define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
> +                       host_abs_func, min_normal)                       \
> +    static inline __attribute__((always_inline)) soft_t                 \
> +    fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,        \
> +                              float_status *s)                          \
> +    {                                                                   \
> +        soft_t ## _input_flush2(&a, &b, s);                             \
> +        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
> +                   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
> +                   s->float_exception_flags & float_flag_inexact &&     \
> +                   s->float_rounding_mode == float_round_nearest_even)) { \
> +            host_t ha = soft_t ## _to_ ## host_t(a);                    \
> +            host_t hb = soft_t ## _to_ ## host_t(b);                    \
> +            host_t hr;                                                  \
> +            soft_t r;                                                   \
> +                                                                        \
> +            if (subtract) {                                             \
> +                hb = -hb;                                               \
> +            }                                                           \
> +            hr = ha + hb;                                               \
> +            r = host_t ## _to_ ## soft_t(hr);                           \
> +            if (unlikely(soft_t ## _is_infinity(r))) {                  \
> +                s->float_exception_flags |= float_flag_overflow;        \
> +            } else if (unlikely(host_abs_func(hr) <= min_normal)) {     \
> +                goto soft;                                              \
> +            }                                                           \
> +            return r;                                                   \
> +        }                                                               \
> +    soft:                                                               \

Is there any especially good reason you want to not put this code into the
normal softfloat function?  Does it really many any measurable difference at
all to force this code to be inlined into a helper?


r~

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22  5:05   ` Richard Henderson
@ 2018-03-22  5:57     ` Emilio G. Cota
  2018-03-22  6:41       ` Richard Henderson
  0 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-22  5:57 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland

On Thu, Mar 22, 2018 at 13:05:00 +0800, Richard Henderson wrote:
> On 03/22/2018 04:11 AM, Emilio G. Cota wrote:
> > +#define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
> > +                       host_abs_func, min_normal)                       \
> > +    static inline __attribute__((always_inline)) soft_t                 \
> > +    fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,        \
> > +                              float_status *s)                          \
> > +    {                                                                   \
> > +        soft_t ## _input_flush2(&a, &b, s);                             \
> > +        if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
> > +                   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
> > +                   s->float_exception_flags & float_flag_inexact &&     \
> > +                   s->float_rounding_mode == float_round_nearest_even)) { \
> > +            host_t ha = soft_t ## _to_ ## host_t(a);                    \
> > +            host_t hb = soft_t ## _to_ ## host_t(b);                    \
> > +            host_t hr;                                                  \
> > +            soft_t r;                                                   \
> > +                                                                        \
> > +            if (subtract) {                                             \
> > +                hb = -hb;                                               \
> > +            }                                                           \
> > +            hr = ha + hb;                                               \
> > +            r = host_t ## _to_ ## soft_t(hr);                           \
> > +            if (unlikely(soft_t ## _is_infinity(r))) {                  \
> > +                s->float_exception_flags |= float_flag_overflow;        \
> > +            } else if (unlikely(host_abs_func(hr) <= min_normal)) {     \
> > +                goto soft;                                              \
> > +            }                                                           \
> > +            return r;                                                   \
> > +        }                                                               \
> > +    soft:                                                               \
> 
> Is there any especially good reason you want to not put this code into the
> normal softfloat function?  Does it really many any measurable difference at
> all to force this code to be inlined into a helper?

You mean to do this? (... or see below)

--- a/fpu/hostfloat.c
+++ b/fpu/hostfloat.c
@@ -97,7 +97,7 @@ GEN_INPUT_FLUSH(float64)

 #define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
                        host_abs_func, min_normal)                       \
-    static inline __attribute__((always_inline)) soft_t                 \
+    static soft_t                                                       \
     fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,        \
                               float_status *s)                          \
     {                                                                   \

That slows add/sub dramatically, because addsub is not inlined into
float32_add and float32_sub (that's an extra function call plus an
extra branch per emulated op).

For x86_64-linux-user/qemu-x86_64 tests/fp-bench -o add, the above gives
- before: 188.06 MFlops
- after:  117.56 MFlops



... or did you miss that fpu_##soft_t##_addsub is only called by
soft_t ## _add / sub, which are standalone? That is:

+#define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
+                       host_abs_func, min_normal)                       \
(...)
+    soft_t add_name(soft_t a, soft_t b, float_status *status)           \
+    {                                                                   \
+        return fpu_ ## soft_t ## _addsub(a, b, false, status);          \
+    }                                                                   \
+                                                                        \
+    soft_t sub_name(soft_t a, soft_t b, float_status *status)           \
+    {                                                                   \
+        return fpu_ ## soft_t ## _addsub(a, b, true, status);           \
+    } 
+
+GEN_FPU_ADDSUB(float32_add, float32_sub, float32, float, fabsf, FLT_MIN)
+GEN_FPU_ADDSUB(float64_add, float64_sub, float64, double, fabs, DBL_MIN)
+#undef GEN_FPU_ADDSUB

Note that add/sub_name expand to float32/64_add/sub; I like having
the full names in the macro to ease grepping.

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22  5:57     ` Emilio G. Cota
@ 2018-03-22  6:41       ` Richard Henderson
  2018-03-22 15:08         ` Emilio G. Cota
  2018-03-22 19:57         ` Emilio G. Cota
  0 siblings, 2 replies; 46+ messages in thread
From: Richard Henderson @ 2018-03-22  6:41 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland

On 03/22/2018 01:57 PM, Emilio G. Cota wrote:
>> Is there any especially good reason you want to not put this code into the
>> normal softfloat function?  Does it really many any measurable difference at
>> all to force this code to be inlined into a helper?
> 
> You mean to do this? (... or see below)
> 
> --- a/fpu/hostfloat.c
> +++ b/fpu/hostfloat.c
> @@ -97,7 +97,7 @@ GEN_INPUT_FLUSH(float64)
> 
>  #define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,              \
>                         host_abs_func, min_normal)                       \
> -    static inline __attribute__((always_inline)) soft_t                 \
> +    static soft_t                                                       \
>      fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,        \
>                                float_status *s)                          \
>      {                                                                   \
> 
> That slows add/sub dramatically, because addsub is not inlined into
> float32_add and float32_sub (that's an extra function call plus an
> extra branch per emulated op).
> 
> For x86_64-linux-user/qemu-x86_64 tests/fp-bench -o add, the above gives
> - before: 188.06 MFlops
> - after:  117.56 MFlops

Well, not quite.  I meant putting all of the new code into softfloat.c, and not
attempting to inline any of it in target/cpu/foo_helper.c.

The best written target helpers currently simply tail-call to softfloat.c.
There are others that do so after minor argument adjustment.  For these, I have
had in my plans to rearrange things such that e.g. float32_add is called from
TCG directly, with no other function calls at all.

For targets that cannot do that, I simply cannot bring myself to care about the
final percentage points enough to want to introduce extra macros.

Another thought re all of the soft_is_normal || soft_is_zero checks that you're
performing.  I think it would be nice if we could work with
float*_unpack_canonical so that we don't have to duplicate work.  E.g.

/* Return true for float_class_normal && float_class_zero.  */
static inline bool is_finite(FloatClass c) { return c <= float_class_zero; }

float32 float32_add(float32 a, float32 b, float_status *s)
{
  FloatClass a_cls = float32_classify(a);
  FloatClass b_cls = float32_classify(b);

  if (is_finite(a_cls) && is_finite(b_cls) && ...) {
      /* do hardfp thing */
  }

  pa = float32_unpack(a, ca, s);
  pb = float32_unpack(b, cb, s);
  pr = addsub_floats(pa, pb, s, false);
  return float32_round_pack(pr, s);
}

Where float32_classify produces Normal/Zero/Inf/NaN and might avoid duplicate
work within float32_unpack.


r~

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat
  2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
                   ` (15 preceding siblings ...)
  2018-03-22  5:02 ` no-reply
@ 2018-03-22  8:56 ` Alex Bennée
  2018-03-22 15:28   ` Emilio G. Cota
  16 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-22  8:56 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

<snip>
> For performance numbers see the last patch.

Just another random data point as we've been using himeno for our SVE
wor:

Master:

8:05:45  [alex@zen:~/l/q/qemu.git] master ± ./aarch64-linux-user/qemu-aarch64 sve.demo/himeno-v80
mimax = 129 mjmax = 65 mkmax = 65
imax = 128 jmax = 64 kmax =64
cpu : 33.430299 sec.
Loop executed for 200 times
Gosa : 1.688752e-03
MFLOPS measured : 98.519585
Score based on MMX Pentium 200MHz : 3.052978

Host FPU:

08:25:03 [alex@zen:~/l/q/qemu.git] master ± ./aarch64-linux-user/qemu-aarch64 sve.demo/himeno-v80
mimax = 129 mjmax = 65 mkmax = 65
imax = 128 jmax = 64 kmax =64
cpu : 15.067773 sec.
Loop executed for 200 times
Gosa : 1.688752e-03
MFLOPS measured : 218.581684
Score based on MMX Pentium 200MHz : 6.773526

Given SVE also beats v80 code thanks to avoiding marshalling overhead by
doing bigger vectors I expect that improvement to be even better. Once
the SVE patches are re-based I'll measure them.

By the way I've been talking to some of the people at connect about
tracking performance over time. I got pointed to LLVM's LNT tool
(example: https://lnt.llvm.org/) so I might see if I can get a server
set up that we can start pushing numbers to. Have you come across any
other such things?

--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22  6:41       ` Richard Henderson
@ 2018-03-22 15:08         ` Emilio G. Cota
  2018-03-22 15:12           ` Laurent Vivier
  2018-03-22 19:57         ` Emilio G. Cota
  1 sibling, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-22 15:08 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland

On Thu, Mar 22, 2018 at 14:41:05 +0800, Richard Henderson wrote:
> On 03/22/2018 01:57 PM, Emilio G. Cota wrote:
> >> Is there any especially good reason you want to not put this code into the
> >> normal softfloat function?  Does it really many any measurable difference at
> >> all to force this code to be inlined into a helper?
(snip)
> Well, not quite.  I meant putting all of the new code into softfloat.c,

I put all this in a separate file because I didn't want to spend time
trying to understand the licensing of softfloat. It isn't clear to
me whether what goes into softfloat.[ch] is only GPL'ed or also BSD'ed.

> and not
> attempting to inline any of it in target/cpu/foo_helper.c.

Unless I've made a mistake, I have not tried to inline anything in
target/*helper*.c

> The best written target helpers currently simply tail-call to softfloat.c.
> There are others that do so after minor argument adjustment.  For these, I have
> had in my plans to rearrange things such that e.g. float32_add is called from
> TCG directly, with no other function calls at all.

Yes, this is definitely worth trying.

> For targets that cannot do that, I simply cannot bring myself to care about the
> final percentage points enough to want to introduce extra macros.

Agreed.

> Another thought re all of the soft_is_normal || soft_is_zero checks that you're
> performing.  I think it would be nice if we could work with
> float*_unpack_canonical so that we don't have to duplicate work.  E.g.
> 
> /* Return true for float_class_normal && float_class_zero.  */
> static inline bool is_finite(FloatClass c) { return c <= float_class_zero; }
> 
> float32 float32_add(float32 a, float32 b, float_status *s)
> {
>   FloatClass a_cls = float32_classify(a);
>   FloatClass b_cls = float32_classify(b);
> 
>   if (is_finite(a_cls) && is_finite(b_cls) && ...) {
>       /* do hardfp thing */
>   }
> 
>   pa = float32_unpack(a, ca, s);
>   pb = float32_unpack(b, cb, s);
>   pr = addsub_floats(pa, pb, s, false);
>   return float32_round_pack(pr, s);
> }
> 
> Where float32_classify produces Normal/Zero/Inf/NaN and might avoid duplicate
> work within float32_unpack.

I'll look into this.

Thanks,

		Emilio

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22 15:08         ` Emilio G. Cota
@ 2018-03-22 15:12           ` Laurent Vivier
  0 siblings, 0 replies; 46+ messages in thread
From: Laurent Vivier @ 2018-03-22 15:12 UTC (permalink / raw)
  To: Emilio G. Cota, Richard Henderson
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Paolo Bonzini, Mark Cave-Ayland

Le 22/03/2018 à 16:08, Emilio G. Cota a écrit :
> On Thu, Mar 22, 2018 at 14:41:05 +0800, Richard Henderson wrote:
>> On 03/22/2018 01:57 PM, Emilio G. Cota wrote:
>>>> Is there any especially good reason you want to not put this code into the
>>>> normal softfloat function?  Does it really many any measurable difference at
>>>> all to force this code to be inlined into a helper?
> (snip)
>> Well, not quite.  I meant putting all of the new code into softfloat.c,
> 
> I put all this in a separate file because I didn't want to spend time
> trying to understand the licensing of softfloat. It isn't clear to
> me whether what goes into softfloat.[ch] is only GPL'ed or also BSD'ed.

It's in the header of sofltloat.c:

...
 * so some portions are provided under:
 *  the SoftFloat-2a license
 *  the BSD license
 *  GPL-v2-or-later
 *
 * Any future contributions to this file after December 1st 2014 will be
 * taken to be licensed under the Softfloat-2a license unless specifically
 * indicated otherwise.
 */

and

/* Portions of this work are licensed under the terms of the GNU GPL,
 * version 2 or later. See the COPYING file in the top-level directory.
 */

So you can choose your license, just say what you want.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat
  2018-03-22  8:56 ` Alex Bennée
@ 2018-03-22 15:28   ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-22 15:28 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Thu, Mar 22, 2018 at 08:56:36 +0000, Alex Bennée wrote:
> 
> Emilio G. Cota <cota@braap.org> writes:
> 
> <snip>
> > For performance numbers see the last patch.
> 
> Just another random data point as we've been using himeno for our SVE
> wor:
> 
> Master:
> 
> 8:05:45  [alex@zen:~/l/q/qemu.git] master ± ./aarch64-linux-user/qemu-aarch64 sve.demo/himeno-v80
> mimax = 129 mjmax = 65 mkmax = 65
> imax = 128 jmax = 64 kmax =64
> cpu : 33.430299 sec.
> Loop executed for 200 times
> Gosa : 1.688752e-03
> MFLOPS measured : 98.519585
> Score based on MMX Pentium 200MHz : 3.052978
> 
> Host FPU:
> 
> 08:25:03 [alex@zen:~/l/q/qemu.git] master ± ./aarch64-linux-user/qemu-aarch64 sve.demo/himeno-v80
> mimax = 129 mjmax = 65 mkmax = 65
> imax = 128 jmax = 64 kmax =64
> cpu : 15.067773 sec.
> Loop executed for 200 times
> Gosa : 1.688752e-03
> MFLOPS measured : 218.581684
> Score based on MMX Pentium 200MHz : 6.773526
> 
> Given SVE also beats v80 code thanks to avoiding marshalling overhead by
> doing bigger vectors I expect that improvement to be even better. Once
> the SVE patches are re-based I'll measure them.

This is nice to see. It is possible though that this code uses other FP
instructions that this patchset doesn't speed up; perf record/report
will point to those, if any.

> By the way I've been talking to some of the people at connect about
> tracking performance over time. I got pointed to LLVM's LNT tool
> (example: https://lnt.llvm.org/) so I might see if I can get a server
> set up that we can start pushing numbers to. Have you come across any
> other such things?

I like the idea of having a server to test for performance regressions.

Perhaps the hardest bit would be to choose what benchmarks to run.
We could start with nbench and (parallel w/ MTTCG) bootup+shutdown
tests, although having access to SPEC (it's proprietary) would be nice;
as you can see below I think SPEC has a better job than nbench at
characterizing performance.

I have scripts for automatically generating perf numbers and plots;
I could share those. With them, generating plots like the following
is trivial (if you discount the time it takes for the tests to run,
heh):
  https://imgur.com/a/5P5zj
  context:
  http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg01206.html

Thanks,

		Emilio

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22  6:41       ` Richard Henderson
  2018-03-22 15:08         ` Emilio G. Cota
@ 2018-03-22 19:57         ` Emilio G. Cota
  2018-03-27 11:41           ` Alex Bennée
  1 sibling, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-22 19:57 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Alex Bennée,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland

On Thu, Mar 22, 2018 at 14:41:05 +0800, Richard Henderson wrote:
(snip)
> Another thought re all of the soft_is_normal || soft_is_zero checks that you're
> performing.  I think it would be nice if we could work with
> float*_unpack_canonical so that we don't have to duplicate work.  E.g.
> 
> /* Return true for float_class_normal && float_class_zero.  */
> static inline bool is_finite(FloatClass c) { return c <= float_class_zero; }
> 
> float32 float32_add(float32 a, float32 b, float_status *s)
> {
>   FloatClass a_cls = float32_classify(a);
>   FloatClass b_cls = float32_classify(b);

Just looked at this. It can be done, although it comes at the
price of some performance for fp-bench -o add:
180 Mflops vs. 196 Mflops, i.e. a 8% slowdown. That is with
adequate inlining etc., otherwise perf is worse.

I'm not convinced that we can gain much in simplicity to
justify the perf impact. Yes, we'd simplify canonicalize(),
but we'd probably need a float_class_denormal[*], which
would complicate everything else.

I think it makes sense to keep some inlines that work on
the float32/64's directly.

>   if (is_finite(a_cls) && is_finite(b_cls) && ...) {
>       /* do hardfp thing */
>   }

[*] Taking 0, denormals and normals would be OK from correctness,
but we really don't want to compute ops with denormal inputs on
the host; it is very likely that the output will also be denormal,
and we'll end up deferring to soft-fp anyway to avoid
computing whether the underflow exception has occurred,
which is expensive.

>   pa = float32_unpack(a, ca, s);
>   pb = float32_unpack(b, cb, s);
>   pr = addsub_floats(pa, pb, s, false);
>   return float32_round_pack(pr, s);
> }

It pays off to have two separate functions (add & sub) for the
slow path. With soft_f32_add/sub factored out:

$ taskset -c 0 x86_64-linux-user/qemu-x86_64 tests/fp-bench -o add
197.53 MFlops

With the above four lines (pa...return) as an else branch:
169.16 MFlops

BTW flattening makes things worse (150.63 MFlops).

Note that fp-bench only tests normal numbers. But I think it's fair
to assume that this is the path we want to speed up.

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks Emilio G. Cota
@ 2018-03-27  8:45   ` Alex Bennée
  2018-03-27 17:21     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27  8:45 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> This will allow us to measure the performance impact of FP
> emulation optimizations.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  tests/fp-bench.c       | 290 +++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/.gitignore       |   1 +
>  tests/Makefile.include |   3 +-
>  3 files changed, 293 insertions(+), 1 deletion(-)
>  create mode 100644 tests/fp-bench.c
>
> diff --git a/tests/fp-bench.c b/tests/fp-bench.c
> new file mode 100644
> index 0000000..a782093
> --- /dev/null
> +++ b/tests/fp-bench.c
> @@ -0,0 +1,290 @@
> +/*
> + * fp-bench.c - A collection of simple floating point microbenchmarks.
> + *
> + * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
> + *
> + * License: GNU GPL, version 2 or later.
> + *   See the COPYING file in the top-level directory.
> + */
> +#include "qemu/osdep.h"
> +#include "qemu/atomic.h"
> +
> +#include <math.h>
> +
> +#include <sys/time.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <time.h>
> +
> +/* amortize the computation of random inputs */
> +#define OPS_PER_ITER     (1000ULL)
> +
> +#define SEED_A 0xdeadfacedeadface
> +#define SEED_B 0xbadc0feebadc0fee
> +#define SEED_C 0xbeefdeadbeefdead
> +
> +enum op {
> +    OP_ADD,
> +    OP_SUB,
> +    OP_MUL,
> +    OP_DIV,
> +    OP_FMA,
> +    OP_SQRT,
> +};
> +
> +static const char * const op_names[] = {
> +    [OP_ADD] = "add",
> +    [OP_SUB] = "sub",
> +    [OP_MUL] = "mul",
> +    [OP_DIV] = "div",
> +    [OP_FMA] = "fma",
> +    [OP_SQRT] = "sqrt",
> +};
> +
> +static uint64_t n_ops = 10000000;
> +static enum op op;
> +static const char *precision = "float";
> +
> +static const char commands_string[] =
> +    " -n = number of floating point operations\n"
> +    " -o = floating point operation (add, sub, mul, div, fma, sqrt). Default: add\n"
> +    " -p = precision (float|single, double). Default: float";
> +
> +static void usage_complete(int argc, char *argv[])
> +{
> +    fprintf(stderr, "Usage: %s [options]\n", argv[0]);
> +    fprintf(stderr, "options:\n%s\n", commands_string);
> +    exit(-1);
> +}
> +
> +static void set_op(const char *name)
> +{
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(op_names); i++) {
> +        if (strcmp(name, op_names[i]) == 0) {
> +            op = i;
> +            return;
> +        }
> +    }
> +    fprintf(stderr, "Unsupported op '%s'\n", name);
> +    exit(EXIT_FAILURE);
> +}
> +
> +static inline int64_t get_clock_realtime(void)
> +{
> +    struct timeval tv;
> +
> +    gettimeofday(&tv, NULL);
> +    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
> +}
> +
> +/*
> + * From: https://en.wikipedia.org/wiki/Xorshift
> + * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
> + * guaranteed to be >= INT_MAX).
> + */
> +static uint64_t xorshift64star(uint64_t x)
> +{
> +    x ^= x >> 12; /* a */
> +    x ^= x << 25; /* b */
> +    x ^= x >> 27; /* c */
> +    return x * UINT64_C(2685821657736338717);
> +}
> +
> +static inline bool u32_is_normal(uint32_t x)
> +{
> +    return ((x + 0x00800000) & 0x7fffffff) >= 0x01000000;
> +}
> +
> +static inline bool u64_is_normal(uint64_t x)
> +{
> +    return ((x + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
> +}
> +
> +static inline float get_random_float(uint64_t *x)
> +{
> +    uint64_t r = *x;
> +    uint32_t r32;
> +
> +    do {
> +        r = xorshift64star(r);
> +    } while (!u32_is_normal(r));
> +    *x = r;
> +    r32 = r;
> +    return *(float *)&r32;
> +}
> +
> +static inline double get_random_double(uint64_t *x)
> +{
> +    uint64_t r = *x;
> +
> +    do {
> +        r = xorshift64star(r);
> +    } while (!u64_is_normal(r));
> +    *x = r;
> +    return *(double *)&r;
> +}
> +
> +/*
> + * Disable optimizations (e.g. "a OP b" outside of the inner loop) with
> + * volatile.
> + */
> +#define GEN_BENCH_1OPF(NAME, FUNC, PRECISION)                           \
> +    static void NAME(volatile PRECISION *res)                           \
> +    {                                                                   \
> +        uint64_t ra = SEED_A;                                           \
> +        uint64_t i, j;                                                  \
> +                                                                        \
> +        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
> +            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
> +                                                                        \
> +            for (j = 0; j < OPS_PER_ITER; j++) {                        \
> +                *res = FUNC(a);                                         \
> +            }                                                           \
> +        }                                                               \
> +    }
> +

Have you had a chance to look at if this will vectorise? I have a
similar benchmark which I compile with multiple options to test normal,
NEON/AdvSIMD and SVE enabled loops.

> +GEN_BENCH_1OPF(bench_float_sqrt, sqrtf, float)
> +GEN_BENCH_1OPF(bench_double_sqrt, sqrt, double)
> +#undef GEN_BENCH_1OPF
> +
> +#define GEN_BENCH_2OP(NAME, OP, PRECISION)                              \
> +    static void NAME(volatile PRECISION *res)                           \
> +    {                                                                   \
> +        uint64_t ra = SEED_A;                                           \
> +        uint64_t rb = SEED_B;                                           \
> +        uint64_t i, j;                                                  \
> +                                                                        \
> +        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
> +            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
> +            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \
> +                                                                        \
> +            for (j = 0; j < OPS_PER_ITER; j++) {                        \
> +                *res = a OP b;                                          \
> +            }                                                           \
> +        }                                                               \
> +    }
> +
> +GEN_BENCH_2OP(bench_float_add, +, float)
> +GEN_BENCH_2OP(bench_float_sub, -, float)
> +GEN_BENCH_2OP(bench_float_mul, *, float)
> +GEN_BENCH_2OP(bench_float_div, /, float)
> +
> +GEN_BENCH_2OP(bench_double_add, +, double)
> +GEN_BENCH_2OP(bench_double_sub, -, double)
> +GEN_BENCH_2OP(bench_double_mul, *, double)
> +GEN_BENCH_2OP(bench_double_div, /, double)
> +
> +#define GEN_BENCH_3OPF(NAME, FUNC, PRECISION)                           \
> +    static void NAME(volatile PRECISION *res)                           \
> +    {                                                                   \
> +        uint64_t ra = SEED_A;                                           \
> +        uint64_t rb = SEED_B;                                           \
> +        uint64_t rc = SEED_C;                                           \
> +        uint64_t i, j;                                                  \
> +                                                                        \
> +        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
> +            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
> +            volatile PRECISION b = glue(get_random_, PRECISION)(&rb);   \
> +            volatile PRECISION c = glue(get_random_, PRECISION)(&rc);   \
> +                                                                        \
> +            for (j = 0; j < OPS_PER_ITER; j++) {                        \
> +                *res = FUNC(a, b, c);                                   \
> +            }                                                           \
> +        }                                                               \
> +    }
> +
> +GEN_BENCH_3OPF(bench_float_fma, fmaf, float)
> +GEN_BENCH_3OPF(bench_double_fma, fma, double)
> +#undef GEN_BENCH_3OPF
> +
> +static void parse_args(int argc, char *argv[])
> +{
> +    int c;
> +
> +    for (;;) {
> +        c = getopt(argc, argv, "n:ho:p:");
> +        if (c < 0) {
> +            break;
> +        }
> +        switch (c) {
> +        case 'h':
> +            usage_complete(argc, argv);
> +            exit(0);
> +        case 'n':
> +            n_ops = atoll(optarg);
> +            if (n_ops < OPS_PER_ITER) {
> +                n_ops = OPS_PER_ITER;
> +            }
> +            n_ops -= n_ops % OPS_PER_ITER;
> +            break;
> +        case 'o':
> +            set_op(optarg);
> +            break;
> +        case 'p':
> +            precision = optarg;
> +            if (strcmp(precision, "float") &&
> +                strcmp(precision, "single") &&
> +                strcmp(precision, "double")) {
> +                fprintf(stderr, "Unsupported precision '%s'\n", precision);
> +                exit(EXIT_FAILURE);

Supporting half-precision if the compiler does would also be useful here.

> +            }
> +            break;
> +        }
> +    }
> +}
> +
> +#define CALL_BENCH(OP, PRECISION, RESP)                 \
> +    do {                                                \
> +        switch (OP) {                                   \
> +        case OP_ADD:                                    \
> +            glue(glue(bench_, PRECISION), _add)(RESP);  \
> +            break;                                      \
> +        case OP_SUB:                                    \
> +            glue(glue(bench_, PRECISION), _sub)(RESP);  \
> +            break;                                      \
> +        case OP_MUL:                                    \
> +            glue(glue(bench_, PRECISION), _mul)(RESP);  \
> +            break;                                      \
> +        case OP_DIV:                                    \
> +            glue(glue(bench_, PRECISION), _div)(RESP);  \
> +            break;                                      \
> +        case OP_FMA:                                    \
> +            glue(glue(bench_, PRECISION), _fma)(RESP);  \
> +            break;                                      \
> +        case OP_SQRT:                                   \
> +            glue(glue(bench_, PRECISION), _sqrt)(RESP); \
> +            break;                                      \
> +        default:                                        \
> +            g_assert_not_reached();                     \
> +        }                                               \
> +    } while (0)
> +
> +int main(int argc, char *argv[])
> +{
> +    int64_t t0, t1;
> +    double resd;
> +
> +    parse_args(argc, argv);
> +    if (!strcmp(precision, "float") || !strcmp(precision, "single")) {
> +        float res;
> +        t0 = get_clock_realtime();
> +        CALL_BENCH(op, float, &res);
> +        t1 = get_clock_realtime();
> +        resd = res;
> +    } else if (!strcmp(precision, "double")) {
> +        t0 = get_clock_realtime();
> +        CALL_BENCH(op, double, &resd);
> +        t1 = get_clock_realtime();
> +    } else {
> +        g_assert_not_reached();
> +    }
> +    printf("%.2f MFlops\n", (double)n_ops / (t1 - t0) * 1e3);
> +    if (resd) {
> +        return 0;
> +    }
> +    return 0;
> +}
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 18e58b2..df69175 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -12,6 +12,7 @@ check-qobject
>  check-qstring
>  check-qom-interface
>  check-qom-proplist
> +fp-bench
>  qht-bench
>  rcutorture
>  test-aio
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index ef9b88c..f6121ee 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -587,7 +587,7 @@ test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
>  	tests/rcutorture.o tests/test-rcu-list.o \
>  	tests/test-qdist.o tests/test-shift128.o \
>  	tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
> -	tests/atomic_add-bench.o
> +	tests/atomic_add-bench.o tests/fp-bench.o

Not sure why but "make check" didn't build this. I had to explicitly
"make tests/fp-bench". I guess along with atomic_add_bench though these
are explicitly guest facing tests so maybe we should move them once
tests/tcg is working again. I'll have another run at that this week.

>
>  $(test-obj-y): QEMU_INCLUDES += -Itests
>  QEMU_CFLAGS += -I$(SRC_PATH)/tests
> @@ -639,6 +639,7 @@ tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(tes
>  tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
>  tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
>  tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
> +tests/fp-bench$(EXESUF): tests/fp-bench.o $(test-util-obj-y)
>
>  tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
>  	hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\

Anyway for this version:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite Emilio G. Cota
@ 2018-03-27 10:13   ` Alex Bennée
  2018-03-27 18:00     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 10:13 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> This will allow us to run correctness tests against our
> FP implementation. The test can be run in two modes (called
> "testers"): host and soft. With the former we check the results
> and FP flags on the host machine against the model.
> With the latter we check QEMU's fpu primitives against the
> model. Note that in soft mode we are not instantiating any
> particular CPU (hence the HW_POISON_H hack to avoid macro poisoning);
> for that we need to run the test in host mode under QEMU.
>
> The input files are taken from IBM's FPGen test suite:
> https://www.research.ibm.com/haifa/projects/verification/fpgen/
>
> I see no license file in there so I am just downloading them
> with wget. We might want to keep a copy on a qemu server though,
> in case IBM takes those files down in the future.

Hmm the files themselves have:

  Copyright of IBM Corp. 2005

So I'm not sure we can take them into any of our source trees. However
what are we testing here?

Do we just want to test our implementation is IEEE compliant or should
we generate our own test cases on validated hardware to check that our
emulation of a guest is correct (e.g. correct modulo the valid
variations in the standard)?

> The "IBM" syntax of those files (for now the only syntax supported
> in fp-test) is documented here:
> https://www.research.ibm.com/haifa/projects/verification/fpgen/papers/ieee-test-suite-v2.pdf
>
> Note that the syntax document has some inaccuracies; the appended
> parsing code works around some of those.
>
> The exception flag (-e) is important: many of the optimizations
> included in the following commits assume that the inexact flag
> is set, so "-e x" is necessary in order to test those code paths.
>
> The whitelist flag (-w) points to a file with test cases to be ignored.
> I have put some whitelist files online, but we should have them
> on a QEMU-related server.
>
> Thus, a typical of fp-test is as follows:
>
>   $ cd qemu/build/tests/fp-test
>   $ make -j && \
> 	./fp-test -t soft ibm/*.fptest \
> 	-w whitelist.txt \
> 	-e x

So this is a unit test of our code rather than a test program running
under QEMU? I noted running under x86-64-linux-user fails pretty
quick.

If so we really should be building this automatically in make check.

>
> If we want to test after-rounding tininess detection, then we need to
> pass "-a -w whitelist-tininess-after.txt" in addition to the above.
> (NB. we can pass "-w" as many times as we want.)
>
> The patch immediately after this one fixes a mismatch against the model
> in softfloat, but after that is applied the above should finish with a 0
> return code, and print something like:
>   All tests OK.
>   Tests passed: 76572. Not handled: 51237, whitelisted: 2662
>
> The tests pass on "host" mode on x86_64 and aarch64 machines.
> On an IBM Power8 machine some exception flags are different from the
> model files, which is interesting given that the model comes from IBM.
>
> Running on host mode under QEMU reports flag mismatches (e.g. for
> x86_64-linux-user), but that isn't too surprising given how little
> love the i386 frontend gets. Host mode under aarch64-linux-user
> passes OK.
>
> Flush-to-zero and flush-inputs-to-zero modes can be tested with the
> -z and -Z flags. Note however that the IBM input files are only
> IEEE-compliant, so for now I've tested these modes by diff'ing
> the reported errors against the model files. We should look into
> generating files for these non-standard modes to make testing
> these modes less painful.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  configure                |    2 +
>  tests/fp-test/fp-test.c  | 1159 ++++++++++++++++++++++++++++++++++++++++++++++
>  tests/.gitignore         |    1 +
>  tests/fp-test/.gitignore |    3 +
>  tests/fp-test/Makefile   |   34 ++
>  5 files changed, 1199 insertions(+)
>  create mode 100644 tests/fp-test/fp-test.c
>  create mode 100644 tests/fp-test/.gitignore
>  create mode 100644 tests/fp-test/Makefile
>
> diff --git a/configure b/configure
> index 6f3921c..8ea3825 100755
> --- a/configure
> +++ b/configure
> @@ -7046,12 +7046,14 @@ fi
>
>  # build tree in object directory in case the source is not in the current directory
>  DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
> +DIRS="$DIRS tests/fp-test"
>  DIRS="$DIRS docs docs/interop fsdev scsi"
>  DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
>  DIRS="$DIRS roms/seabios roms/vgabios"
>  FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
>  FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
>  FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
> +FILES="$FILES tests/fp-test/Makefile"
>  FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
>  FILES="$FILES pc-bios/spapr-rtas/Makefile"
>  FILES="$FILES pc-bios/s390-ccw/Makefile"
> diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
> new file mode 100644
> index 0000000..27637c4
> --- /dev/null
> +++ b/tests/fp-test/fp-test.c
> @@ -0,0 +1,1159 @@
> +/*
> + * fp-test.c - Floating point test suite.
> + *
> + * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
> + *
> + * License: GNU GPL, version 2 or later.
> + *   See the COPYING file in the top-level directory.
> + */
> +#ifndef HW_POISON_H
> +#error Must define HW_POISON_H to work around TARGET_* poisoning
> +#endif
> +
> +#include "qemu/osdep.h"
> +#include "fpu/softfloat.h"
> +
> +#include <fenv.h>
> +#include <math.h>
> +
> +enum error {
> +    ERROR_NONE,
> +    ERROR_NOT_HANDLED,
> +    ERROR_WHITELISTED,
> +    ERROR_COMMENT,
> +    ERROR_INPUT,
> +    ERROR_RESULT,
> +    ERROR_EXCEPTIONS,
> +    ERROR_MAX,
> +};
> +
> +enum input_fmt {
> +    INPUT_FMT_IBM,
> +};
> +
> +struct input {
> +    const char * const name;
> +    enum error (*test_line)(const char *line);
> +};
> +
> +enum precision {
> +    PREC_FLOAT,
> +    PREC_DOUBLE,
> +    PREC_QUAD,
> +    PREC_FLOAT_TO_DOUBLE,
> +};

Again we will want to include half-precision.

> +
> +struct op_desc {
> +    const char * const name;
> +    int n_operands;
> +};
> +
> +enum op {
> +    OP_ADD,
> +    OP_SUB,
> +    OP_MUL,
> +    OP_MULADD,
> +    OP_DIV,
> +    OP_SQRT,
> +    OP_MINNUM,
> +    OP_MAXNUM,
> +    OP_MAXNUMMAG,
> +    OP_ABS,
> +    OP_IS_NAN,
> +    OP_IS_INF,
> +    OP_FLOAT_TO_DOUBLE,
> +};
> +
> +static const struct op_desc ops[] = {
> +    [OP_ADD] =       { "+", 2 },
> +    [OP_SUB] =       { "-", 2 },
> +    [OP_MUL] =       { "*", 2 },
> +    [OP_MULADD] =    { "*+", 3 },
> +    [OP_DIV] =       { "/", 2 },
> +    [OP_SQRT] =      { "V", 1 },
> +    [OP_MINNUM] =    { "<C", 2 },
> +    [OP_MAXNUM] =    { ">C", 2 },
> +    [OP_MAXNUMMAG] = { ">A", 2 },
> +    [OP_ABS] =       { "A", 1 },
> +    [OP_IS_NAN] =    { "?N", 1 },
> +    [OP_IS_INF] =    { "?i", 1 },
> +    [OP_FLOAT_TO_DOUBLE] = { "cff", 1 },
> +};
> +
> +/*
> + * We could enumerate all the types here. But really we only care about
> + * QNaN and SNaN since only those can vary across ISAs.
> + */
> +enum op_type {
> +    OP_TYPE_NUMBER,
> +    OP_TYPE_QNAN,
> +    OP_TYPE_SNAN,
> +};
> +
> +struct operand {
> +    uint64_t val;
> +    enum op_type type;
> +};
> +
> +struct test_op {
> +    struct operand operands[3];
> +    struct operand expected_result;
> +    enum precision prec;
> +    enum op op;
> +    signed char round;
> +    uint8_t trapped_exceptions;
> +    uint8_t exceptions;
> +    bool expected_result_is_valid;
> +};
> +
> +typedef enum error (*tester_func_t)(struct test_op *);
> +
> +struct tester {
> +    tester_func_t func;
> +    const char *name;
> +};
> +
> +struct whitelist {
> +    char **lines;
> +    size_t n;
> +    GHashTable *ht;
> +};
> +
> +static uint64_t test_stats[ERROR_MAX];
> +static struct whitelist whitelist;
> +static uint8_t default_exceptions;
> +static bool die_on_error = true;
> +static struct float_status soft_status = {
> +    .float_detect_tininess = float_tininess_before_rounding,
> +};
> +
> +static inline float u64_to_float(uint64_t v)
> +{
> +    uint32_t v32 = v;
> +    uint32_t *v32p = &v32;
> +
> +    return *(float *)v32p;
> +}
> +
> +static inline double u64_to_double(uint64_t v)
> +{
> +    uint64_t *vp = &v;
> +
> +    return *(double *)vp;
> +}
> +
> +static inline uint64_t float_to_u64(float f)
> +{
> +    float *fp = &f;
> +
> +    return *(uint32_t *)fp;
> +}
> +
> +static inline uint64_t double_to_u64(double d)
> +{
> +    double *dp = &d;
> +
> +    return *(uint64_t *)dp;
> +}
> +
> +static inline bool is_err(enum error err)
> +{
> +    return err != ERROR_NONE &&
> +        err != ERROR_NOT_HANDLED &&
> +        err != ERROR_WHITELISTED &&
> +        err != ERROR_COMMENT;
> +}
> +
> +static int host_exceptions_translate(int host_flags)
> +{
> +    int flags = 0;
> +
> +    if (host_flags & FE_INEXACT) {
> +        flags |= float_flag_inexact;
> +    }
> +    if (host_flags & FE_UNDERFLOW) {
> +        flags |= float_flag_underflow;
> +    }
> +    if (host_flags & FE_OVERFLOW) {
> +        flags |= float_flag_overflow;
> +    }
> +    if (host_flags & FE_DIVBYZERO) {
> +        flags |= float_flag_divbyzero;
> +    }
> +    if (host_flags & FE_INVALID) {
> +        flags |= float_flag_invalid;
> +    }
> +    return flags;
> +}
> +
> +static inline uint8_t host_get_exceptions(void)
> +{
> +    return host_exceptions_translate(fetestexcept(FE_ALL_EXCEPT));
> +}
> +
> +static void host_set_exceptions(uint8_t flags)
> +{
> +    int host_flags = 0;
> +
> +    if (flags & float_flag_inexact) {
> +        host_flags |= FE_INEXACT;
> +    }
> +    if (flags & float_flag_underflow) {
> +        host_flags |= FE_UNDERFLOW;
> +    }
> +    if (flags & float_flag_overflow) {
> +        host_flags |= FE_OVERFLOW;
> +    }
> +    if (flags & float_flag_divbyzero) {
> +        host_flags |= FE_DIVBYZERO;
> +    }
> +    if (flags & float_flag_invalid) {
> +        host_flags |= FE_INVALID;
> +    }
> +    feraiseexcept(host_flags);
> +}
> +
> +#define STANDARD_EXCEPTIONS \
> +    (float_flag_inexact | float_flag_underflow | \
> +     float_flag_overflow | float_flag_divbyzero | float_flag_invalid)
> +#define FMT_EXCEPTIONS "%s%s%s%s%s%s"
> +#define PR_EXCEPTIONS(x)                                \
> +        ((x) & STANDARD_EXCEPTIONS ? "" : "none"),      \
> +        (((x) & float_flag_inexact)   ? "x" : ""),      \
> +        (((x) & float_flag_underflow) ? "u" : ""),      \
> +        (((x) & float_flag_overflow)  ? "o" : ""),      \
> +        (((x) & float_flag_divbyzero) ? "z" : ""),      \
> +        (((x) & float_flag_invalid)   ? "i" : "")
> +
> +static enum error tester_check(const struct test_op *t, uint64_t res64,
> +                               bool res_is_nan, uint8_t flags)
> +{
> +    enum error err = ERROR_NONE;
> +
> +    if (t->expected_result_is_valid) {
> +        if (t->expected_result.type == OP_TYPE_QNAN ||
> +            t->expected_result.type == OP_TYPE_SNAN) {
> +            if (!res_is_nan) {
> +                err = ERROR_RESULT;
> +                goto out;
> +            }
> +        } else if (res64 != t->expected_result.val) {
> +            err = ERROR_RESULT;
> +            goto out;
> +        }
> +    }
> +    if (t->exceptions && flags != (t->exceptions | default_exceptions)) {
> +        err = ERROR_EXCEPTIONS;
> +        goto out;
> +    }
> +
> + out:
> +    if (is_err(err)) {
> +        int i;
> +
> +        fprintf(stderr, "%s ", ops[t->op].name);
> +        for (i = 0; i < ops[t->op].n_operands; i++) {
> +            fprintf(stderr, "0x%" PRIx64 "%s", t->operands[i].val,
> +                    i < ops[t->op].n_operands - 1 ? " " : "");
> +        }
> +        fprintf(stderr, ", expected: 0x%" PRIx64 ", returned: 0x%" PRIx64,
> +                t->expected_result.val, res64);
> +        if (err == ERROR_EXCEPTIONS) {
> +            fprintf(stderr, ", expected exceptions: " FMT_EXCEPTIONS
> +                    ", returned: " FMT_EXCEPTIONS,
> +                    PR_EXCEPTIONS(t->exceptions), PR_EXCEPTIONS(flags));
> +        }
> +        fprintf(stderr, "\n");
> +    }
> +    return err;
> +}
> +
> +static enum error host_tester(struct test_op *t)
> +{
> +    uint64_t res64;
> +    bool result_is_nan;
> +    uint8_t flags = 0;
> +
> +    feclearexcept(FE_ALL_EXCEPT);
> +    if (default_exceptions) {
> +        host_set_exceptions(default_exceptions);
> +    }
> +
> +    if (t->prec == PREC_FLOAT) {
> +        float a, b, c;
> +        float *in[] = { &a, &b, &c };
> +        float res;
> +        int i;
> +
> +        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
> +        for (i = 0; i < ops[t->op].n_operands; i++) {
> +            /* use the host's QNaN/SNaN patterns */
> +            if (t->operands[i].type == OP_TYPE_QNAN) {
> +                *in[i] = __builtin_nanf("");
> +            } else if (t->operands[i].type == OP_TYPE_SNAN) {
> +                *in[i] = __builtin_nansf("");
> +            } else {
> +                *in[i] = u64_to_float(t->operands[i].val);
> +            }
> +        }
> +
> +        if (t->expected_result.type == OP_TYPE_QNAN) {
> +            t->expected_result.val = float_to_u64(__builtin_nanf(""));
> +        } else if (t->expected_result.type == OP_TYPE_SNAN) {
> +            t->expected_result.val = float_to_u64(__builtin_nansf(""));
> +        }
> +
> +        switch (t->op) {
> +        case OP_ADD:
> +            res = a + b;
> +            break;
> +        case OP_SUB:
> +            res = a - b;
> +            break;
> +        case OP_MUL:
> +            res = a * b;
> +            break;
> +        case OP_MULADD:
> +            res = fmaf(a, b, c);
> +            break;
> +        case OP_DIV:
> +            res = a / b;
> +            break;
> +        case OP_SQRT:
> +            res = sqrtf(a);
> +            break;
> +        case OP_ABS:
> +            res = fabsf(a);
> +            break;
> +        case OP_IS_NAN:
> +            res = !!isnan(a);
> +            break;
> +        case OP_IS_INF:
> +            res = !!isinf(a);
> +            break;
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        flags = host_get_exceptions();
> +        res64 = float_to_u64(res);
> +        result_is_nan = isnan(res);
> +    } else if (t->prec == PREC_DOUBLE) {
> +        double a, b, c;
> +        double *in[] = { &a, &b, &c };
> +        double res;
> +        int i;
> +
> +        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
> +        for (i = 0; i < ops[t->op].n_operands; i++) {
> +            /* use the host's QNaN/SNaN patterns */
> +            if (t->operands[i].type == OP_TYPE_QNAN) {
> +                *in[i] = __builtin_nan("");
> +            } else if (t->operands[i].type == OP_TYPE_SNAN) {
> +                *in[i] = __builtin_nans("");
> +            } else {
> +                *in[i] = u64_to_double(t->operands[i].val);
> +            }
> +        }
> +
> +        if (t->expected_result.type == OP_TYPE_QNAN) {
> +            t->expected_result.val = double_to_u64(__builtin_nan(""));
> +        } else if (t->expected_result.type == OP_TYPE_SNAN) {
> +            t->expected_result.val = double_to_u64(__builtin_nans(""));
> +        }
> +
> +        switch (t->op) {
> +        case OP_ADD:
> +            res = a + b;
> +            break;
> +        case OP_SUB:
> +            res = a - b;
> +            break;
> +        case OP_MUL:
> +            res = a * b;
> +            break;
> +        case OP_MULADD:
> +            res = fma(a, b, c);
> +            break;
> +        case OP_DIV:
> +            res = a / b;
> +            break;
> +        case OP_SQRT:
> +            res = sqrt(a);
> +            break;
> +        case OP_ABS:
> +            res = fabs(a);
> +            break;
> +        case OP_IS_NAN:
> +            res = !!isnan(a);
> +            break;
> +        case OP_IS_INF:
> +            res = !!isinf(a);
> +            break;
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        flags = host_get_exceptions();
> +        res64 = double_to_u64(res);
> +        result_is_nan = isnan(res);
> +    } else if (t->prec == PREC_FLOAT_TO_DOUBLE) {
> +        float a;
> +        double res;
> +
> +        if (t->operands[0].type == OP_TYPE_QNAN) {
> +            a = __builtin_nanf("");
> +        } else if (t->operands[0].type == OP_TYPE_SNAN) {
> +            a = __builtin_nansf("");
> +        } else {
> +            a = u64_to_float(t->operands[0].val);
> +        }
> +
> +        if (t->expected_result.type == OP_TYPE_QNAN) {
> +            t->expected_result.val = double_to_u64(__builtin_nan(""));
> +        } else if (t->expected_result.type == OP_TYPE_SNAN) {
> +            t->expected_result.val = double_to_u64(__builtin_nans(""));
> +        }
> +
> +        switch (t->op) {
> +        case OP_FLOAT_TO_DOUBLE:
> +            res = a;
> +            break;
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        flags = host_get_exceptions();
> +        res64 = double_to_u64(res);
> +        result_is_nan = isnan(res);
> +    } else {
> +        return ERROR_NOT_HANDLED; /* XXX */
> +    }
> +    return tester_check(t, res64, result_is_nan, flags);
> +}
> +
> +static enum error soft_tester(struct test_op *t)
> +{
> +    float_status *s = &soft_status;
> +    uint64_t res64;
> +    enum error err = ERROR_NONE;
> +    bool result_is_nan;
> +
> +    s->float_rounding_mode = t->round;
> +    s->float_exception_flags = default_exceptions;
> +
> +    if (t->prec == PREC_FLOAT) {
> +        float32 a, b, c;
> +        float32 *in[] = { &a, &b, &c };
> +        float32 res;
> +        int i;
> +
> +        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
> +        for (i = 0; i < ops[t->op].n_operands; i++) {
> +            *in[i] = t->operands[i].val;
> +        }
> +
> +        switch (t->op) {
> +        case OP_ADD:
> +            res = float32_add(a, b, s);
> +            break;
> +        case OP_SUB:
> +            res = float32_sub(a, b, s);
> +            break;
> +        case OP_MUL:
> +            res = float32_mul(a, b, s);
> +            break;
> +        case OP_MULADD:
> +            res = float32_muladd(a, b, c, 0, s);
> +            break;
> +        case OP_DIV:
> +            res = float32_div(a, b, s);
> +            break;
> +        case OP_SQRT:
> +            res = float32_sqrt(a, s);
> +            break;
> +        case OP_MINNUM:
> +            res = float32_minnum(a, b, s);
> +            break;
> +        case OP_MAXNUM:
> +            res = float32_maxnum(a, b, s);
> +            break;
> +        case OP_MAXNUMMAG:
> +            res = float32_maxnummag(a, b, s);
> +            break;
> +        case OP_IS_NAN:
> +        {
> +            float f = !!float32_is_any_nan(a);
> +
> +            res = float_to_u64(f);
> +            break;
> +        }
> +        case OP_IS_INF:
> +        {
> +            float f = !!float32_is_infinity(a);
> +
> +            res = float_to_u64(f);
> +            break;
> +        }
> +        case OP_ABS:
> +            /* Fall-through: float32_abs does not handle NaN's */
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        res64 = res;
> +        result_is_nan = isnan(*(float *)&res);
> +    } else if (t->prec == PREC_DOUBLE) {
> +        float64 a, b, c;
> +        float64 *in[] = { &a, &b, &c };
> +        int i;
> +
> +        g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
> +        for (i = 0; i < ops[t->op].n_operands; i++) {
> +            *in[i] = t->operands[i].val;
> +        }
> +
> +        switch (t->op) {
> +        case OP_ADD:
> +            res64 = float64_add(a, b, s);
> +            break;
> +        case OP_SUB:
> +            res64 = float64_sub(a, b, s);
> +            break;
> +        case OP_MUL:
> +            res64 = float64_mul(a, b, s);
> +            break;
> +        case OP_MULADD:
> +            res64 = float64_muladd(a, b, c, 0, s);
> +            break;
> +        case OP_DIV:
> +            res64 = float64_div(a, b, s);
> +            break;
> +        case OP_SQRT:
> +            res64 = float64_sqrt(a, s);
> +            break;
> +        case OP_MINNUM:
> +            res64 = float64_minnum(a, b, s);
> +            break;
> +        case OP_MAXNUM:
> +            res64 = float64_maxnum(a, b, s);
> +            break;
> +        case OP_MAXNUMMAG:
> +            res64 = float64_maxnummag(a, b, s);
> +            break;
> +        case OP_IS_NAN:
> +        {
> +            double d = !!float64_is_any_nan(a);
> +
> +            res64 = double_to_u64(d);
> +            break;
> +        }
> +        case OP_IS_INF:
> +        {
> +            double d = !!float64_is_infinity(a);
> +
> +            res64 = double_to_u64(d);
> +            break;
> +        }
> +        case OP_ABS:
> +            /* Fall-through: float64_abs does not handle NaN's */
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        result_is_nan = isnan(*(double *)&res64);
> +    } else if (t->prec == PREC_FLOAT_TO_DOUBLE) {
> +        float32 a = t->operands[0].val;
> +
> +        switch (t->op) {
> +        case OP_FLOAT_TO_DOUBLE:
> +            res64 = float32_to_float64(a, s);
> +            break;
> +        default:
> +            return ERROR_NOT_HANDLED;
> +        }
> +        result_is_nan = isnan(*(double *)&res64);
> +    } else {
> +        return ERROR_NOT_HANDLED; /* XXX */
> +    }
> +    return tester_check(t, res64, result_is_nan, s->float_exception_flags);
> +    return err;
> +}
> +
> +static const struct tester valid_testers[] = {
> +    [0] = {
> +        .name = "soft",
> +        .func = soft_tester,
> +    },
> +    [1] = {
> +        .name = "host",
> +        .func = host_tester,
> +    },
> +};
> +static const struct tester *tester = &valid_testers[0];
> +
> +static int ibm_get_exceptions(const char *p, uint8_t *excp)
> +{
> +    while (*p) {
> +        switch (*p) {
> +        case 'x':
> +            *excp |= float_flag_inexact;
> +            break;
> +        case 'u':
> +            *excp |= float_flag_underflow;
> +            break;
> +        case 'o':
> +            *excp |= float_flag_overflow;
> +            break;
> +        case 'z':
> +            *excp |= float_flag_divbyzero;
> +            break;
> +        case 'i':
> +            *excp |= float_flag_invalid;
> +            break;
> +        default:
> +            return 1;
> +        }
> +        p++;
> +    }
> +    return 0;
> +}
> +
> +static uint64_t fp_choose(enum precision prec, uint64_t f, uint64_t d)
> +{
> +    switch (prec) {
> +    case PREC_FLOAT:
> +        return f;
> +    case PREC_DOUBLE:
> +        return d;
> +    default:
> +        g_assert_not_reached();
> +    }
> +}
> +
> +static int
> +ibm_fp_hex(const char *p, enum precision prec, struct operand *ret)
> +{
> +    int len;
> +
> +    ret->type = OP_TYPE_NUMBER;
> +
> +    /* QNaN */
> +    if (unlikely(!strcmp("Q", p))) {
> +        ret->val = fp_choose(prec, 0xffc00000, 0xfff8000000000000);
> +        ret->type = OP_TYPE_QNAN;
> +        return 0;
> +    }
> +    /* SNaN */
> +    if (unlikely(!strcmp("S", p))) {
> +        ret->val = fp_choose(prec, 0xffb00000, 0xfff7000000000000);
> +        ret->type = OP_TYPE_SNAN;
> +        return 0;
> +    }
> +    if (unlikely(!strcmp("+Zero", p))) {
> +        ret->val = fp_choose(prec, 0x00000000, 0x0000000000000000);
> +        return 0;
> +    }
> +    if (unlikely(!strcmp("-Zero", p))) {
> +        ret->val = fp_choose(prec, 0x80000000, 0x8000000000000000);
> +        return 0;
> +    }
> +    if (unlikely(!strcmp("+inf", p) || !strcmp("+Inf", p))) {
> +        ret->val = fp_choose(prec, 0x7f800000, 0x7ff0000000000000);
> +        return 0;
> +    }
> +    if (unlikely(!strcmp("-inf", p) || !strcmp("-Inf", p))) {
> +        ret->val = fp_choose(prec, 0xff800000, 0xfff0000000000000);
> +        return 0;
> +    }
> +
> +    len = strlen(p);
> +
> +    if (strchr(p, 'P')) {

Given we have already strlen'ed should we use memchr(p, 'P', len) or
even strchrnul(p,'P') with a check we haven't run over the end? OR maybe
use glib's string stuff instead.

> +        bool negative = p[0] == '-';
> +        char *pos;
> +        bool denormal;
> +
> +        if (len <= 4) {
> +            return 1;
> +        }
> +        denormal = p[1] == '0';
> +        if (prec == PREC_FLOAT) {
> +            uint32_t exponent;
> +            uint32_t significand;
> +            uint32_t h;
> +
> +            significand = strtoul(&p[3], &pos, 16);
> +            if (*pos != 'P') {
> +                return 1;
> +            }
> +            pos++;
> +            exponent = strtol(pos, &pos, 10) + 127;
> +            if (pos != p + len) {
> +                return 1;
> +            }
> +            /*
> +             * When there's a leading zero, we have a denormal number. We'd
> +             * expect the input (unbiased) exponent to be -127, but for some
> +             * reason -126 is used. Correct that here.
> +             */
> +            if (denormal) {
> +                if (exponent != 1) {
> +                    return 1;
> +                }
> +                exponent = 0;
> +            }
> +            h = negative ? (1 << 31) : 0;
> +            h |= exponent << 23;
> +            h |= significand;
> +            ret->val = h;
> +            return 0;
> +        } else if (prec == PREC_DOUBLE) {
> +            uint64_t exponent;
> +            uint64_t significand;
> +            uint64_t h;
> +
> +            significand = strtoul(&p[3], &pos, 16);
> +            if (*pos != 'P') {
> +                return 1;
> +            }
> +            pos++;
> +            exponent = strtol(pos, &pos, 10) + 1023;
> +            if (pos != p + len) {
> +                return 1;
> +            }
> +            if (denormal) {
> +                return 1; /* XXX */
> +            }
> +            h = negative ? (1ULL << 63) : 0;
> +            h |= exponent << 52;
> +            h |= significand;
> +            ret->val = h;
> +            return 0;
> +        } else { /* XXX */
> +            return 1;
> +        }
> +    } else if (strchr(p, 'e')) {
> +        char *pos;
> +
> +        if (prec == PREC_FLOAT) {
> +            float f = strtof(p, &pos);
> +
> +            if (*pos) {
> +                return 1;
> +            }
> +            ret->val = float_to_u64(f);
> +            return 0;
> +        }
> +        if (prec == PREC_DOUBLE) {
> +            double d = strtod(p, &pos);
> +
> +            if (*pos) {
> +                return 1;
> +            }
> +            ret->val = double_to_u64(d);
> +            return 0;
> +        }
> +        return 0;
> +    } else if (!strcmp(p, "0x0")) {
> +        if (prec == PREC_FLOAT) {
> +            ret->val = float_to_u64(0.0);
> +        } else if (prec == PREC_DOUBLE) {
> +            ret->val = double_to_u64(0.0);
> +        } else {
> +            g_assert_not_reached();
> +        }
> +        return 0;
> +    } else if (!strcmp(p, "0x1")) {
> +        if (prec == PREC_FLOAT) {
> +            ret->val = float_to_u64(1.0);
> +        } else if (prec == PREC_DOUBLE) {
> +            ret->val = double_to_u64(1.0);
> +        } else {
> +            g_assert_not_reached();
> +        }
> +        return 0;
> +    }
> +    return 1;
> +}
> +
> +static int find_op(const char *name, enum op *op)
> +{
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(ops); i++) {
> +        if (strcmp(ops[i].name, name) == 0) {
> +            *op = i;
> +            return 0;
> +        }
> +    }
> +    return 1;
> +}
> +
> +/* Syntax of IBM FP test cases:
> + * https://www.research.ibm.com/haifa/projects/verification/fpgen/syntax.txt
> + */
> +static enum error ibm_test_line(const char *line)
> +{
> +    struct test_op t;
> +    /* at most nine fields; this should be more than enough for each field */
> +    char s[9][64];
> +    char *p;
> +    int n, field;
> +    int i;
> +
> +    /* data lines start with either b32 or d(64|128) */
> +    if (unlikely(line[0] != 'b' && line[0] != 'd')) {
> +        return ERROR_COMMENT;
> +    }
> +    n = sscanf(line, "%63s %63s %63s %63s %63s %63s %63s %63s %63s",
> +               s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
> +    if (unlikely(n < 5 || n > 9)) {
> +        return ERROR_INPUT;
> +    }

Personally I find g_strsplit(line, " ", 9) and g_strfreev() handy for
this sort of parsing.

> +
> +    field = 0;
> +    p = s[field];
> +    if (unlikely(strlen(p) < 4)) {
> +        return ERROR_INPUT;
> +    }
> +    if (strcmp("b32b64cff", p) == 0) {
> +        t.prec = PREC_FLOAT_TO_DOUBLE;
> +        if (find_op(&p[6], &t.op)) {
> +            return ERROR_NOT_HANDLED;
> +        }
> +    } else {
> +        if (strncmp("b32", p, 3) == 0) {
> +            t.prec = PREC_FLOAT;
> +        } else if (strncmp("d64", p, 3) == 0) {
> +            t.prec = PREC_DOUBLE;
> +        } else if (strncmp("d128", p, 4) == 0) {
> +            return ERROR_NOT_HANDLED; /* XXX */
> +        } else {
> +            return ERROR_INPUT;
> +        }
> +        if (find_op(&p[3], &t.op)) {
> +            return ERROR_NOT_HANDLED;
> +        }
> +    }
> +
> +    field = 1;
> +    p = s[field];
> +    if (!strncmp("=0", p, 2)) {
> +        t.round = float_round_nearest_even;
> +    } else {
> +        return ERROR_NOT_HANDLED; /* XXX */
> +    }
> +
> +    /* The trapped exceptions field is optional */
> +    t.trapped_exceptions = 0;
> +    field = 2;
> +    p = s[field];
> +    if (ibm_get_exceptions(p, &t.trapped_exceptions)) {
> +        if (unlikely(n == 9)) {
> +            return ERROR_INPUT;
> +        }
> +    } else {
> +        field++;
> +    }
> +
> +    for (i = 0; i < ops[t.op].n_operands; i++) {
> +        enum precision prec = t.prec == PREC_FLOAT_TO_DOUBLE ?
> +            PREC_FLOAT : t.prec;
> +
> +        p = s[field++];
> +        if (ibm_fp_hex(p, prec, &t.operands[i])) {
> +            return ERROR_INPUT;
> +        }
> +    }
> +
> +    p = s[field++];
> +    if (strcmp("->", p)) {
> +        return ERROR_INPUT;
> +    }
> +
> +    p = s[field++];
> +    if (unlikely(strcmp("#", p) == 0)) {
> +        t.expected_result_is_valid = false;
> +    } else {
> +        enum precision prec = t.prec == PREC_FLOAT_TO_DOUBLE ?
> +            PREC_DOUBLE : t.prec;
> +
> +        if (ibm_fp_hex(p, prec, &t.expected_result)) {
> +            return ERROR_INPUT;
> +        }
> +        t.expected_result_is_valid = true;
> +    }
> +
> +    /*
> +     * A 0 here means "do not check the exceptions", i.e. it does NOT mean
> +     * "there should be no exceptions raised".
> +     */
> +    t.exceptions = 0;
> +    /* the expected exceptions field is optional */
> +    if (field == n - 1) {
> +        p = s[field++];
> +        if (ibm_get_exceptions(p, &t.exceptions)) {
> +            return ERROR_INPUT;
> +        }
> +    }
> +
> +    /*
> +     * We ignore "trapped exceptions" because we're not testing the trapping
> +     * mechanism of the host CPU.
> +     * We test though that the exception bits are correctly set.
> +     */
> +    if (t.trapped_exceptions) {
> +        return ERROR_NOT_HANDLED;
> +    }
> +    return tester->func(&t);
> +}
> +
> +static const struct input valid_input_types[] = {
> +    [INPUT_FMT_IBM] = {
> +        .name = "ibm",
> +        .test_line = ibm_test_line,
> +    },
> +};
> +
> +static const struct input *input_type = &valid_input_types[INPUT_FMT_IBM];
> +
> +static bool line_is_whitelisted(const char *line)
> +{
> +    if (whitelist.ht == NULL) {
> +        return false;
> +    }
> +    return !!g_hash_table_lookup(whitelist.ht, line);
> +}
> +
> +static void test_file(const char *filename)
> +{
> +    static char line[256];
> +    unsigned int i;
> +    FILE *fp;
> +
> +    fp = fopen(filename, "r");
> +    if (fp == NULL) {
> +        fprintf(stderr, "cannot open file '%s': %s\n",
> +                filename, strerror(errno));
> +        exit(EXIT_FAILURE);
> +    }
> +    i = 0;
> +    while (fgets(line, sizeof(line), fp)) {
> +        enum error err;
> +
> +        i++;
> +        if (unlikely(line_is_whitelisted(line))) {
> +            test_stats[ERROR_WHITELISTED]++;
> +            continue;
> +        }
> +        err = input_type->test_line(line);
> +        if (unlikely(is_err(err))) {
> +            switch (err) {
> +            case ERROR_INPUT:
> +                fprintf(stderr, "error: malformed input @ %s:%d:\n",
> +                        filename, i);
> +                break;
> +            case ERROR_RESULT:
> +                fprintf(stderr, "error: result mismatch for input @ %s:%d:\n",
> +                        filename, i);
> +                break;
> +            case ERROR_EXCEPTIONS:
> +                fprintf(stderr, "error: flags mismatch for input @ %s:%d:\n",
> +                        filename, i);
> +                break;
> +            default:
> +                g_assert_not_reached();
> +            }
> +            fprintf(stderr, "%s", line);
> +            if (die_on_error) {
> +                exit(EXIT_FAILURE);
> +            }
> +        }
> +        test_stats[err]++;
> +    }
> +    if (fclose(fp)) {
> +        fprintf(stderr, "warning: cannot close file '%s': %s\n",
> +                filename, strerror(errno));
> +    }
> +}
> +
> +static void set_input_fmt(const char *optarg)
> +{
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(valid_input_types); i++) {
> +        const struct input *type = &valid_input_types[i];
> +
> +        if (strcmp(optarg, type->name) == 0) {
> +            input_type = type;
> +            return;
> +        }
> +    }
> +    fprintf(stderr, "Unknown input format '%s'", optarg);
> +    exit(EXIT_FAILURE);
> +}
> +
> +static void set_tester(const char *optarg)
> +{
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(valid_testers); i++) {
> +        const struct tester *t = &valid_testers[i];
> +
> +        if (strcmp(optarg, t->name) == 0) {
> +            tester = t;
> +            return;
> +        }
> +    }
> +    fprintf(stderr, "Unknown tester '%s'", optarg);
> +    exit(EXIT_FAILURE);
> +}
> +
> +static void whitelist_add_line(const char *orig_line)
> +{
> +    char *line;
> +    bool inserted;
> +
> +    if (whitelist.ht == NULL) {
> +        whitelist.ht = g_hash_table_new(g_str_hash, g_str_equal);
> +    }
> +    line = g_hash_table_lookup(whitelist.ht, orig_line);
> +    if (unlikely(line != NULL)) {
> +        return;
> +    }
> +    whitelist.n++;
> +    whitelist.lines = g_realloc_n(whitelist.lines, whitelist.n, sizeof(line));
> +    line = strdup(orig_line);
> +    whitelist.lines[whitelist.n - 1] = line;
> +    /* if we pass key == val GLib will not reserve space for the value */
> +    inserted = g_hash_table_insert(whitelist.ht, line, line);
> +    g_assert(inserted);
> +}
> +
> +static void set_whitelist(const char *filename)
> +{
> +    FILE *fp;
> +    static char line[256];
> +
> +    fp = fopen(filename, "r");
> +    if (fp == NULL) {
> +        fprintf(stderr, "warning: cannot open white list file '%s': %s\n",
> +                filename, strerror(errno));
> +        return;
> +    }
> +    while (fgets(line, sizeof(line), fp)) {
> +        if (isspace(line[0]) || line[0] == '#') {
> +            continue;
> +        }
> +        whitelist_add_line(line);
> +    }
> +    if (fclose(fp)) {
> +        fprintf(stderr, "warning: cannot close file '%s': %s\n",
> +                filename, strerror(errno));
> +    }
> +}
> +
> +static void set_default_exceptions(const char *str)
> +{
> +    if (ibm_get_exceptions(str, &default_exceptions)) {
> +        fprintf(stderr, "Invalid exception '%s'\n", str);
> +        exit(EXIT_FAILURE);
> +    }
> +}
> +
> +static void usage_complete(int argc, char *argv[])
> +{
> +    fprintf(stderr, "Usage: %s [options] file1 [file2 ...]\n", argv[0]);
> +    fprintf(stderr, "options:\n");
> +    fprintf(stderr, "  -a = Perform tininess detection after rounding "
> +            "(soft tester only). Default: before\n");
> +    fprintf(stderr, "  -n = do not die on error. Default: dies on error\n");
> +    fprintf(stderr, "  -e = default exception flags (xiozu). Default: none\n");
> +    fprintf(stderr, "  -f = format of the input file(s). Default: %s\n",
> +            valid_input_types[0].name);
> +    fprintf(stderr, "  -t = tester. Default: %s\n", valid_testers[0].name);
> +    fprintf(stderr, "  -w = path to file with test cases to be whitelisted\n");
> +    fprintf(stderr, "  -z = flush inputs to zero (soft tester only). "
> +            "Default: disabled\n");
> +    fprintf(stderr, "  -Z = flush output to zero (soft tester only). "
> +            "Default: disabled\n");
> +}
> +
> +static void parse_opts(int argc, char *argv[])
> +{
> +    int c;
> +
> +    for (;;) {
> +        c = getopt(argc, argv, "ae:f:hnt:w:zZ");
> +        if (c < 0) {
> +            return;
> +        }
> +        switch (c) {
> +        case 'a':
> +            soft_status.float_detect_tininess = float_tininess_after_rounding;
> +            break;
> +        case 'e':
> +            set_default_exceptions(optarg);
> +            break;
> +        case 'f':
> +            set_input_fmt(optarg);
> +            break;
> +        case 'h':
> +            usage_complete(argc, argv);
> +            exit(EXIT_SUCCESS);
> +        case 'n':
> +            die_on_error = false;
> +            break;
> +        case 't':
> +            set_tester(optarg);
> +            break;
> +        case 'w':
> +            set_whitelist(optarg);
> +            break;
> +        case 'z':
> +            soft_status.flush_inputs_to_zero = 1;
> +            break;
> +        case 'Z':
> +            soft_status.flush_to_zero = 1;
> +            break;
> +        }
> +    }
> +    g_assert_not_reached();
> +}
> +
> +static uint64_t count_errors(void)
> +{
> +    uint64_t ret = 0;
> +    int i;
> +
> +    for (i = ERROR_INPUT; i < ERROR_MAX; i++) {
> +        ret += test_stats[i];
> +    }
> +    return ret;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +    uint64_t n_errors;
> +    int i;
> +
> +    if (argc == 1) {
> +        usage_complete(argc, argv);
> +        exit(EXIT_FAILURE);
> +    }
> +    parse_opts(argc, argv);
> +    for (i = optind; i < argc; i++) {
> +        test_file(argv[i]);
> +    }
> +
> +    n_errors = count_errors();
> +    if (n_errors) {
> +        printf("Tests failed: %"PRIu64". Parsing: %"PRIu64
> +               ", result:%"PRIu64", flags:%"PRIu64"\n",
> +               n_errors, test_stats[ERROR_INPUT], test_stats[ERROR_RESULT],
> +               test_stats[ERROR_EXCEPTIONS]);
> +    } else {
> +        printf("All tests OK.\n");
> +    }
> +    printf("Tests passed: %" PRIu64 ". Not handled: %" PRIu64
> +           ", whitelisted: %"PRIu64 "\n",
> +           test_stats[ERROR_NONE], test_stats[ERROR_NOT_HANDLED],
> +           test_stats[ERROR_WHITELISTED]);
> +    return !!n_errors;
> +}
> diff --git a/tests/.gitignore b/tests/.gitignore
> index df69175..f9b0f08 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -97,5 +97,6 @@ test-netfilter
>  test-filter-mirror
>  test-filter-redirector
>  *-test
> +!fp-test
>  qapi-schema/*.test.*
>  vm/*.img
> diff --git a/tests/fp-test/.gitignore b/tests/fp-test/.gitignore
> new file mode 100644
> index 0000000..e1e175c
> --- /dev/null
> +++ b/tests/fp-test/.gitignore
> @@ -0,0 +1,3 @@
> +ibm
> +whitelist.txt
> +fp-test
> diff --git a/tests/fp-test/Makefile b/tests/fp-test/Makefile
> new file mode 100644
> index 0000000..703434f
> --- /dev/null
> +++ b/tests/fp-test/Makefile
> @@ -0,0 +1,34 @@
> +BUILD_DIR=$(CURDIR)/../..
> +
> +include ../../config-host.mak
> +include $(SRC_PATH)/rules.mak
> +
> +$(call set-vpath, $(SRC_PATH)/tests/fp-test $(SRC_PATH)/fpu)
> +
> +QEMU_INCLUDES += -I../..
> +QEMU_INCLUDES += -I$(SRC_PATH)/fpu
> +# work around TARGET_* poisoning
> +QEMU_CFLAGS += -DHW_POISON_H
> +
> +IBMFP := ibm-fptests.zip
> +
> +OBJS := fp-test$(EXESUF)
> +
> +WHITELIST_FILES := whitelist.txt whitelist-tininess-after.txt
> +
> +all: $(OBJS) ibm $(WHITELIST_FILES)
> +
> +ibm:
> +	wget -nv -O $(IBMFP) http://www.haifa.il.ibm.com/projects/verification/fpgen/download/test_suite.zip
> +	mkdir -p $@
> +	unzip $(IBMFP) -d $@
> +	rm -rf $(IBMFP)
> +
> +# XXX: upload this to a qemu server, or just commit it.
> +$(WHITELIST_FILES):
> +	wget -nv -O $@ http://www.cs.columbia.edu/~cota/qemu/fpbench-$@
> +
> +fp-test$(EXESUF): fp-test.o softfloat.o
> +
> +clean:
> +	rm -f *.o *.d $(OBJS)


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
@ 2018-03-27 10:15   ` Alex Bennée
  2018-03-27 10:15   ` Alex Bennée
  1 sibling, 0 replies; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 10:15 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> Before 8936006 ("fpu/softfloat: re-factor minmax", 2018-02-21),
> we used to return +Zero for maxnummag(-Zero,+Zero); after that
> commit, we return -Zero.
>
> Fix it by making {min,max}nummag consistent with {min,max}num,
> deferring to the latter when the absolute value of the operands
> is the same.
>
> With this fix we now pass fp-test.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>

Oops. I guess it didn't show up in any of the testing, which is likely
given how poorly RISU exercises the boundary conditions.

I'll grab this patch as I'm fixing up some other bugs in ARM handling.

> ---
>  fpu/softfloat.c | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index e124df9..ee615a9 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -1700,7 +1700,6 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
>          return pick_nan(a, b, s);
>      } else {
>          int a_exp, b_exp;
> -        bool a_sign, b_sign;
>
>          switch (a.cls) {
>          case float_class_normal:
> @@ -1731,20 +1730,22 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
>              break;
>          }
>
> -        a_sign = a.sign;
> -        b_sign = b.sign;
> -        if (ismag) {
> -            a_sign = b_sign = 0;
> +        if (ismag && (a_exp != b_exp || a.frac != b.frac)) {
> +            bool a_less = a_exp < b_exp;
> +            if (a_exp == b_exp) {
> +                a_less = a.frac < b.frac;
> +            }
> +            return a_less ^ ismin ? b : a;
>          }
>
> -        if (a_sign == b_sign) {
> +        if (a.sign == b.sign) {
>              bool a_less = a_exp < b_exp;
>              if (a_exp == b_exp) {
>                  a_less = a.frac < b.frac;
>              }
> -            return a_sign ^ a_less ^ ismin ? b : a;
> +            return a.sign ^ a_less ^ ismin ? b : a;
>          } else {
> -            return a_sign ^ ismin ? b : a;
> +            return a.sign ^ ismin ? b : a;
>          }
>      }
>  }


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
  2018-03-27 10:15   ` Alex Bennée
@ 2018-03-27 10:15   ` Alex Bennée
  1 sibling, 0 replies; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 10:15 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> Before 8936006 ("fpu/softfloat: re-factor minmax", 2018-02-21),
> we used to return +Zero for maxnummag(-Zero,+Zero); after that
> commit, we return -Zero.
>
> Fix it by making {min,max}nummag consistent with {min,max}num,
> deferring to the latter when the absolute value of the operands
> is the same.
>
> With this fix we now pass fp-test.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  fpu/softfloat.c | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index e124df9..ee615a9 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -1700,7 +1700,6 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
>          return pick_nan(a, b, s);
>      } else {
>          int a_exp, b_exp;
> -        bool a_sign, b_sign;
>
>          switch (a.cls) {
>          case float_class_normal:
> @@ -1731,20 +1730,22 @@ static FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin,
>              break;
>          }
>
> -        a_sign = a.sign;
> -        b_sign = b.sign;
> -        if (ismag) {
> -            a_sign = b_sign = 0;
> +        if (ismag && (a_exp != b_exp || a.frac != b.frac)) {
> +            bool a_less = a_exp < b_exp;
> +            if (a_exp == b_exp) {
> +                a_less = a.frac < b.frac;
> +            }
> +            return a_less ^ ismin ? b : a;
>          }
>
> -        if (a_sign == b_sign) {
> +        if (a.sign == b.sign) {
>              bool a_less = a_exp < b_exp;
>              if (a_exp == b_exp) {
>                  a_less = a.frac < b.frac;
>              }
> -            return a_sign ^ a_less ^ ismin ? b : a;
> +            return a.sign ^ a_less ^ ismin ? b : a;
>          } else {
> -            return a_sign ^ ismin ? b : a;
> +            return a.sign ^ ismin ? b : a;
>          }
>      }
>  }


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants Emilio G. Cota
@ 2018-03-27 11:33   ` Alex Bennée
  2018-03-27 18:03     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 11:33 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> These are a few muladd-related operations that the original IBM syntax
> does not specify; model files for these are in muladd.fptest.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  tests/fp-test/fp-test.c     | 24 +++++++++++++++++++++
>  tests/fp-test/muladd.fptest | 51 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 75 insertions(+)
>  create mode 100644 tests/fp-test/muladd.fptest
>
> diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
> index 27637c4..2200d40 100644
> --- a/tests/fp-test/fp-test.c
> +++ b/tests/fp-test/fp-test.c
> @@ -53,6 +53,9 @@ enum op {
>      OP_SUB,
>      OP_MUL,
>      OP_MULADD,
> +    OP_MULADD_NEG_ADDEND,
> +    OP_MULADD_NEG_PRODUCT,
> +    OP_MULADD_NEG_RESULT,
>      OP_DIV,
>      OP_SQRT,
>      OP_MINNUM,
> @@ -69,6 +72,9 @@ static const struct op_desc ops[] = {
>      [OP_SUB] =       { "-", 2 },
>      [OP_MUL] =       { "*", 2 },
>      [OP_MULADD] =    { "*+", 3 },
> +    [OP_MULADD_NEG_ADDEND] =  { "*+nc", 3 },
> +    [OP_MULADD_NEG_PRODUCT] = { "*+np", 3 },
> +    [OP_MULADD_NEG_RESULT] =  { "*+nr", 3 },
>      [OP_DIV] =       { "/", 2 },
>      [OP_SQRT] =      { "V", 1 },
>      [OP_MINNUM] =    { "<C", 2 },
> @@ -463,6 +469,15 @@ static enum error soft_tester(struct test_op *t)
>          case OP_MULADD:
>              res = float32_muladd(a, b, c, 0, s);
>              break;
> +        case OP_MULADD_NEG_ADDEND:
> +            res = float32_muladd(a, b, c, float_muladd_negate_c, s);
> +            break;
> +        case OP_MULADD_NEG_PRODUCT:
> +            res = float32_muladd(a, b, c, float_muladd_negate_product, s);
> +            break;
> +        case OP_MULADD_NEG_RESULT:
> +            res = float32_muladd(a, b, c, float_muladd_negate_result, s);
> +            break;
>          case OP_DIV:
>              res = float32_div(a, b, s);
>              break;
> @@ -522,6 +537,15 @@ static enum error soft_tester(struct test_op *t)
>          case OP_MULADD:
>              res64 = float64_muladd(a, b, c, 0, s);
>              break;
> +        case OP_MULADD_NEG_ADDEND:
> +            res64 = float64_muladd(a, b, c, float_muladd_negate_c, s);
> +            break;
> +        case OP_MULADD_NEG_PRODUCT:
> +            res64 = float64_muladd(a, b, c, float_muladd_negate_product, s);
> +            break;
> +        case OP_MULADD_NEG_RESULT:
> +            res64 = float64_muladd(a, b, c, float_muladd_negate_result, s);
> +            break;
>          case OP_DIV:
>              res64 = float64_div(a, b, s);
>              break;

Are there any intrinsics we could use for the hard variant which would
be useful if we want to run under translation?

> diff --git a/tests/fp-test/muladd.fptest b/tests/fp-test/muladd.fptest
> new file mode 100644
> index 0000000..6cd48ff
> --- /dev/null
> +++ b/tests/fp-test/muladd.fptest
> @@ -0,0 +1,51 @@
> +# nc == negate addend
> +b32*+nc =0 -Inf -Inf +Inf -> Q i
> +b32*+nc =0 -1.7FFFFFP127 -Inf +Inf -> Q i
> +b32*+nc =0 -1.6C9AE7P113 -Inf +Inf -> Q i
> +b32*+nc =0 -1.000000P-126 -Inf +Inf -> Q i
> +b32*+nc =0 -0.7FFFFFP-126 -Inf +Inf -> Q i
> +b32*+nc =0 -0.1B977AP-126 -Inf +Inf -> Q i
> +b32*+nc =0 -0.000001P-126 -Inf +Inf -> Q i
> +b32*+nc =0 -1.000000P0 -Inf +Inf -> Q i
> +b32*+nc =0 -Zero -Inf +Inf -> Q i
> +b32*+nc =0 +Zero -Inf +Inf -> Q i
> +b32*+nc =0 -Zero -1.000000P-126 +1.7FFFFFP127 -> -1.7FFFFFP127
> +b32*+nc =0 +Zero -1.000000P-126 +1.7FFFFFP127 -> -1.7FFFFFP127
> +b32*+nc =0 -1.000000P-126 -1.7FFFFFP127 -1.4B9156P109 -> +1.4B9156P109 x
> +b32*+nc =0 -0.7FFFFFP-126 -1.7FFFFFP127 -1.51BA59P-113 -> +1.7FFFFDP1 x
> +b32*+nc =0 -0.3D6B57P-126 -1.7FFFFFP127 -1.265398P-67 -> +1.75AD5BP0 x
> +b32*+nc =0 -0.000001P-126 -1.7FFFFFP127 -1.677330P-113 -> +1.7FFFFFP-22 x
> +
> +# np == negate product
> +b32*+np =0 +Inf -Inf -Inf -> Q i
> +b32*+np =0 +1.7FFFFFP127 -Inf -Inf -> Q i
> +b32*+np =0 +1.6C9AE7P113 -Inf -Inf -> Q i
> +b32*+np =0 +1.000000P-126 -Inf -Inf -> Q i
> +b32*+np =0 +0.7FFFFFP-126 -Inf -Inf -> Q i
> +b32*+np =0 +0.1B977AP-126 -Inf -Inf -> Q i
> +b32*+np =0 +0.000001P-126 -Inf -Inf -> Q i
> +b32*+np =0 +1.000000P0 -Inf -Inf -> Q i
> +b32*+np =0 +Zero -Inf -Inf -> Q i
> +b32*+np =0 +Zero -Inf -Inf -> Q i
> +b32*+np =0 -Zero -1.000000P-126 -1.7FFFFFP127 -> -1.7FFFFFP127
> +b32*+np =0 +Zero -1.000000P-126 -1.7FFFFFP127 -> -1.7FFFFFP127
> +b32*+np =0 -1.3A6A89P-18 +1.24E7AEP9 -0.7FFFFFP-126 -> +1.7029E9P-9 x
> +
> +# nr == negate result
> +b32*+nr =0 -Inf -Inf -Inf -> Q i
> +b32*+nr =0 -1.7FFFFFP127 -Inf -Inf -> Q i
> +b32*+nr =0 -1.6C9AE7P113 -Inf -Inf -> Q i
> +b32*+nr =0 -1.000000P-126 -Inf -Inf -> Q i
> +b32*+nr =0 -0.7FFFFFP-126 -Inf -Inf -> Q i
> +b32*+nr =0 -0.1B977AP-126 -Inf -Inf -> Q i
> +b32*+nr =0 -0.000001P-126 -Inf -Inf -> Q i
> +b32*+nr =0 -1.000000P0 -Inf -Inf -> Q i
> +b32*+nr =0 -Zero -Inf -Inf -> Q i
> +b32*+nr =0 -Zero -Inf -Inf -> Q i
> +b32*+nr =0 +Zero -1.000000P-126 -1.7FFFFFP127 -> +1.7FFFFFP127
> +b32*+nr =0 -Zero -1.000000P-126 -1.7FFFFFP127 -> +1.7FFFFFP127
> +b32*+nr =0 -1.000000P-126 -1.7FFFFFP127 -1.4B9156P109 -> +1.4B9156P109 x
> +b32*+nr =0 -0.7FFFFFP-126 -1.7FFFFFP127 -1.51BA59P-113 -> -1.7FFFFDP1 x
> +b32*+nr =0 -0.3D6B57P-126 -1.7FFFFFP127 -1.265398P-67 -> -1.75AD5BP0 x
> +b32*+nr =0 -0.000001P-126 -1.7FFFFFP127 -1.677330P-113 -> -1.7FFFFFP-22 x
> +b32*+nr =0 +1.72E53AP-33 -1.7FFFFFP127 -1.5AA684P-2 -> +1.72E539P95 x


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal Emilio G. Cota
@ 2018-03-27 11:34   ` Alex Bennée
  2018-03-27 18:05     ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 11:34 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> This paves the way for upcoming work.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  include/fpu/softfloat.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 36626a5..7b9d31c 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -402,6 +402,11 @@ static inline int float32_is_zero(float32 a)
>      return (float32_val(a) & 0x7fffffff) == 0;
>  }
>
> +static inline bool float32_is_normal(float32 a)
> +{
> +    return ((float32_val(a) + 0x00800000) & 0x7fffffff) >= 0x01000000;
> +}
> +
>  static inline int float32_is_any_nan(float32 a)
>  {
>      return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
> @@ -531,6 +536,11 @@ static inline int float64_is_zero(float64 a)
>      return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
>  }
>
> +static inline bool float64_is_normal(float64 a)
> +{
> +    return ((float64_val(a) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
> +}
> +
>  static inline int float64_is_any_nan(float64 a)
>  {
>      return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal Emilio G. Cota
@ 2018-03-27 11:35   ` Alex Bennée
  0 siblings, 0 replies; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 11:35 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> This paves the way for upcoming work.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  include/fpu/softfloat.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 7b9d31c..8fb44a8 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -417,6 +417,11 @@ static inline int float32_is_zero_or_denormal(float32 a)
>      return (float32_val(a) & 0x7f800000) == 0;
>  }
>
> +static inline bool float32_is_denormal(float32 a)
> +{
> +    return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
> +}
> +
>  static inline float32 float32_set_sign(float32 a, int sign)
>  {
>      return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
> @@ -551,6 +556,11 @@ static inline int float64_is_zero_or_denormal(float64 a)
>      return (float64_val(a) & 0x7ff0000000000000LL) == 0;
>  }
>
> +static inline bool float64_is_denormal(float64 a)
> +{
> +    return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
> +}
> +
>  static inline float64 float64_set_sign(float64 a, int sign)
>  {
>      return make_float64((float64_val(a) & 0x7fffffffffffffffULL)


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-22 19:57         ` Emilio G. Cota
@ 2018-03-27 11:41           ` Alex Bennée
  2018-03-27 18:08             ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 11:41 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: Richard Henderson, qemu-devel, Aurelien Jarno, Peter Maydell,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> On Thu, Mar 22, 2018 at 14:41:05 +0800, Richard Henderson wrote:
> (snip)
>> Another thought re all of the soft_is_normal || soft_is_zero checks that you're
>> performing.  I think it would be nice if we could work with
>> float*_unpack_canonical so that we don't have to duplicate work.  E.g.
>>
>> /* Return true for float_class_normal && float_class_zero.  */
>> static inline bool is_finite(FloatClass c) { return c <= float_class_zero; }
>>
>> float32 float32_add(float32 a, float32 b, float_status *s)
>> {
>>   FloatClass a_cls = float32_classify(a);
>>   FloatClass b_cls = float32_classify(b);
>
> Just looked at this. It can be done, although it comes at the
> price of some performance for fp-bench -o add:
> 180 Mflops vs. 196 Mflops, i.e. a 8% slowdown. That is with
> adequate inlining etc., otherwise perf is worse.
>
> I'm not convinced that we can gain much in simplicity to
> justify the perf impact. Yes, we'd simplify canonicalize(),
> but we'd probably need a float_class_denormal[*], which
> would complicate everything else.
>
> I think it makes sense to keep some inlines that work on
> the float32/64's directly.
>
>>   if (is_finite(a_cls) && is_finite(b_cls) && ...) {
>>       /* do hardfp thing */
>>   }
>
> [*] Taking 0, denormals and normals would be OK from correctness,
> but we really don't want to compute ops with denormal inputs on
> the host; it is very likely that the output will also be denormal,
> and we'll end up deferring to soft-fp anyway to avoid
> computing whether the underflow exception has occurred,
> which is expensive.
>
>>   pa = float32_unpack(a, ca, s);
>>   pb = float32_unpack(b, cb, s);
>>   pr = addsub_floats(pa, pb, s, false);
>>   return float32_round_pack(pr, s);
>> }
>
> It pays off to have two separate functions (add & sub) for the
> slow path. With soft_f32_add/sub factored out:
>
> $ taskset -c 0 x86_64-linux-user/qemu-x86_64 tests/fp-bench -o add
> 197.53 MFlops
>
> With the above four lines (pa...return) as an else branch:
> 169.16 MFlops
>
> BTW flattening makes things worse (150.63 MFlops).

That's disappointing. Did you look at the generated code? Because the
way we are abusing __flatten__ to effectively make a compile time
template you would hope it could pull the relevant classify bits to
before the hard float branch and do the rest later if needed.

Everything was inline or in softfloat.c for this test right?

>
> Note that fp-bench only tests normal numbers. But I think it's fair
> to assume that this is the path we want to speed up.
>
> Thanks,
>
> 		E.


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat
  2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat Emilio G. Cota
  2018-03-21 20:41   ` Laurent Vivier
@ 2018-03-27 11:49   ` Alex Bennée
  2018-03-27 18:16     ` Emilio G. Cota
  1 sibling, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-27 11:49 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> The appended paves the way for leveraging the host FPU for a subset
> of guest FP operations. For most guest workloads (e.g. FP flags
> aren't ever cleared, inexact occurs often and rounding is set to the
> default [to nearest]) this will yield sizable performance speedups.
>
> The approach followed here avoids checking the FP exception flags register.
> See the comment at the top of hostfloat.c for details.
>
> This assumes that QEMU is running on an IEEE754-compliant FPU and
> that the rounding is set to the default (to nearest). The
> implementation-dependent specifics of the FPU should not matter; things
> like tininess detection and snan representation are still dealt with in
> soft-fp. However, this approach will break on most hosts if we compile
> QEMU with flags such as -ffast-math. We control the flags so this should
> be easy to enforce though.

The thing I would avoid is generating is any x87 instructions as we can
get weird effects if the compiler ever decides to stash a signalling NaN
in an x87 register.

Anyway perhaps -fno-fast-math should be explicit when building fpu/* code?

>
> The licensing in softfloat.h is complicated at best, so to keep things
> simple I'm adding this as a separate, GPL'ed file.

I don't think we need to worry about this. It's fine to add GPL only
stuff to softfloat.c and since the re-factoring (or before really) we
"own" this code and are unlikely to upstream anything.

My preference would be to include this all in softfloat.c unless there
is a very good reason not to.

>
> This patch just adds some boilerplate code; subsequent patches add
> operations, one per commit to ease bisection.
>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  Makefile.target           |  2 +-
>  include/fpu/hostfloat.h   | 14 +++++++
>  include/fpu/softfloat.h   |  1 +
>  fpu/hostfloat.c           | 96 +++++++++++++++++++++++++++++++++++++++++++++++
>  target/m68k/Makefile.objs |  2 +-
>  tests/fp-test/Makefile    |  2 +-
>  6 files changed, 114 insertions(+), 3 deletions(-)
>  create mode 100644 include/fpu/hostfloat.h
>  create mode 100644 fpu/hostfloat.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 6549481..efcdfb9 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -97,7 +97,7 @@ obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o
>  obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o
>  obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o
>  obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
> -obj-y += fpu/softfloat.o
> +obj-y += fpu/softfloat.o fpu/hostfloat.o
>  obj-y += target/$(TARGET_BASE_ARCH)/
>  obj-y += disas.o
>  obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
> diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h
> new file mode 100644
> index 0000000..b01291b
> --- /dev/null
> +++ b/include/fpu/hostfloat.h
> @@ -0,0 +1,14 @@
> +/*
> + * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
> + *
> + * License: GNU GPL, version 2 or later.
> + *   See the COPYING file in the top-level directory.
> + */
> +#ifndef HOSTFLOAT_H
> +#define HOSTFLOAT_H
> +
> +#ifndef SOFTFLOAT_H
> +#error fpu/hostfloat.h must only be included from softfloat.h
> +#endif
> +
> +#endif /* HOSTFLOAT_H */
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 8fb44a8..8963b68 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -95,6 +95,7 @@ enum {
>  };
>
>  #include "fpu/softfloat-types.h"
> +#include "fpu/hostfloat.h"
>
>  static inline void set_float_detect_tininess(int val, float_status *status)
>  {
> diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c
> new file mode 100644
> index 0000000..cab0341
> --- /dev/null
> +++ b/fpu/hostfloat.c
> @@ -0,0 +1,96 @@
> +/*
> + * hostfloat.c - FP primitives that use the host's FPU whenever possible.
> + *
> + * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
> + *
> + * License: GNU GPL, version 2 or later.
> + *   See the COPYING file in the top-level directory.
> + *
> + * Fast emulation of guest FP instructions is challenging for two reasons.
> + * First, FP instruction semantics are similar but not identical, particularly
> + * when handling NaNs. Second, emulating at reasonable speed the guest FP
> + * exception flags is not trivial: reading the host's flags register with a
> + * feclearexcept & fetestexcept pair is slow [slightly slower than soft-fp],
> + * and trapping on every FP exception is not fast nor pleasant to work with.
> + *
> + * This module leverages the host FPU for a subset of the operations. To
> + * do this it follows the main idea presented in this paper:
> + *
> + * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions in a
> + * binary translator." Software: Practice and Experience 46.12 (2016):1591-1615.
> + *
> + * The idea is thus to leverage the host FPU to (1) compute FP operations
> + * and (2) identify whether FP exceptions occurred while avoiding
> + * expensive exception flag register accesses.
> + *
> + * An important optimization shown in the paper is that given that exception
> + * flags are rarely cleared by the guest, we can avoid recomputing some flags.
> + * This is particularly useful for the inexact flag, which is very frequently
> + * raised in floating-point workloads.
> + *
> + * We optimize the code further by deferring to soft-fp whenever FP
> + * exception detection might get hairy. Fortunately this is not common.
> + */
> +#include <math.h>
> +
> +#include "qemu/osdep.h"
> +#include "fpu/softfloat.h"
> +
> +#define GEN_TYPE_CONV(name, to_t, from_t)       \
> +    static inline to_t name(from_t a)           \
> +    {                                           \
> +        to_t r = *(to_t *)&a;                   \
> +        return r;                               \
> +    }
> +
> +GEN_TYPE_CONV(float32_to_float, float, float32)
> +GEN_TYPE_CONV(float64_to_double, double, float64)
> +GEN_TYPE_CONV(float_to_float32, float32, float)
> +GEN_TYPE_CONV(double_to_float64, float64, double)
> +#undef GEN_TYPE_CONV
> +
> +#define GEN_INPUT_FLUSH(soft_t)                                         \
> +    static inline __attribute__((always_inline)) void                   \
> +    soft_t ## _input_flush__nocheck(soft_t *a, float_status *s)         \
> +    {                                                                   \
> +        if (unlikely(soft_t ## _is_denormal(*a))) {                     \
> +            *a = soft_t ## _set_sign(soft_t ## _zero,                   \
> +                                     soft_t ## _is_neg(*a));            \
> +            s->float_exception_flags |= float_flag_input_denormal;      \
> +        }                                                               \
> +    }                                                                   \
> +                                                                        \
> +    static inline __attribute__((always_inline)) void                   \
> +    soft_t ## _input_flush1(soft_t *a, float_status *s)                 \
> +    {                                                                   \
> +        if (likely(!s->flush_inputs_to_zero)) {                         \
> +            return;                                                     \
> +        }                                                               \
> +        soft_t ## _input_flush__nocheck(a, s);                          \
> +    }                                                                   \
> +                                                                        \
> +    static inline __attribute__((always_inline)) void                   \
> +    soft_t ## _input_flush2(soft_t *a, soft_t *b, float_status *s)      \
> +    {                                                                   \
> +        if (likely(!s->flush_inputs_to_zero)) {                         \
> +            return;                                                     \
> +        }                                                               \
> +        soft_t ## _input_flush__nocheck(a, s);                          \
> +        soft_t ## _input_flush__nocheck(b, s);                          \
> +    }                                                                   \
> +                                                                        \
> +    static inline __attribute__((always_inline)) void                   \
> +    soft_t ## _input_flush3(soft_t *a, soft_t *b, soft_t *c,            \
> +                            float_status *s)                            \
> +    {                                                                   \
> +        if (likely(!s->flush_inputs_to_zero)) {                         \
> +            return;                                                     \
> +        }                                                               \
> +        soft_t ## _input_flush__nocheck(a, s);                          \
> +        soft_t ## _input_flush__nocheck(b, s);                          \
> +        soft_t ## _input_flush__nocheck(c, s);                          \
> +    }
> +
> +GEN_INPUT_FLUSH(float32)
> +GEN_INPUT_FLUSH(float64)

Having spent time getting rid of a bunch of macro expansions I'm wary of
adding more in. However for these I guess it's kind of marginal.

> +#undef GEN_INPUT_FLUSH
> diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
> index ac61948..2868b11 100644
> --- a/target/m68k/Makefile.objs
> +++ b/target/m68k/Makefile.objs
> @@ -1,5 +1,5 @@
>  obj-y += m68k-semi.o
>  obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += fpu_helper.o softfloat.o
> +obj-y += fpu_helper.o softfloat.o hostfloat.o
>  obj-y += gdbstub.o
>  obj-$(CONFIG_SOFTMMU) += monitor.o
> diff --git a/tests/fp-test/Makefile b/tests/fp-test/Makefile
> index 703434f..187cfcc 100644
> --- a/tests/fp-test/Makefile
> +++ b/tests/fp-test/Makefile
> @@ -28,7 +28,7 @@ ibm:
>  $(WHITELIST_FILES):
>  	wget -nv -O $@ http://www.cs.columbia.edu/~cota/qemu/fpbench-$@
>
> -fp-test$(EXESUF): fp-test.o softfloat.o
> +fp-test$(EXESUF): fp-test.o softfloat.o hostfloat.o
>
>  clean:
>  	rm -f *.o *.d $(OBJS)


--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks
  2018-03-27  8:45   ` Alex Bennée
@ 2018-03-27 17:21     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 17:21 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 09:45:14 +0100, Alex Bennée wrote:
> Emilio G. Cota <cota@braap.org> writes:
(snip)
> > +/*
> > + * Disable optimizations (e.g. "a OP b" outside of the inner loop) with
> > + * volatile.
> > + */
> > +#define GEN_BENCH_1OPF(NAME, FUNC, PRECISION)                           \
> > +    static void NAME(volatile PRECISION *res)                           \
> > +    {                                                                   \
> > +        uint64_t ra = SEED_A;                                           \
> > +        uint64_t i, j;                                                  \
> > +                                                                        \
> > +        for (i = 0; i < n_ops; i += OPS_PER_ITER) {                     \
> > +            volatile PRECISION a = glue(get_random_, PRECISION)(&ra);   \
> > +                                                                        \
> > +            for (j = 0; j < OPS_PER_ITER; j++) {                        \
> > +                *res = FUNC(a);                                         \
> > +            }                                                           \
> > +        }                                                               \
> > +    }
> > +
> 
> Have you had a chance to look at if this will vectorise? I have a
> similar benchmark which I compile with multiple options to test normal,
> NEON/AdvSIMD and SVE enabled loops.

It does not. I'm pretty sure the volatile there prevents the compiler
from doing anything smart. In this case I don't want the compiler
to vectorise though, but I can see how that would be a nice
benchmark to have in addition to the above.

> > +        case 'p':
> > +            precision = optarg;
> > +            if (strcmp(precision, "float") &&
> > +                strcmp(precision, "single") &&
> > +                strcmp(precision, "double")) {
> > +                fprintf(stderr, "Unsupported precision '%s'\n", precision);
> > +                exit(EXIT_FAILURE);
> 
> Supporting half-precision if the compiler does would also be useful here.

I wasn't speeding those up so didn't care to test them. But yes I can see how
that could be useful for arm/aarch64; we can add it later.

> > diff --git a/tests/Makefile.include b/tests/Makefile.include
> > index ef9b88c..f6121ee 100644
> > --- a/tests/Makefile.include
> > +++ b/tests/Makefile.include
> > @@ -587,7 +587,7 @@ test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
> >  	tests/rcutorture.o tests/test-rcu-list.o \
> >  	tests/test-qdist.o tests/test-shift128.o \
> >  	tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
> > -	tests/atomic_add-bench.o
> > +	tests/atomic_add-bench.o tests/fp-bench.o
> 
> Not sure why but "make check" didn't build this. I had to explicitly
> "make tests/fp-bench". I guess along with atomic_add_bench though these
> are explicitly guest facing tests so maybe we should move them once
> tests/tcg is working again. I'll have another run at that this week.

That was intentional; these are benchmarks rather than tests so I
wouldn't expect make check to build them or run them at all. So that was 


> >  $(test-obj-y): QEMU_INCLUDES += -Itests
> >  QEMU_CFLAGS += -I$(SRC_PATH)/tests
> > @@ -639,6 +639,7 @@ tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(tes
> >  tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
> >  tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
> >  tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
> > +tests/fp-bench$(EXESUF): tests/fp-bench.o $(test-util-obj-y)
> >
> >  tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
> >  	hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
> 
> Anyway for this version:
> 
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

Thanks! I'll keep this for v3 (I sent v2 yesterday), since not
much changed.

If I had more time to work on this I'd like to have a -t soft/host flag
like in fp-test. Right now there is no such flag so we default to "host";
IOW, we end up testing the performance of the whole sausage, i.e. guest
compiler + QEMU. This is useful because it represents real-life
scenarios. However, if we tested the functions in fpu/ directly,
we'd get benchmarking that (1) would be more sensitive to the functions
we want to benchmark, and (2) would not depend on the particular
implementation of the QEMU target (e.g. i386 does not emit fma
at all!).

Thanks,

		Emilio

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite
  2018-03-27 10:13   ` Alex Bennée
@ 2018-03-27 18:00     ` Emilio G. Cota
  2018-03-28  9:51       ` Alex Bennée
  0 siblings, 1 reply; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 18:00 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 11:13:01 +0100, Alex Bennée wrote:
> 
> Emilio G. Cota <cota@braap.org> writes:
> 
> > This will allow us to run correctness tests against our
> > FP implementation. The test can be run in two modes (called
> > "testers"): host and soft. With the former we check the results
> > and FP flags on the host machine against the model.
> > With the latter we check QEMU's fpu primitives against the
> > model. Note that in soft mode we are not instantiating any
> > particular CPU (hence the HW_POISON_H hack to avoid macro poisoning);
> > for that we need to run the test in host mode under QEMU.
> >
> > The input files are taken from IBM's FPGen test suite:
> > https://www.research.ibm.com/haifa/projects/verification/fpgen/
> >
> > I see no license file in there so I am just downloading them
> > with wget. We might want to keep a copy on a qemu server though,
> > in case IBM takes those files down in the future.
> 
> Hmm the files themselves have:
> 
>   Copyright of IBM Corp. 2005
> 
> So I'm not sure we can take them into any of our source trees.

Yes I don't think committing these would be appropriate. I guess keeping
our own copy of the tarball somewhere would be OK, though. My worry is
that at some point IBM's server will die and we'll have no more test
files.

> However what are we testing here?

fp-test allows you to test against a model. This model can be anything;
for now, I grabbed model files from IBM's fpgen, which tests for
IEEE compliance.

We can add more model files; the muladd tests are an example of that.

> Do we just want to test our implementation is IEEE compliant or should
> we generate our own test cases on validated hardware to check that our
> emulation of a guest is correct (e.g. correct modulo the valid
> variations in the standard)?

I think what we want is a large core of tests that test the standard,
plus a smaller set of tests that cover ISA particularities. I think
the IBM models are a good starting point for the former -- note
though that some operations are not covered in the models (despite
the syntax description specifying an op for them, e.g. int-to-float
conversions.)

> > The "IBM" syntax of those files (for now the only syntax supported
> > in fp-test) is documented here:
> > https://www.research.ibm.com/haifa/projects/verification/fpgen/papers/ieee-test-suite-v2.pdf
> >
> > Note that the syntax document has some inaccuracies; the appended
> > parsing code works around some of those.
> >
> > The exception flag (-e) is important: many of the optimizations
> > included in the following commits assume that the inexact flag
> > is set, so "-e x" is necessary in order to test those code paths.
> >
> > The whitelist flag (-w) points to a file with test cases to be ignored.
> > I have put some whitelist files online, but we should have them
> > on a QEMU-related server.
> >
> > Thus, a typical of fp-test is as follows:
> >
> >   $ cd qemu/build/tests/fp-test
> >   $ make -j && \
> > 	./fp-test -t soft ibm/*.fptest \
> > 	-w whitelist.txt \
> > 	-e x
> 
> So this is a unit test of our code rather than a test program running
> under QEMU?

Having the -t host/soft flags allows you flexibility in what to test.

With "host" mode, you're generating a binary that knows nothing
about QEMU, i.e. all its FP operations are native. You can use this
to (1) figure out whether your host diverts from the model [hopefully
it doesn't in anything substantial], and (2) test whether QEMU mimics
the corresponding host by running the binary under *-linux-user.

With "soft" mode, you're testing QEMU's soft-fp implementation. This
allows you to check it against the model. Note that it doesn't let
you check anything specific about a target CPU (hence the HW_POISON_H
hack); for this you'd have to go to point (2) above. Here instead we're
checking QEMU's FP implementation directly against the models.

>  I noted running under x86-64-linux-user fails pretty quick.

As I wrote below, I think this is due to bugs in the i386 target.

On a host x86_64 machine:
$ ./fp-test -t host ibm/* -w whitelist.txt -w whitelist-tininess-after.txt
All tests OK.
Tests passed: 74426. Not handled: 53297, whitelisted: 2748

$ ../../x86_64-linux-user/qemu-x86_64 ./fp-test -t host \
	ibm/* -w whitelist.txt -w whitelist-tininess-after.txt -n 2>/dev/null
Tests failed: 57479. Parsing: 0, result:14, flags:57465
Tests passed: 16947. Not handled: 53297, whitelisted: 2748

The results are different when run under QEMU, which means
this target is not doing things correctly (despite -t soft
passing).

> If so we really should be building this automatically in make check.

Yes, passing -soft mode would certainly be valuable and trivial
to integrate since there is nothing built that is target-dependent.

(snip)
> > --- /dev/null
> > +++ b/tests/fp-test/fp-test.c
(snip)
> > +enum precision {
> > +    PREC_FLOAT,
> > +    PREC_DOUBLE,
> > +    PREC_QUAD,
> > +    PREC_FLOAT_TO_DOUBLE,
> > +};
> 
> Again we will want to include half-precision.

Sure. We'll need to come up with model files for that though.

(snip)
> > +    }
> > +    if (unlikely(!strcmp("-inf", p) || !strcmp("-Inf", p))) {
> > +        ret->val = fp_choose(prec, 0xff800000, 0xfff0000000000000);
> > +        return 0;
> > +    }
> > +
> > +    len = strlen(p);
> > +
> > +    if (strchr(p, 'P')) {
> 
> Given we have already strlen'ed should we use memchr(p, 'P', len) or
> even strchrnul(p,'P') with a check we haven't run over the end? OR maybe
> use glib's string stuff instead.

I think in this case strchr is warranted; p points to a valid string
(otherwise strlen would also be dangerous).

(snip)
> > +/* Syntax of IBM FP test cases:
> > + * https://www.research.ibm.com/haifa/projects/verification/fpgen/syntax.txt
> > + */
> > +static enum error ibm_test_line(const char *line)
> > +{
> > +    struct test_op t;
> > +    /* at most nine fields; this should be more than enough for each field */
> > +    char s[9][64];
> > +    char *p;
> > +    int n, field;
> > +    int i;
> > +
> > +    /* data lines start with either b32 or d(64|128) */
> > +    if (unlikely(line[0] != 'b' && line[0] != 'd')) {
> > +        return ERROR_COMMENT;
> > +    }
> > +    n = sscanf(line, "%63s %63s %63s %63s %63s %63s %63s %63s %63s",
> > +               s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
> > +    if (unlikely(n < 5 || n > 9)) {
> > +        return ERROR_INPUT;
> > +    }
> 
> Personally I find g_strsplit(line, " ", 9) and g_strfreev() handy for
> this sort of parsing.

I figured the above might be simpler since I wouldn't have to worry
about freeing memory. Also, scanf directly returns n, which is used
later.

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants
  2018-03-27 11:33   ` Alex Bennée
@ 2018-03-27 18:03     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 18:03 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 12:33:55 +0100, Alex Bennée wrote:
> Emilio G. Cota <cota@braap.org> writes:
> 
> > These are a few muladd-related operations that the original IBM syntax
> > does not specify; model files for these are in muladd.fptest.
> >
> > Signed-off-by: Emilio G. Cota <cota@braap.org>
(snip)
> > +        case OP_MULADD_NEG_ADDEND:
> > +            res64 = float64_muladd(a, b, c, float_muladd_negate_c, s);
> > +            break;
> > +        case OP_MULADD_NEG_PRODUCT:
> > +            res64 = float64_muladd(a, b, c, float_muladd_negate_product, s);
> > +            break;
> > +        case OP_MULADD_NEG_RESULT:
> > +            res64 = float64_muladd(a, b, c, float_muladd_negate_result, s);
> > +            break;
> >          case OP_DIV:
> >              res64 = float64_div(a, b, s);
> >              break;
> 
> Are there any intrinsics we could use for the hard variant which would
> be useful if we want to run under translation?

I don't know of any portable way of doing this. We could add some
arch-specific code though, suitably ifdef'ed.

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal
  2018-03-27 11:34   ` Alex Bennée
@ 2018-03-27 18:05     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 18:05 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 12:34:57 +0100, Alex Bennée wrote:
> 
> Emilio G. Cota <cota@braap.org> writes:
> 
> > This paves the way for upcoming work.
> >
> > Signed-off-by: Emilio G. Cota <cota@braap.org>
> 
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

(snip)
On Tue, Mar 27, 2018 at 12:35:07 +0100, Alex Bennée wrote:
> 
> Emilio G. Cota <cota@braap.org> writes:
> 
> > This paves the way for upcoming work.
> >
> > Signed-off-by: Emilio G. Cota <cota@braap.org>
> 
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

In v2 I merged these two into the same commit, so I've added your
R-b tag to the corresponding commit in v3.

Thanks,

		Emilio

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction
  2018-03-27 11:41           ` Alex Bennée
@ 2018-03-27 18:08             ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 18:08 UTC (permalink / raw)
  To: Alex Bennée
  Cc: Richard Henderson, qemu-devel, Aurelien Jarno, Peter Maydell,
	Laurent Vivier, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 12:41:18 +0100, Alex Bennée wrote:
> 
> Emilio G. Cota <cota@braap.org> writes:
> 
> > On Thu, Mar 22, 2018 at 14:41:05 +0800, Richard Henderson wrote:
> > (snip)
> >> Another thought re all of the soft_is_normal || soft_is_zero checks that you're
> >> performing.  I think it would be nice if we could work with
> >> float*_unpack_canonical so that we don't have to duplicate work.  E.g.
> >>
> >> /* Return true for float_class_normal && float_class_zero.  */
> >> static inline bool is_finite(FloatClass c) { return c <= float_class_zero; }
> >>
> >> float32 float32_add(float32 a, float32 b, float_status *s)
> >> {
> >>   FloatClass a_cls = float32_classify(a);
> >>   FloatClass b_cls = float32_classify(b);
> >
> > Just looked at this. It can be done, although it comes at the
> > price of some performance for fp-bench -o add:
> > 180 Mflops vs. 196 Mflops, i.e. a 8% slowdown. That is with
> > adequate inlining etc., otherwise perf is worse.
> >
> > I'm not convinced that we can gain much in simplicity to
> > justify the perf impact. Yes, we'd simplify canonicalize(),
> > but we'd probably need a float_class_denormal[*], which
> > would complicate everything else.
> >
> > I think it makes sense to keep some inlines that work on
> > the float32/64's directly.
> >
> >>   if (is_finite(a_cls) && is_finite(b_cls) && ...) {
> >>       /* do hardfp thing */
> >>   }
> >
> > [*] Taking 0, denormals and normals would be OK from correctness,
> > but we really don't want to compute ops with denormal inputs on
> > the host; it is very likely that the output will also be denormal,
> > and we'll end up deferring to soft-fp anyway to avoid
> > computing whether the underflow exception has occurred,
> > which is expensive.
> >
> >>   pa = float32_unpack(a, ca, s);
> >>   pb = float32_unpack(b, cb, s);
> >>   pr = addsub_floats(pa, pb, s, false);
> >>   return float32_round_pack(pr, s);
> >> }
> >
> > It pays off to have two separate functions (add & sub) for the
> > slow path. With soft_f32_add/sub factored out:
> >
> > $ taskset -c 0 x86_64-linux-user/qemu-x86_64 tests/fp-bench -o add
> > 197.53 MFlops
> >
> > With the above four lines (pa...return) as an else branch:
> > 169.16 MFlops
> >
> > BTW flattening makes things worse (150.63 MFlops).
> 
> That's disappointing. Did you look at the generated code? Because the
> way we are abusing __flatten__ to effectively make a compile time
> template you would hope it could pull the relevant classify bits to
> before the hard float branch and do the rest later if needed.
> 
> Everything was inline or in softfloat.c for this test right?

Yes. It's just that the classify bits are more expensive than
the alternative. This is fair enough when you look at classify().

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat
  2018-03-27 11:49   ` Alex Bennée
@ 2018-03-27 18:16     ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-27 18:16 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Tue, Mar 27, 2018 at 12:49:48 +0100, Alex Bennée wrote:
> Emilio G. Cota <cota@braap.org> writes:
> 
> > The appended paves the way for leveraging the host FPU for a subset
> > of guest FP operations. For most guest workloads (e.g. FP flags
> > aren't ever cleared, inexact occurs often and rounding is set to the
> > default [to nearest]) this will yield sizable performance speedups.
> >
> > The approach followed here avoids checking the FP exception flags register.
> > See the comment at the top of hostfloat.c for details.
> >
> > This assumes that QEMU is running on an IEEE754-compliant FPU and
> > that the rounding is set to the default (to nearest). The
> > implementation-dependent specifics of the FPU should not matter; things
> > like tininess detection and snan representation are still dealt with in
> > soft-fp. However, this approach will break on most hosts if we compile
> > QEMU with flags such as -ffast-math. We control the flags so this should
> > be easy to enforce though.
> 
> The thing I would avoid is generating is any x87 instructions as we can
> get weird effects if the compiler ever decides to stash a signalling NaN
> in an x87 register.

We take care not to do hardfloat on operands that might result in NaNs.
So this should not be a concern.

> Anyway perhaps -fno-fast-math should be explicit when building fpu/* code?

That's a fair suggestion. There are plenty of other flags though that could
ruin this approach, so I'm not sure how effective this would be.

Also, we should be careful not to sneak in things like
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON) 
in the QEMU binary. Not sure we can guarantee this is avoided unless
we had a runtime check =)

> > The licensing in softfloat.h is complicated at best, so to keep things
> > simple I'm adding this as a separate, GPL'ed file.
> 
> I don't think we need to worry about this. It's fine to add GPL only
> stuff to softfloat.c and since the re-factoring (or before really) we
> "own" this code and are unlikely to upstream anything.
> 
> My preference would be to include this all in softfloat.c unless there
> is a very good reason not to.

Yes I did this in v2 after reading the license etc.

(snip)
> > +++ b/fpu/hostfloat.c
(snip)
> > +#define GEN_INPUT_FLUSH(soft_t)                                         \
> > +    static inline __attribute__((always_inline)) void                   \
> > +    soft_t ## _input_flush__nocheck(soft_t *a, float_status *s)         \
(snip)
> > +        soft_t ## _input_flush__nocheck(c, s);                          \
> > +    }
> > +
> > +GEN_INPUT_FLUSH(float32)
> > +GEN_INPUT_FLUSH(float64)
> 
> Having spent time getting rid of a bunch of macro expansions I'm wary of
> adding more in. However for these I guess it's kind of marginal.

Then you won't like v2 :-(

I don't like macros either but in this case they might be a necessary evil.
I left a lot of macros in there because it'll let us retain performance
and also easily support things like half/quad precision, if we ever want to.

Thanks,

		Emilio

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite
  2018-03-27 18:00     ` Emilio G. Cota
@ 2018-03-28  9:51       ` Alex Bennée
  2018-03-28 15:36         ` Emilio G. Cota
  0 siblings, 1 reply; 46+ messages in thread
From: Alex Bennée @ 2018-03-28  9:51 UTC (permalink / raw)
  To: Emilio G. Cota
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland


Emilio G. Cota <cota@braap.org> writes:

> On Tue, Mar 27, 2018 at 11:13:01 +0100, Alex Bennée wrote:
>>
>> Emilio G. Cota <cota@braap.org> writes:
>>
>> > This will allow us to run correctness tests against our
>> > FP implementation. The test can be run in two modes (called
>> > "testers"): host and soft. With the former we check the results
>> > and FP flags on the host machine against the model.
>> > With the latter we check QEMU's fpu primitives against the
>> > model. Note that in soft mode we are not instantiating any
>> > particular CPU (hence the HW_POISON_H hack to avoid macro poisoning);
>> > for that we need to run the test in host mode under QEMU.
>> >
>> > The input files are taken from IBM's FPGen test suite:
>> > https://www.research.ibm.com/haifa/projects/verification/fpgen/
>> >
>> > I see no license file in there so I am just downloading them
>> > with wget. We might want to keep a copy on a qemu server though,
>> > in case IBM takes those files down in the future.
>>
>> Hmm the files themselves have:
>>
>>   Copyright of IBM Corp. 2005
>>
>> So I'm not sure we can take them into any of our source trees.
>
> Yes I don't think committing these would be appropriate. I guess keeping
> our own copy of the tarball somewhere would be OK, though. My worry is
> that at some point IBM's server will die and we'll have no more test
> files.
>
>> However what are we testing here?
>
> fp-test allows you to test against a model. This model can be anything;
> for now, I grabbed model files from IBM's fpgen, which tests for
> IEEE compliance.
>
> We can add more model files; the muladd tests are an example of that.
>
>> Do we just want to test our implementation is IEEE compliant or should
>> we generate our own test cases on validated hardware to check that our
>> emulation of a guest is correct (e.g. correct modulo the valid
>> variations in the standard)?
>
> I think what we want is a large core of tests that test the standard,
> plus a smaller set of tests that cover ISA particularities. I think
> the IBM models are a good starting point for the former -- note
> though that some operations are not covered in the models (despite
> the syntax description specifying an op for them, e.g. int-to-float
> conversions.)

OK that sounds sane.

>> > The "IBM" syntax of those files (for now the only syntax supported
>> > in fp-test) is documented here:
>> > https://www.research.ibm.com/haifa/projects/verification/fpgen/papers/ieee-test-suite-v2.pdf
>> >
>> > Note that the syntax document has some inaccuracies; the appended
>> > parsing code works around some of those.
>> >
>> > The exception flag (-e) is important: many of the optimizations
>> > included in the following commits assume that the inexact flag
>> > is set, so "-e x" is necessary in order to test those code paths.
>> >
>> > The whitelist flag (-w) points to a file with test cases to be ignored.
>> > I have put some whitelist files online, but we should have them
>> > on a QEMU-related server.
>> >
>> > Thus, a typical of fp-test is as follows:
>> >
>> >   $ cd qemu/build/tests/fp-test
>> >   $ make -j && \
>> > 	./fp-test -t soft ibm/*.fptest \
>> > 	-w whitelist.txt \
>> > 	-e x
>>
>> So this is a unit test of our code rather than a test program running
>> under QEMU?
>
> Having the -t host/soft flags allows you flexibility in what to test.
>
> With "host" mode, you're generating a binary that knows nothing
> about QEMU, i.e. all its FP operations are native. You can use this
> to (1) figure out whether your host diverts from the model [hopefully
> it doesn't in anything substantial], and (2) test whether QEMU mimics
> the corresponding host by running the binary under *-linux-user.

OK - there is no reason why we can't cross compile the single source
file for multiple tests/tcg/targets. I'll look at that when I have
another run at the cross compile stuff.

I wonder if we should disable the soft mode for these builds so we don't
have to deal with cross compiling the softfloat.o's as well?

> With "soft" mode, you're testing QEMU's soft-fp implementation. This
> allows you to check it against the model. Note that it doesn't let
> you check anything specific about a target CPU (hence the HW_POISON_H
> hack); for this you'd have to go to point (2) above. Here instead we're
> checking QEMU's FP implementation directly against the models.
>
>>  I noted running under x86-64-linux-user fails pretty quick.
>
> As I wrote below, I think this is due to bugs in the i386 target.
>
> On a host x86_64 machine:
> $ ./fp-test -t host ibm/* -w whitelist.txt -w whitelist-tininess-after.txt
> All tests OK.
> Tests passed: 74426. Not handled: 53297, whitelisted: 2748
>
> $ ../../x86_64-linux-user/qemu-x86_64 ./fp-test -t host \
> 	ibm/* -w whitelist.txt -w whitelist-tininess-after.txt -n 2>/dev/null
> Tests failed: 57479. Parsing: 0, result:14, flags:57465
> Tests passed: 16947. Not handled: 53297, whitelisted: 2748
>
> The results are different when run under QEMU, which means
> this target is not doing things correctly (despite -t soft
> passing).
>
>> If so we really should be building this automatically in make check.
>
> Yes, passing -soft mode would certainly be valuable and trivial
> to integrate since there is nothing built that is target-dependent.

So the two bugs I'm currently fixing are guest dependent so can't be
caught by soft mode:

  - ARM FP16 alternative format behaviour
  - round_to_int_and_pack refactor broke TriCore ftoi insns (1759264)

I assume your bug was?

  - fix {min,max}nummag for same-abs-value inputs (from your series)


>
> (snip)
>> > --- /dev/null
>> > +++ b/tests/fp-test/fp-test.c
> (snip)
>> > +enum precision {
>> > +    PREC_FLOAT,
>> > +    PREC_DOUBLE,
>> > +    PREC_QUAD,
>> > +    PREC_FLOAT_TO_DOUBLE,
>> > +};
>>
>> Again we will want to include half-precision.
>
> Sure. We'll need to come up with model files for that though.
>
> (snip)
>> > +    }
>> > +    if (unlikely(!strcmp("-inf", p) || !strcmp("-Inf", p))) {
>> > +        ret->val = fp_choose(prec, 0xff800000, 0xfff0000000000000);
>> > +        return 0;
>> > +    }
>> > +
>> > +    len = strlen(p);
>> > +
>> > +    if (strchr(p, 'P')) {
>>
>> Given we have already strlen'ed should we use memchr(p, 'P', len) or
>> even strchrnul(p,'P') with a check we haven't run over the end? OR maybe
>> use glib's string stuff instead.
>
> I think in this case strchr is warranted; p points to a valid string
> (otherwise strlen would also be dangerous).

Yeah that's fair. I guess it also help cross-compilation to avoid too
many dependencies.

>
> (snip)
>> > +/* Syntax of IBM FP test cases:
>> > + * https://www.research.ibm.com/haifa/projects/verification/fpgen/syntax.txt
>> > + */
>> > +static enum error ibm_test_line(const char *line)
>> > +{
>> > +    struct test_op t;
>> > +    /* at most nine fields; this should be more than enough for each field */
>> > +    char s[9][64];
>> > +    char *p;
>> > +    int n, field;
>> > +    int i;
>> > +
>> > +    /* data lines start with either b32 or d(64|128) */
>> > +    if (unlikely(line[0] != 'b' && line[0] != 'd')) {
>> > +        return ERROR_COMMENT;
>> > +    }
>> > +    n = sscanf(line, "%63s %63s %63s %63s %63s %63s %63s %63s %63s",
>> > +               s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
>> > +    if (unlikely(n < 5 || n > 9)) {
>> > +        return ERROR_INPUT;
>> > +    }
>>
>> Personally I find g_strsplit(line, " ", 9) and g_strfreev() handy for
>> this sort of parsing.
>
> I figured the above might be simpler since I wouldn't have to worry
> about freeing memory. Also, scanf directly returns n, which is used
> later.

/me nods

--
Alex Bennée

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite
  2018-03-28  9:51       ` Alex Bennée
@ 2018-03-28 15:36         ` Emilio G. Cota
  0 siblings, 0 replies; 46+ messages in thread
From: Emilio G. Cota @ 2018-03-28 15:36 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, Aurelien Jarno, Peter Maydell, Laurent Vivier,
	Richard Henderson, Paolo Bonzini, Mark Cave-Ayland

On Wed, Mar 28, 2018 at 10:51:30 +0100, Alex Bennée wrote:
> Emilio G. Cota <cota@braap.org> writes:
> >> So this is a unit test of our code rather than a test program running
> >> under QEMU?
> >
> > Having the -t host/soft flags allows you flexibility in what to test.
> >
> > With "host" mode, you're generating a binary that knows nothing
> > about QEMU, i.e. all its FP operations are native. You can use this
> > to (1) figure out whether your host diverts from the model [hopefully
> > it doesn't in anything substantial], and (2) test whether QEMU mimics
> > the corresponding host by running the binary under *-linux-user.
> 
> OK - there is no reason why we can't cross compile the single source
> file for multiple tests/tcg/targets. I'll look at that when I have
> another run at the cross compile stuff.

In fact I tried this first. I generated one executable per target,
compiling softfloat.o with the corresponding -DTARGET_FOO.

Then I realised this isn't good enough. The problem is that this
only buys you the target-specific part of softfloat, which boils
down to sNaN representation and little else. You still have to
pass your own float_status (with rounding etc.), and decide whether
to act or to ignore whatever flags softfloat sets after an op.

In short, having this without having the actual target code doesn't
buy you much.

I think a better alternative is to:
1- Compile fp-test using host mode on actual hardware. Let's call
   this executable fp-test-host-$arch.
2- Compare fp-test results of running on actual hardware against
   running fp-test-host-$arch on linux-user-$arch.

This will give us complete coverage of both softfloat and
the target code that calls softfloat (and raises exceptions etc.).

> >> If so we really should be building this automatically in make check.
> >
> > Yes, passing -soft mode would certainly be valuable and trivial
> > to integrate since there is nothing built that is target-dependent.
> 
> So the two bugs I'm currently fixing are guest dependent so can't be
> caught by soft mode:
> 
>   - ARM FP16 alternative format behaviour
>   - round_to_int_and_pack refactor broke TriCore ftoi insns (1759264)

Yes, passing soft mode is a necessary condition for correctness but
it isn't sufficient--arch-specific bugs can also happen! And those
bugs might be in softfloat and/or in target/$arch/*.

For that we'll need something like what I sketched above.

> I assume your bug was?
> 
>   - fix {min,max}nummag for same-abs-value inputs (from your series)

Yep.

Thanks,

		E.

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2018-03-28 15:36 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-21 20:11 [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks Emilio G. Cota
2018-03-27  8:45   ` Alex Bennée
2018-03-27 17:21     ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 02/14] tests: add fp-test, a floating point test suite Emilio G. Cota
2018-03-27 10:13   ` Alex Bennée
2018-03-27 18:00     ` Emilio G. Cota
2018-03-28  9:51       ` Alex Bennée
2018-03-28 15:36         ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
2018-03-27 10:15   ` Alex Bennée
2018-03-27 10:15   ` Alex Bennée
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 04/14] fp-test: add muladd variants Emilio G. Cota
2018-03-27 11:33   ` Alex Bennée
2018-03-27 18:03     ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 05/14] softfloat: add float32_is_normal and float64_is_normal Emilio G. Cota
2018-03-27 11:34   ` Alex Bennée
2018-03-27 18:05     ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 06/14] softfloat: add float32_is_denormal and float64_is_denormal Emilio G. Cota
2018-03-27 11:35   ` Alex Bennée
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 07/14] fpu: introduce hostfloat Emilio G. Cota
2018-03-21 20:41   ` Laurent Vivier
2018-03-21 21:45     ` Emilio G. Cota
2018-03-27 11:49   ` Alex Bennée
2018-03-27 18:16     ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 08/14] hostfloat: support float32/64 addition and subtraction Emilio G. Cota
2018-03-22  5:05   ` Richard Henderson
2018-03-22  5:57     ` Emilio G. Cota
2018-03-22  6:41       ` Richard Henderson
2018-03-22 15:08         ` Emilio G. Cota
2018-03-22 15:12           ` Laurent Vivier
2018-03-22 19:57         ` Emilio G. Cota
2018-03-27 11:41           ` Alex Bennée
2018-03-27 18:08             ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 09/14] hostfloat: support float32/64 multiplication Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 10/14] hostfloat: support float32/64 division Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 11/14] hostfloat: support float32/64 fused multiply-add Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 12/14] hostfloat: support float32/64 square root Emilio G. Cota
2018-03-22  1:29   ` Alex Bennée
2018-03-22  4:02     ` Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 13/14] hostfloat: support float32/64 comparison Emilio G. Cota
2018-03-21 20:11 ` [Qemu-devel] [PATCH v1 14/14] hostfloat: support float32_to_float64 Emilio G. Cota
2018-03-21 20:36 ` [Qemu-devel] [PATCH v1 00/14] fp-test + hostfloat no-reply
2018-03-22  5:02 ` no-reply
2018-03-22  8:56 ` Alex Bennée
2018-03-22 15:28   ` Emilio G. Cota

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.