From: "Alex Bennée" <alex.bennee@linaro.org>
To: "Emilio G. Cota" <cota@braap.org>
Cc: qemu-devel@nongnu.org, Aurelien Jarno <aurelien@aurel32.net>,
Peter Maydell <peter.maydell@linaro.org>,
Laurent Vivier <laurent@vivier.eu>,
Richard Henderson <richard.henderson@linaro.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Subject: Re: [Qemu-devel] [PATCH v3 01/15] tests: add fp-test, a floating point test suite
Date: Wed, 11 Apr 2018 02:20:49 +0100 [thread overview]
Message-ID: <874lki5yj2.fsf@linaro.org> (raw)
In-Reply-To: <1522883475-27858-2-git-send-email-cota@braap.org>
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.
<snip>
So with the attached patch and my proposed cross build we can now get:
02:15:54 [alex@zen:~/l/q/qemu.git] softfloat-fixes-for-2.12-v1 ± find . -iname "fp-test" | xargs file
./ppc64-linux-user/tests/fp-test: ELF 64-bit LSB executable, 64-bit PowerPC or cisco 7500, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, not stripped
./armeb-linux-user/tests/fp-test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, not stripped
./aarch64-linux-user/tests/fp-test: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, not stripped
./i386-linux-user/tests/fp-test: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped
./arm-linux-user/tests/fp-test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, not stripped
./s390x-linux-user/tests/fp-test: ELF 64-bit MSB executable, IBM S/390, version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, not stripped
./aarch64_be-linux-user/tests/fp-test: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, not stripped
./tests/fp-test/fp-test: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped
But it did mean having to hack about a little, mainly to get rid of
glib.
--8<---------------cut here---------------start------------->8---
>From 04ed0d9f58f34aa51b9a8284514aab6e36a702b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Wed, 11 Apr 2018 01:35:52 +0100
Subject: [PATCH] tests/tcg: add fp-test to per-guest tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The fp-test code was originally designed to be able to include
softfloat. However cross-compiling QEMU based code is harder than it
needs to be so hide softfloat stuff behind USE_SOFTFLOAT. We also need
to tweak:
- manually include what we need
- g_assert -> assert()
- use libc hsearch instead of g_hash_table
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/fp/fp-test.c | 148 ++++++++++++++++++++++++++++++++++++++++++-----------
tests/tcg/Makefile | 3 ++
2 files changed, 121 insertions(+), 30 deletions(-)
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
index 27637c4617..4cee2a918c 100644
--- a/tests/fp/fp-test.c
+++ b/tests/fp/fp-test.c
@@ -6,12 +6,72 @@
* 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
+
+/* If HW_POISON_H isn't defined then we aren't building against qemu's
+ * softfloat */
+#ifdef HW_POISON_H
#include "qemu/osdep.h"
#include "fpu/softfloat.h"
+#define USE_SOFTFLOAT 1
+
+#else /* else define what QEMU would have given us */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <search.h>
+
+/* See include/fpu/softfloat-types.h */
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+enum {
+ float_round_nearest_even = 0,
+ float_round_down = 1,
+ float_round_up = 2,
+ float_round_to_zero = 3,
+ float_round_ties_away = 4,
+ float_round_to_odd = 5,
+};
+
+enum {
+ float_flag_invalid = 1,
+ float_flag_divbyzero = 4,
+ float_flag_overflow = 8,
+ float_flag_underflow = 16,
+ float_flag_inexact = 32,
+ float_flag_input_denormal = 64,
+ float_flag_output_denormal = 128
+};
+
+/* See include/compiler.h */
+#ifndef likely
+#if __GNUC__ < 3
+#define __builtin_expect(x, n) (x)
+#endif
+
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
#include <fenv.h>
#include <math.h>
@@ -116,16 +176,18 @@ struct tester {
struct whitelist {
char **lines;
size_t n;
- GHashTable *ht;
+ struct hsearch_data ht;
};
static uint64_t test_stats[ERROR_MAX];
static struct whitelist whitelist;
static uint8_t default_exceptions;
static bool die_on_error = true;
+#ifdef USE_SOFTFLOAT
static struct float_status soft_status = {
.float_detect_tininess = float_tininess_before_rounding,
};
+#endif
static inline float u64_to_float(uint64_t v)
{
@@ -285,7 +347,7 @@ static enum error host_tester(struct test_op *t)
float res;
int i;
- g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+ 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) {
@@ -343,7 +405,7 @@ static enum error host_tester(struct test_op *t)
double res;
int i;
- g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+ 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) {
@@ -429,6 +491,8 @@ static enum error host_tester(struct test_op *t)
return tester_check(t, res64, result_is_nan, flags);
}
+#ifdef USE_SOFTFLOAT
+
static enum error soft_tester(struct test_op *t)
{
float_status *s = &soft_status;
@@ -445,7 +509,7 @@ static enum error soft_tester(struct test_op *t)
float32 res;
int i;
- g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+ 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;
}
@@ -504,7 +568,7 @@ static enum error soft_tester(struct test_op *t)
float64 *in[] = { &a, &b, &c };
int i;
- g_assert(ops[t->op].n_operands <= ARRAY_SIZE(in));
+ 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;
}
@@ -585,6 +649,14 @@ static const struct tester valid_testers[] = {
.func = host_tester,
},
};
+#else
+static const struct tester valid_testers[] = {
+ [0] = {
+ .name = "host",
+ .func = host_tester,
+ },
+};
+#endif
static const struct tester *tester = &valid_testers[0];
static int ibm_get_exceptions(const char *p, uint8_t *excp)
@@ -622,7 +694,7 @@ static uint64_t fp_choose(enum precision prec, uint64_t f, uint64_t d)
case PREC_DOUBLE:
return d;
default:
- g_assert_not_reached();
+ assert(false);
}
}
@@ -756,7 +828,7 @@ ibm_fp_hex(const char *p, enum precision prec, struct operand *ret)
} else if (prec == PREC_DOUBLE) {
ret->val = double_to_u64(0.0);
} else {
- g_assert_not_reached();
+ assert(false);
}
return 0;
} else if (!strcmp(p, "0x1")) {
@@ -765,7 +837,7 @@ ibm_fp_hex(const char *p, enum precision prec, struct operand *ret)
} else if (prec == PREC_DOUBLE) {
ret->val = double_to_u64(1.0);
} else {
- g_assert_not_reached();
+ assert(false);
}
return 0;
}
@@ -915,10 +987,13 @@ static const struct input *input_type = &valid_input_types[INPUT_FMT_IBM];
static bool line_is_whitelisted(const char *line)
{
- if (whitelist.ht == NULL) {
+ ENTRY e, *ep;
+
+ if (whitelist.ht.size == 0) {
return false;
}
- return !!g_hash_table_lookup(whitelist.ht, line);
+ e.key = line;
+ return hsearch_r(e, FIND, &ep, &whitelist.ht)==0;
}
static void test_file(const char *filename)
@@ -958,7 +1033,7 @@ static void test_file(const char *filename)
filename, i);
break;
default:
- g_assert_not_reached();
+ assert(false);
}
fprintf(stderr, "%s", line);
if (die_on_error) {
@@ -1007,23 +1082,32 @@ static void set_tester(const char *optarg)
static void whitelist_add_line(const char *orig_line)
{
- char *line;
+ char *line = strdup(orig_line);
bool inserted;
+ ENTRY e, *ep;
+ int r;
- if (whitelist.ht == NULL) {
- whitelist.ht = g_hash_table_new(g_str_hash, g_str_equal);
+ if (whitelist.ht.size == 0) {
+ if (!hcreate_r(4096, &whitelist.ht)) {
+ fprintf(stderr, "%s: error creating hash table\n", __func__);
+ }
}
- line = g_hash_table_lookup(whitelist.ht, orig_line);
- if (unlikely(line != NULL)) {
+
+ int hsearch_r(ENTRY item, ACTION action, ENTRY **retval,
+ struct hsearch_data *htab);
+
+ e.key = line;
+ r = hsearch_r(e, FIND, &ep, &whitelist.ht);
+ if (unlikely(r)) {
+ free(line);
return;
}
whitelist.n++;
- whitelist.lines = g_realloc_n(whitelist.lines, whitelist.n, sizeof(line));
- line = strdup(orig_line);
+ whitelist.lines = realloc(whitelist.lines, (whitelist.n * sizeof(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);
+ e.data = line;
+ inserted = hsearch_r(e, ENTER, &ep, &whitelist.ht);
+ assert(inserted);
}
static void set_whitelist(const char *filename)
@@ -1061,18 +1145,20 @@ 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");
+#ifdef USE_SOFTFLOAT
+ fprintf(stderr, " -a = Perform tininess detection after rounding "
+ "(soft tester only). Default: before\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");
+#endif
}
static void parse_opts(int argc, char *argv[])
@@ -1085,9 +1171,6 @@ static void parse_opts(int argc, char *argv[])
return;
}
switch (c) {
- case 'a':
- soft_status.float_detect_tininess = float_tininess_after_rounding;
- break;
case 'e':
set_default_exceptions(optarg);
break;
@@ -1106,15 +1189,20 @@ static void parse_opts(int argc, char *argv[])
case 'w':
set_whitelist(optarg);
break;
+#ifdef USE_SOFTFLOAT
+ case 'a':
+ soft_status.float_detect_tininess = float_tininess_after_rounding;
+ break;
case 'z':
soft_status.flush_inputs_to_zero = 1;
break;
case 'Z':
soft_status.flush_to_zero = 1;
break;
+#endif
}
}
- g_assert_not_reached();
+ assert(false);
}
static uint64_t count_errors(void)
diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile
index 2bba0d2a32..9c8011063e 100644
--- a/tests/tcg/Makefile
+++ b/tests/tcg/Makefile
@@ -24,6 +24,9 @@
VPATH = $(SRC_PATH)/tests/tcg/multiarch
TEST_SRCS = $(wildcard $(SRC_PATH)/tests/tcg/multiarch/*.c)
+VPATH += $(SRC_PATH)/tests/fp
+TEST_SRCS += $(wildcard $(SRC_PATH)/tests/fp/*.c)
+
VPATH += $(SRC_PATH)/tests/tcg/$(ARCH)
TEST_SRCS += $(wildcard $(SRC_PATH)/tests/tcg/$(ARCH)/*.c)
--
2.16.2
--8<---------------cut here---------------end--------------->8---
--
Alex Bennée
next prev parent reply other threads:[~2018-04-11 1:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-04 23:11 [Qemu-devel] [PATCH v3 00/15] fp-test + hardfloat Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 01/15] tests: add fp-test, a floating point test suite Emilio G. Cota
2018-04-11 1:20 ` Alex Bennée [this message]
2018-04-11 1:39 ` Alex Bennée
2018-04-11 21:36 ` Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 02/15] softfloat: fix {min, max}nummag for same-abs-value inputs Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 03/15] fp-test: add muladd variants Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 04/15] softfloat: add float{32, 64}_is_{de, }normal Emilio G. Cota
2018-04-06 12:01 ` Bastian Koppelmann
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 05/15] target/tricore: use float32_is_denormal Emilio G. Cota
2018-04-06 12:01 ` Bastian Koppelmann
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 06/15] tests/fp: add fp-bench, a collection of simple floating point microbenchmarks Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 07/15] softfloat: rename canonicalize to sf_canonicalize Emilio G. Cota
2018-04-06 12:02 ` Bastian Koppelmann
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 08/15] softfloat: add float{32, 64}_is_zero_or_normal Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 09/15] fpu: introduce hardfloat Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 10/15] hardfloat: support float32/64 addition and subtraction Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 11/15] hardfloat: support float32/64 multiplication Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 12/15] hardfloat: support float32/64 division Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 13/15] hardfloat: support float32/64 fused multiply-add Emilio G. Cota
2018-04-04 23:16 ` Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 14/15] hardfloat: support float32/64 square root Emilio G. Cota
2018-04-04 23:17 ` Emilio G. Cota
2018-04-04 23:11 ` [Qemu-devel] [PATCH v3 15/15] hardfloat: support float32/64 comparison Emilio G. Cota
2018-04-04 23:31 ` [Qemu-devel] [PATCH v3 00/15] fp-test + hardfloat no-reply
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=874lki5yj2.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=aurelien@aurel32.net \
--cc=cota@braap.org \
--cc=laurent@vivier.eu \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--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).