qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
	1841592@bugs.launchpad.net, richard.henderson@linaro.org,
	pc@us.ibm.com
Subject: [Qemu-devel] [PATCH] tests/tcg: add float_madds test to multiarch
Date: Fri, 13 Sep 2019 14:49:34 +0100	[thread overview]
Message-ID: <20190913134935.29696-1-alex.bennee@linaro.org> (raw)

This is a generic floating point multiply and accumulate test for
single precision floating point values. I've split of the common float
functions into a helper library so additional tests can use the same
common code.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/tcg/multiarch/Makefile.target |   7 +-
 tests/tcg/multiarch/float_helpers.c | 208 ++++++++++++++++++++++++++++
 tests/tcg/multiarch/float_helpers.h |  26 ++++
 tests/tcg/multiarch/float_madds.c   |  78 +++++++++++
 4 files changed, 318 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/multiarch/float_helpers.c
 create mode 100644 tests/tcg/multiarch/float_helpers.h
 create mode 100644 tests/tcg/multiarch/float_madds.c

diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 657a04f802d..0446b75c456 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -10,12 +10,17 @@ MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
 # Set search path for all sources
 VPATH 		+= $(MULTIARCH_SRC)
 MULTIARCH_SRCS   =$(notdir $(wildcard $(MULTIARCH_SRC)/*.c))
-MULTIARCH_TESTS  =$(MULTIARCH_SRCS:.c=)
+MULTIARCH_TESTS  =$(filter-out float_helpers, $(MULTIARCH_SRCS:.c=))
 
 #
 # The following are any additional rules needed to build things
 #
 
+
+float_madds: LDFLAGS+=-lm
+float_madds: float_madds.c float_helpers.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -O2 $< $(MULTIARCH_SRC)/float_helpers.c -o $@ $(LDFLAGS)
+
 testthread: LDFLAGS+=-lpthread
 
 # We define the runner for test-mmap after the individual
diff --git a/tests/tcg/multiarch/float_helpers.c b/tests/tcg/multiarch/float_helpers.c
new file mode 100644
index 00000000000..481d8d33317
--- /dev/null
+++ b/tests/tcg/multiarch/float_helpers.c
@@ -0,0 +1,208 @@
+/*
+ * Common Float Helpers
+ *
+ * This contains a series of useful utility routines and a set of
+ * floating point constants useful for exercising the edge cases in
+ * floating point tests.
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* we want additional float type definitions */
+#define __STDC_WANT_IEC_60559_BFP_EXT__
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+#include "float_helpers.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/*
+ * Half Precision Numbers
+ *
+ * Not yet well standardised so we return a plain uint16_t for now.
+ */
+
+/* no handy defines for these numbers */
+static uint16_t f16_numbers[] = {
+    0xffff, /* -NaN / AHP -Max */
+    0xfcff, /* -NaN / AHP */
+    0xfc01, /* -NaN / AHP */
+    0xfc00, /* -Inf */
+    0xfbff, /* -Max */
+    0xc000, /* -2 */
+    0xbc00, /* -1 */
+    0x8001, /* -MIN subnormal */
+    0x8000, /* -0 */
+    0x0000, /* +0 */
+    0x0001, /* MIN subnormal */
+    0x3c00, /* 1 */
+    0x7bff, /* Max */
+    0x7c00, /* Inf */
+    0x7c01, /* NaN / AHP */
+    0x7cff, /* NaN / AHP */
+    0x7fff, /* NaN / AHP +Max*/
+};
+
+const int num_f16 = ARRAY_SIZE(f16_numbers);
+
+uint16_t get_f16(int i) {
+    return f16_numbers[i % num_f16];
+}
+
+/* only display as hex */
+char *fmt_16(uint16_t num) {
+    char *fmt;
+    asprintf(&fmt, "f16 %#04x", num);
+    return fmt;
+}
+
+/*
+ * Single Precision Numbers
+ */
+
+#ifndef SNANF
+/* Signaling NaN macros, if supported.  */
+# if __GNUC_PREREQ(3, 3)
+#  define SNANF (__builtin_nansf (""))
+#  define SNAN (__builtin_nans (""))
+#  define SNANL (__builtin_nansl (""))
+# endif
+#endif
+
+static float f32_numbers[] = {
+    -SNANF,
+    -NAN,
+    -INFINITY,
+    -FLT_MAX,
+    -1.111E+31,
+    -1.111E+30,
+    -1.08700982e-12,
+    -1.78051176e-20,
+    -FLT_MIN,
+    0.0,
+    FLT_MIN,
+    2.98023224e-08,
+    5.96046E-8, /* min positive FP16 subnormal */
+    6.09756E-5, /* max subnormal FP16 */
+    6.10352E-5, /* min positive normal FP16 */
+    1.0,
+    1.0009765625, /* smallest float after 1.0 FP16 */
+    2.0,
+    M_E, M_PI,
+    65503.0,
+    65504.0, /* max FP16 */
+    65505.0,
+    131007.0,
+    131008.0, /* max AFP */
+    131009.0,
+    1.111E+30,
+    FLT_MAX,
+    INFINITY,
+    NAN,
+    SNANF
+};
+
+const int num_f32 = ARRAY_SIZE(f32_numbers);
+
+float get_f32(int i) {
+    return f32_numbers[i % num_f32];
+}
+
+char *fmt_f32(float num) {
+    uint32_t single_as_hex = *(uint32_t *) &num;
+    char *fmt;
+    asprintf(&fmt, "f32 %02.20e / %#010x", num, single_as_hex);
+    return fmt;
+}
+
+
+/* This allows us to initialise some doubles as pure hex */
+typedef union {
+    double d;
+    uint64_t h;
+} test_doubles;
+
+static test_doubles f64_numbers[] = {
+    {SNAN},
+    {-NAN},
+    {-INFINITY},
+    {-DBL_MAX},
+    {-FLT_MAX-1.0},
+    {-FLT_MAX},
+    {-1.111E+31},
+    {-1.111E+30}, /* half prec */
+    {-2.0}, {-1.0},
+    {-DBL_MIN},
+    {-FLT_MIN},
+    {0.0},
+    {FLT_MIN},
+    {2.98023224e-08},
+    {5.96046E-8}, /* min positive FP16 subnormal */
+    {6.09756E-5}, /* max subnormal FP16 */
+    {6.10352E-5}, /* min positive normal FP16 */
+    {1.0},
+    {1.0009765625}, /* smallest float after 1.0 FP16 */
+    {DBL_MIN},
+    {1.3789972848607228e-308},
+    {1.4914738736681624e-308},
+    {1.0}, {2.0},
+    {M_E}, {M_PI},
+    {65503.0},
+    {65504.0}, /* max FP16 */
+    {65505.0},
+    {131007.0},
+    {131008.0}, /* max AFP */
+    {131009.0},
+    {.h = 0x41dfffffffc00000 }, /* to int = 0x7fffffff */
+    {FLT_MAX},
+    {FLT_MAX + 1.0},
+    {DBL_MAX},
+    {INFINITY},
+    {NAN},
+    {.h = 0x7ff0000000000001}, /* SNAN */
+    {SNAN},
+};
+
+const int num_f64 = ARRAY_SIZE(f64_numbers);
+
+double get_f64(int i) {
+    return f64_numbers[i % num_f64].d;
+}
+
+char *fmt_f64(double num) {
+    uint64_t double_as_hex = *(uint64_t *) &num;
+    char *fmt;
+    asprintf(&fmt, "f64 %02.20e / %#020" PRIx64, num, double_as_hex);
+    return fmt;
+}
+
+/*
+ * Float flags
+ */
+char *fmt_flags(void)
+{
+    int flags = fetestexcept(FE_ALL_EXCEPT);
+    char *fmt;
+
+    if (flags) {
+        asprintf(&fmt, "%s%s%s%s%s",
+                 flags & FE_OVERFLOW ? "OVERFLOW " : "",
+                 flags & FE_UNDERFLOW ? "UNDERFLOW " : "",
+                 flags & FE_DIVBYZERO ? "DIV0 " : "",
+                 flags & FE_INEXACT ? "INEXACT " : "",
+                 flags & FE_INVALID ? "INVALID" : "");
+    } else {
+        asprintf(&fmt, "OK");
+    }
+
+    return fmt;
+}
diff --git a/tests/tcg/multiarch/float_helpers.h b/tests/tcg/multiarch/float_helpers.h
new file mode 100644
index 00000000000..4a1e2f3853a
--- /dev/null
+++ b/tests/tcg/multiarch/float_helpers.h
@@ -0,0 +1,26 @@
+/*
+ * Common Float Helpers
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <inttypes.h>
+
+/* Number of constants in each table */
+extern const int num_f16;
+extern const int num_f32;
+extern const int num_f64;
+
+/* Accessor helpers */
+uint16_t get_f16(int i); /* use _Float16 when we can */
+float    get_f32(int i);
+double   get_f64(int i);
+
+/* Return format strings, free after use */
+char * fmt_f16(uint16_t);
+char * fmt_f32(float);
+char * fmt_f64(double);
+/* exception flags */
+char * fmt_flags(void);
diff --git a/tests/tcg/multiarch/float_madds.c b/tests/tcg/multiarch/float_madds.c
new file mode 100644
index 00000000000..bc11eea9084
--- /dev/null
+++ b/tests/tcg/multiarch/float_madds.c
@@ -0,0 +1,78 @@
+/*
+ * Fused Multiply Add (Single)
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+#include "float_helpers.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef struct {
+    int flag;
+    char *desc;
+} float_mapping;
+
+float_mapping round_flags[] = {
+    { FE_TONEAREST, "to nearest" },
+    { FE_UPWARD, "upwards" },
+    { FE_DOWNWARD, "downwards" },
+    { FE_TOWARDZERO, "to zero" }
+};
+
+void print_result(float a, float b, float c, float r)
+{
+    char *a_fmt, *b_fmt, *c_fmt, *r_fmt, *flag_fmt;
+
+    a_fmt = fmt_f32(a);
+    b_fmt = fmt_f32(b);
+    c_fmt = fmt_f32(c);
+    r_fmt = fmt_f32(r);
+    flag_fmt = fmt_flags();
+
+    printf("%s * %s + %s = %s  (%s)\n",
+           a_fmt, b_fmt, c_fmt, r_fmt, flag_fmt);
+
+    free(a_fmt);
+    free(b_fmt);
+    free(c_fmt);
+    free(r_fmt);
+    free(flag_fmt);
+}
+
+
+int main(int argc, char *argv[argc])
+{
+    int i, j, k, l;
+    float a, b, c, r;
+
+    for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
+        fesetround(round_flags[i].flag);
+        printf("### Rounding %s\n", round_flags[i].desc);
+        for (j = 0; j < num_f32; j += 3) {
+            for (k = 1; k < num_f32; k += 3 ) {
+                for (l = 2; l < num_f32; l += 3) {
+                    a = get_f32(j);
+                    b = get_f32(k);
+                    c = get_f32(l);
+                    feclearexcept(FE_ALL_EXCEPT);
+
+                    /* must be built with -O2 to generate fused op */
+                    r = a * b + c;
+
+                    print_result(a, b, c, r);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
-- 
2.20.1



WARNING: multiple messages have this Message-ID (diff)
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [Bug 1841592] [PATCH] tests/tcg: add float_madds test to multiarch
Date: Fri, 13 Sep 2019 13:49:34 -0000	[thread overview]
Message-ID: <20190913134935.29696-1-alex.bennee@linaro.org> (raw)
Message-ID: <20190913134934.RFEHZssXZdNUU2Sf30gZFHA_jvr2V24vHBTVjCjv2n4@z> (raw)
In-Reply-To: 156691209320.18814.746226319480624520.malonedeb@soybean.canonical.com

This is a generic floating point multiply and accumulate test for
single precision floating point values. I've split of the common float
functions into a helper library so additional tests can use the same
common code.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/tcg/multiarch/Makefile.target |   7 +-
 tests/tcg/multiarch/float_helpers.c | 208 ++++++++++++++++++++++++++++
 tests/tcg/multiarch/float_helpers.h |  26 ++++
 tests/tcg/multiarch/float_madds.c   |  78 +++++++++++
 4 files changed, 318 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/multiarch/float_helpers.c
 create mode 100644 tests/tcg/multiarch/float_helpers.h
 create mode 100644 tests/tcg/multiarch/float_madds.c

diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 657a04f802d..0446b75c456 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -10,12 +10,17 @@ MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
 # Set search path for all sources
 VPATH 		+= $(MULTIARCH_SRC)
 MULTIARCH_SRCS   =$(notdir $(wildcard $(MULTIARCH_SRC)/*.c))
-MULTIARCH_TESTS  =$(MULTIARCH_SRCS:.c=)
+MULTIARCH_TESTS  =$(filter-out float_helpers, $(MULTIARCH_SRCS:.c=))
 
 #
 # The following are any additional rules needed to build things
 #
 
+
+float_madds: LDFLAGS+=-lm
+float_madds: float_madds.c float_helpers.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -O2 $< $(MULTIARCH_SRC)/float_helpers.c -o $@ $(LDFLAGS)
+
 testthread: LDFLAGS+=-lpthread
 
 # We define the runner for test-mmap after the individual
diff --git a/tests/tcg/multiarch/float_helpers.c b/tests/tcg/multiarch/float_helpers.c
new file mode 100644
index 00000000000..481d8d33317
--- /dev/null
+++ b/tests/tcg/multiarch/float_helpers.c
@@ -0,0 +1,208 @@
+/*
+ * Common Float Helpers
+ *
+ * This contains a series of useful utility routines and a set of
+ * floating point constants useful for exercising the edge cases in
+ * floating point tests.
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* we want additional float type definitions */
+#define __STDC_WANT_IEC_60559_BFP_EXT__
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+#include "float_helpers.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/*
+ * Half Precision Numbers
+ *
+ * Not yet well standardised so we return a plain uint16_t for now.
+ */
+
+/* no handy defines for these numbers */
+static uint16_t f16_numbers[] = {
+    0xffff, /* -NaN / AHP -Max */
+    0xfcff, /* -NaN / AHP */
+    0xfc01, /* -NaN / AHP */
+    0xfc00, /* -Inf */
+    0xfbff, /* -Max */
+    0xc000, /* -2 */
+    0xbc00, /* -1 */
+    0x8001, /* -MIN subnormal */
+    0x8000, /* -0 */
+    0x0000, /* +0 */
+    0x0001, /* MIN subnormal */
+    0x3c00, /* 1 */
+    0x7bff, /* Max */
+    0x7c00, /* Inf */
+    0x7c01, /* NaN / AHP */
+    0x7cff, /* NaN / AHP */
+    0x7fff, /* NaN / AHP +Max*/
+};
+
+const int num_f16 = ARRAY_SIZE(f16_numbers);
+
+uint16_t get_f16(int i) {
+    return f16_numbers[i % num_f16];
+}
+
+/* only display as hex */
+char *fmt_16(uint16_t num) {
+    char *fmt;
+    asprintf(&fmt, "f16 %#04x", num);
+    return fmt;
+}
+
+/*
+ * Single Precision Numbers
+ */
+
+#ifndef SNANF
+/* Signaling NaN macros, if supported.  */
+# if __GNUC_PREREQ(3, 3)
+#  define SNANF (__builtin_nansf (""))
+#  define SNAN (__builtin_nans (""))
+#  define SNANL (__builtin_nansl (""))
+# endif
+#endif
+
+static float f32_numbers[] = {
+    -SNANF,
+    -NAN,
+    -INFINITY,
+    -FLT_MAX,
+    -1.111E+31,
+    -1.111E+30,
+    -1.08700982e-12,
+    -1.78051176e-20,
+    -FLT_MIN,
+    0.0,
+    FLT_MIN,
+    2.98023224e-08,
+    5.96046E-8, /* min positive FP16 subnormal */
+    6.09756E-5, /* max subnormal FP16 */
+    6.10352E-5, /* min positive normal FP16 */
+    1.0,
+    1.0009765625, /* smallest float after 1.0 FP16 */
+    2.0,
+    M_E, M_PI,
+    65503.0,
+    65504.0, /* max FP16 */
+    65505.0,
+    131007.0,
+    131008.0, /* max AFP */
+    131009.0,
+    1.111E+30,
+    FLT_MAX,
+    INFINITY,
+    NAN,
+    SNANF
+};
+
+const int num_f32 = ARRAY_SIZE(f32_numbers);
+
+float get_f32(int i) {
+    return f32_numbers[i % num_f32];
+}
+
+char *fmt_f32(float num) {
+    uint32_t single_as_hex = *(uint32_t *) &num;
+    char *fmt;
+    asprintf(&fmt, "f32 %02.20e / %#010x", num, single_as_hex);
+    return fmt;
+}
+
+
+/* This allows us to initialise some doubles as pure hex */
+typedef union {
+    double d;
+    uint64_t h;
+} test_doubles;
+
+static test_doubles f64_numbers[] = {
+    {SNAN},
+    {-NAN},
+    {-INFINITY},
+    {-DBL_MAX},
+    {-FLT_MAX-1.0},
+    {-FLT_MAX},
+    {-1.111E+31},
+    {-1.111E+30}, /* half prec */
+    {-2.0}, {-1.0},
+    {-DBL_MIN},
+    {-FLT_MIN},
+    {0.0},
+    {FLT_MIN},
+    {2.98023224e-08},
+    {5.96046E-8}, /* min positive FP16 subnormal */
+    {6.09756E-5}, /* max subnormal FP16 */
+    {6.10352E-5}, /* min positive normal FP16 */
+    {1.0},
+    {1.0009765625}, /* smallest float after 1.0 FP16 */
+    {DBL_MIN},
+    {1.3789972848607228e-308},
+    {1.4914738736681624e-308},
+    {1.0}, {2.0},
+    {M_E}, {M_PI},
+    {65503.0},
+    {65504.0}, /* max FP16 */
+    {65505.0},
+    {131007.0},
+    {131008.0}, /* max AFP */
+    {131009.0},
+    {.h = 0x41dfffffffc00000 }, /* to int = 0x7fffffff */
+    {FLT_MAX},
+    {FLT_MAX + 1.0},
+    {DBL_MAX},
+    {INFINITY},
+    {NAN},
+    {.h = 0x7ff0000000000001}, /* SNAN */
+    {SNAN},
+};
+
+const int num_f64 = ARRAY_SIZE(f64_numbers);
+
+double get_f64(int i) {
+    return f64_numbers[i % num_f64].d;
+}
+
+char *fmt_f64(double num) {
+    uint64_t double_as_hex = *(uint64_t *) &num;
+    char *fmt;
+    asprintf(&fmt, "f64 %02.20e / %#020" PRIx64, num, double_as_hex);
+    return fmt;
+}
+
+/*
+ * Float flags
+ */
+char *fmt_flags(void)
+{
+    int flags = fetestexcept(FE_ALL_EXCEPT);
+    char *fmt;
+
+    if (flags) {
+        asprintf(&fmt, "%s%s%s%s%s",
+                 flags & FE_OVERFLOW ? "OVERFLOW " : "",
+                 flags & FE_UNDERFLOW ? "UNDERFLOW " : "",
+                 flags & FE_DIVBYZERO ? "DIV0 " : "",
+                 flags & FE_INEXACT ? "INEXACT " : "",
+                 flags & FE_INVALID ? "INVALID" : "");
+    } else {
+        asprintf(&fmt, "OK");
+    }
+
+    return fmt;
+}
diff --git a/tests/tcg/multiarch/float_helpers.h b/tests/tcg/multiarch/float_helpers.h
new file mode 100644
index 00000000000..4a1e2f3853a
--- /dev/null
+++ b/tests/tcg/multiarch/float_helpers.h
@@ -0,0 +1,26 @@
+/*
+ * Common Float Helpers
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <inttypes.h>
+
+/* Number of constants in each table */
+extern const int num_f16;
+extern const int num_f32;
+extern const int num_f64;
+
+/* Accessor helpers */
+uint16_t get_f16(int i); /* use _Float16 when we can */
+float    get_f32(int i);
+double   get_f64(int i);
+
+/* Return format strings, free after use */
+char * fmt_f16(uint16_t);
+char * fmt_f32(float);
+char * fmt_f64(double);
+/* exception flags */
+char * fmt_flags(void);
diff --git a/tests/tcg/multiarch/float_madds.c b/tests/tcg/multiarch/float_madds.c
new file mode 100644
index 00000000000..bc11eea9084
--- /dev/null
+++ b/tests/tcg/multiarch/float_madds.c
@@ -0,0 +1,78 @@
+/*
+ * Fused Multiply Add (Single)
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+#include "float_helpers.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef struct {
+    int flag;
+    char *desc;
+} float_mapping;
+
+float_mapping round_flags[] = {
+    { FE_TONEAREST, "to nearest" },
+    { FE_UPWARD, "upwards" },
+    { FE_DOWNWARD, "downwards" },
+    { FE_TOWARDZERO, "to zero" }
+};
+
+void print_result(float a, float b, float c, float r)
+{
+    char *a_fmt, *b_fmt, *c_fmt, *r_fmt, *flag_fmt;
+
+    a_fmt = fmt_f32(a);
+    b_fmt = fmt_f32(b);
+    c_fmt = fmt_f32(c);
+    r_fmt = fmt_f32(r);
+    flag_fmt = fmt_flags();
+
+    printf("%s * %s + %s = %s  (%s)\n",
+           a_fmt, b_fmt, c_fmt, r_fmt, flag_fmt);
+
+    free(a_fmt);
+    free(b_fmt);
+    free(c_fmt);
+    free(r_fmt);
+    free(flag_fmt);
+}
+
+
+int main(int argc, char *argv[argc])
+{
+    int i, j, k, l;
+    float a, b, c, r;
+
+    for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
+        fesetround(round_flags[i].flag);
+        printf("### Rounding %s\n", round_flags[i].desc);
+        for (j = 0; j < num_f32; j += 3) {
+            for (k = 1; k < num_f32; k += 3 ) {
+                for (l = 2; l < num_f32; l += 3) {
+                    a = get_f32(j);
+                    b = get_f32(k);
+                    c = get_f32(l);
+                    feclearexcept(FE_ALL_EXCEPT);
+
+                    /* must be built with -O2 to generate fused op */
+                    r = a * b + c;
+
+                    print_result(a, b, c, r);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
-- 
2.20.1

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1841592

Title:
  ppc: softfloat float implementation issues

Status in QEMU:
  Incomplete

Bug description:
  Per bug #1841491, Richard Henderson (rth) said:
  > The float test failure is part of a larger problem for target/powerpc
  > in which all float routines are implemented incorrectly. They are all
  > implemented as double operations with rounding to float as a second
  > step. Which not only produces incorrect exceptions, as in this case,
  > but incorrect numerical results from the double rounding.
  >
  > This should probably be split to a separate bug...

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1841592/+subscriptions


         reply	other threads:[~2019-09-13 13:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-27 13:21 [Qemu-devel] [Bug 1841592] [NEW] ppc: softfloat float implementation issues Paul Clarke
2019-08-27 13:26 ` [Qemu-devel] [Bug 1841592] " Paul Clarke
2019-09-12 17:11 ` Alex Bennée
2019-09-12 18:39 ` Alex Bennée
2019-09-12 19:27 ` Richard Henderson
2019-09-12 21:30 ` Alex Bennée
2019-09-13  8:47 ` Alex Bennée
2019-09-13 13:49 ` Alex Bennée [this message]
2019-09-13 13:49   ` [Qemu-devel] [Bug 1841592] [PATCH] tests/tcg: add float_madds test to multiarch Alex Bennée
2019-09-13 14:50   ` [Qemu-devel] " Paul Clarke
2019-09-13 14:50     ` [Qemu-devel] [Bug 1841592] " Paul Clarke
2019-09-14 15:12   ` [Qemu-devel] " Richard Henderson
2019-09-14 17:59     ` Alex Bennée
2019-09-14 17:59       ` [Qemu-devel] [Bug 1841592] " Alex Bennée
2019-09-14 18:11       ` [Qemu-devel] " Richard Henderson
2019-09-13 14:13 ` [Qemu-devel] [Bug 1841592] Re: ppc: softfloat float implementation issues Alex Bennée
2019-11-14  4:17 ` Launchpad Bug Tracker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190913134935.29696-1-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=1841592@bugs.launchpad.net \
    --cc=pc@us.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).