Some more softfloat/fpu fixes
- make check-softfloat - fixes for fp-bench - workaround broken host fma - compile fix for s390x/clang - fixed for bigendian (v2) - minor makefile tweaks (v2) -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAlxIUhEACgkQ+9DbCVqe KkRCGQf/T3GW3Y2I/3VAbHGAtgFMcs7R73rDjcU35wcNxQKqTOxz6vBVWq0wvYj0 hYsIKx9gpH8pk07ZVZ+g7BK75tB+KiHxjPcmDz2B7jI1CRxK2nYZ8hXSZfYb62uS lGa34yzbMQFq/P2n4ENdiRmFn9nOdv/Meff1VQB4cKO6hExt22r+uqydrV4S2+d9 MBAtxzA/sMWM6Tdq0CdiM1jHJie+Ac/Z5NhImSUMulkhTnPIhr1iOfNV+IjLKpbW ah4brjRXndKUKb3zL3EgH5a37FOinDGB9UfY6PgCwbmGa/aBtDmIEtAgq9T2uTPI Lore/sYOLJwURRtJcG/ClWAf/QpGCQ== =MwxC -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stsquad/tags/pull-fpu-next-230119-2' into staging Some more softfloat/fpu fixes - make check-softfloat - fixes for fp-bench - workaround broken host fma - compile fix for s390x/clang - fixed for bigendian (v2) - minor makefile tweaks (v2) # gpg: Signature made Wed 23 Jan 2019 11:37:53 GMT # gpg: using RSA key FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-fpu-next-230119-2: tests/Makefile: add check-softfloat rule scripts/archive-source: include softfloat tests tests/Makefile: add floating point tests include/fpu/softfloat: Fix compilation with Clang on s390x softfloat: enforce softfloat if the host's FMA is broken tests/fp/platform.h: include config-host.h fp-test: fix signature of slow_clear_flags and qemu_clear_flags tests/fp/Makefile: do not use gcc-only -W flags berkeley-testfloat-3: pull changes fp-bench: remove wrong exponent raise in fill_random fp-bench: fix update_random_ops Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3e821195b1
@ -1542,6 +1542,8 @@ soft_f64_muladd(float64 a, float64 b, float64 c, int flags,
|
||||
return float64_round_pack_canonical(pr, status);
|
||||
}
|
||||
|
||||
static bool force_soft_fma;
|
||||
|
||||
float32 QEMU_FLATTEN
|
||||
float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
|
||||
{
|
||||
@ -1562,6 +1564,11 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
|
||||
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
|
||||
goto soft;
|
||||
}
|
||||
|
||||
if (unlikely(force_soft_fma)) {
|
||||
goto soft;
|
||||
}
|
||||
|
||||
/*
|
||||
* When (a || b) == 0, there's no need to check for under/over flow,
|
||||
* since we know the addend is (normal || 0) and the product is 0.
|
||||
@ -1623,6 +1630,11 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
|
||||
if (unlikely(!f64_is_zon3(ua, ub, uc))) {
|
||||
goto soft;
|
||||
}
|
||||
|
||||
if (unlikely(force_soft_fma)) {
|
||||
goto soft;
|
||||
}
|
||||
|
||||
/*
|
||||
* When (a || b) == 0, there's no need to check for under/over flow,
|
||||
* since we know the addend is (normal || 0) and the product is 0.
|
||||
@ -7974,3 +7986,24 @@ float128 float128_scalbn(float128 a, int n, float_status *status)
|
||||
, status);
|
||||
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) softfloat_init(void)
|
||||
{
|
||||
union_float64 ua, ub, uc, ur;
|
||||
|
||||
if (QEMU_NO_HARDFLOAT) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Test that the host's FMA is not obviously broken. For example,
|
||||
* glibc < 2.23 can perform an incorrect FMA on certain hosts; see
|
||||
* https://sourceware.org/bugzilla/show_bug.cgi?id=13304
|
||||
*/
|
||||
ua.s = 0x0020000000000001ULL;
|
||||
ub.s = 0x3ca0000000000000ULL;
|
||||
uc.s = 0x0020000000000000ULL;
|
||||
ur.h = fma(ua.h, ub.h, uc.h);
|
||||
if (ur.s != 0x0020000000000001ULL) {
|
||||
force_soft_fma = true;
|
||||
}
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
|
||||
uint64_t q;
|
||||
asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
|
||||
return q;
|
||||
#elif defined(__s390x__)
|
||||
#elif defined(__s390x__) && !defined(__clang__)
|
||||
/* Need to use a TImode type to get an even register pair for DLGR. */
|
||||
unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
|
||||
asm("dlgr %0, %1" : "+r"(n) : "r"(d));
|
||||
|
@ -26,7 +26,7 @@ vroot_dir="${tar_file}.vroot"
|
||||
# independent of what the developer currently has initialized
|
||||
# in their checkout, because the build environment is completely
|
||||
# different to the host OS.
|
||||
submodules="dtc ui/keycodemapdb"
|
||||
submodules="dtc ui/keycodemapdb tests/fp/berkeley-softfloat-3 tests/fp/berkeley-testfloat-3"
|
||||
|
||||
trap "status=$?; rm -rf \"$list_file\" \"$vroot_dir\"; exit \$status" 0 1 2 3 15
|
||||
|
||||
|
@ -12,6 +12,7 @@ check-help:
|
||||
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
|
||||
@echo " $(MAKE) check-block Run block tests"
|
||||
@echo " $(MAKE) check-tcg Run TCG tests"
|
||||
@echo " $(MAKE) check-softfloat Run FPU emulation tests"
|
||||
@echo " $(MAKE) check-acceptance Run all acceptance (functional) tests"
|
||||
@echo
|
||||
@echo " $(MAKE) check-report.html Generates an HTML test report"
|
||||
@ -880,6 +881,138 @@ check-report-unit.tap: $(check-unit-y)
|
||||
check-report.tap: $(patsubst %,check-report-qtest-%.tap, $(QTEST_TARGETS)) check-report-unit.tap
|
||||
$(call quiet-command,./scripts/tap-merge.py $^ > $@,"GEN","$@")
|
||||
|
||||
# FPU Emulation tests (aka softfloat)
|
||||
#
|
||||
# As we still have some places that need fixing the rules are a little
|
||||
# more complex than they need to be and have to override some of the
|
||||
# generic Makefile expansions. Once we are cleanly passing all
|
||||
# the tests we can simplify the make syntax.
|
||||
|
||||
FP_TEST_BIN=$(BUILD_DIR)/tests/fp/fp-test
|
||||
|
||||
# the build dir is created by configure
|
||||
.PHONY: $(FP_TEST_BIN)
|
||||
$(FP_TEST_BIN):
|
||||
$(call quiet-command, \
|
||||
$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" $(notdir $@), \
|
||||
"BUILD", "$(notdir $@)")
|
||||
|
||||
# The full test suite can take a bit of time, default to a quick run
|
||||
ifeq ($(SPEED), quick)
|
||||
FP_TL=-l 1
|
||||
else
|
||||
FP_TL=-l 2 -r all
|
||||
endif
|
||||
|
||||
# $1 = tests, $2 = description
|
||||
test-softfloat = $(call quiet-command, \
|
||||
cd $(BUILD_DIR)/tests/fp && \
|
||||
./fp-test -s $(FP_TL) $1 > $2.out 2>&1 || \
|
||||
(cat $2.out && exit 1;), \
|
||||
"FLOAT TEST", $2)
|
||||
|
||||
# Conversion Routines:
|
||||
# FIXME: i32_to_extF80 (broken), i64_to_extF80 (broken)
|
||||
# ui32_to_f128 (not implemented), f128_to_ui32 (not implemented)
|
||||
# extF80_roundToInt (broken)
|
||||
#
|
||||
check-softfloat-conv: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, \
|
||||
i32_to_f16 i64_to_f16 \
|
||||
i32_to_f32 i64_to_f32 \
|
||||
i32_to_f64 i64_to_f64 \
|
||||
i32_to_f128 i64_to_f128, int-to-float)
|
||||
$(call test-softfloat, \
|
||||
ui32_to_f16 ui64_to_f16 \
|
||||
ui32_to_f32 ui64_to_f32 \
|
||||
ui32_to_f64 ui64_to_f64 \
|
||||
ui64_to_f128, uint-to-float)
|
||||
$(call test-softfloat, \
|
||||
f16_to_i32 f16_to_i32_r_minMag \
|
||||
f32_to_i32 f32_to_i32_r_minMag \
|
||||
f64_to_i32 f64_to_i32_r_minMag \
|
||||
extF80_to_i32 extF80_to_i32_r_minMag \
|
||||
f128_to_i32 f128_to_i32_r_minMag \
|
||||
f16_to_i64 f16_to_i64_r_minMag \
|
||||
f32_to_i64 f32_to_i64_r_minMag \
|
||||
f64_to_i64 f64_to_i64_r_minMag \
|
||||
extF80_to_i64 extF80_to_i64_r_minMag \
|
||||
f128_to_i64 f128_to_i64_r_minMag, \
|
||||
float-to-int)
|
||||
$(call test-softfloat, \
|
||||
f16_to_ui32 f16_to_ui32_r_minMag \
|
||||
f32_to_ui32 f32_to_ui32_r_minMag \
|
||||
f64_to_ui32 f64_to_ui32_r_minMag \
|
||||
f16_to_ui64 f16_to_ui64_r_minMag \
|
||||
f32_to_ui64 f32_to_ui64_r_minMag \
|
||||
f64_to_ui64 f64_to_ui64_r_minMag, \
|
||||
float-to-uint)
|
||||
$(call test-softfloat, \
|
||||
f16_roundToInt f32_roundToInt \
|
||||
f64_roundToInt f128_roundToInt, \
|
||||
round-to-integer)
|
||||
|
||||
# Generic rule for all float operations
|
||||
#
|
||||
# Some patterns are overidden due to broken or missing tests.
|
||||
# Hopefully these can be removed over time.
|
||||
|
||||
check-softfloat-%: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, f16_$* f32_$* f64_$* extF80_$* f128_$*, $*)
|
||||
|
||||
# Float Compare routines
|
||||
SF_COMPARE_OPS=eq eq_signaling le le_quiet lt_quiet
|
||||
SF_COMPARE_RULES=$(patsubst %,check-softfloat-%, $(SF_COMPARE_OPS))
|
||||
|
||||
# FIXME: extF80_le_quiet (broken)
|
||||
check-softfloat-le_quiet: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, \
|
||||
f16_le_quiet f32_le_quiet f64_le_quiet \
|
||||
f128_le_quiet, \
|
||||
le_quiet)
|
||||
|
||||
# FIXME: extF80_lt_quiet (broken)
|
||||
check-softfloat-lt_quiet: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, \
|
||||
f16_lt_quiet f32_lt_quiet f64_lt_quiet \
|
||||
f128_lt_quiet, \
|
||||
lt_quiet)
|
||||
|
||||
.PHONY: check-softfloat-compare
|
||||
check-softfloat-compare: $(SF_COMPARE_RULES)
|
||||
|
||||
# Math Operations
|
||||
|
||||
# FIXME: extF80_mulAdd (missing)
|
||||
check-softfloat-mulAdd: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, \
|
||||
f16_mulAdd f32_mulAdd f64_mulAdd f128_mulAdd, \
|
||||
mulAdd)
|
||||
|
||||
# FIXME: extF80_rem (broken)
|
||||
check-softfloat-rem: $(FP_TEST_BIN)
|
||||
$(call test-softfloat, \
|
||||
f16_rem f32_rem f64_rem f128_rem, \
|
||||
rem)
|
||||
|
||||
SF_MATH_OPS=add sub mul mulAdd div rem sqrt
|
||||
SF_MATH_RULES=$(patsubst %,check-softfloat-%, $(SF_MATH_OPS))
|
||||
|
||||
.PHONY: check-softfloat-ops
|
||||
check-softfloat-ops: $(SF_MATH_RULES)
|
||||
|
||||
# Finally a generic rule to test all of softfoat. If TCG isnt't
|
||||
# enabled we define a null operation which skips the tests.
|
||||
|
||||
.PHONY: check-softfloat
|
||||
ifeq ($(CONFIG_TCG),y)
|
||||
check-softfloat: check-softfloat-conv check-softfloat-compare check-softfloat-ops
|
||||
else
|
||||
check-softfloat:
|
||||
$(call quiet-command, /bin/true, "FLOAT TEST", \
|
||||
"SKIPPED for non-TCG builds")
|
||||
endif
|
||||
|
||||
# Per guest TCG tests
|
||||
|
||||
LINUX_USER_TARGETS=$(filter %-linux-user,$(TARGET_DIRS))
|
||||
@ -912,7 +1045,7 @@ clean-tcg-tests-%:
|
||||
build-tcg: $(BUILD_TCG_TARGET_RULES)
|
||||
|
||||
.PHONY: check-tcg
|
||||
check-tcg: $(RUN_TCG_TARGET_RULES)
|
||||
check-tcg: check-softfloat $(RUN_TCG_TARGET_RULES)
|
||||
|
||||
.PHONY: clean-tcg
|
||||
clean-tcg: $(CLEAN_TCG_TARGET_RULES)
|
||||
@ -993,7 +1126,7 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR)
|
||||
check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) check-tests/qapi-schema/doc-good.texi
|
||||
check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
|
||||
check-block: $(patsubst %,check-%, $(check-block-y))
|
||||
check: check-qapi-schema check-unit check-qtest check-decodetree
|
||||
check: check-qapi-schema check-unit check-softfloat check-qtest check-decodetree
|
||||
check-clean:
|
||||
rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
|
||||
rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y)) $(check-qtest-generic-y))
|
||||
|
@ -65,8 +65,7 @@ QEMU_CFLAGS += $(TF_OPTS)
|
||||
TF_CFLAGS :=
|
||||
TF_CFLAGS += -Wno-strict-prototypes
|
||||
TF_CFLAGS += -Wno-unknown-pragmas
|
||||
TF_CFLAGS += -Wno-discarded-qualifiers
|
||||
TF_CFLAGS += -Wno-maybe-uninitialized
|
||||
TF_CFLAGS += -Wno-uninitialized
|
||||
TF_CFLAGS += -Wno-missing-prototypes
|
||||
TF_CFLAGS += -Wno-return-type
|
||||
TF_CFLAGS += -Wno-unused-function
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit ca9fa2ba05625ba929958f163b01747e07dd39cc
|
||||
Subproject commit 5a59dcec19327396a011a17fd924aed4fec416b3
|
@ -143,15 +143,20 @@ static void update_random_ops(int n_ops, enum precision prec)
|
||||
for (i = 0; i < n_ops; i++) {
|
||||
uint64_t r = random_ops[i];
|
||||
|
||||
if (prec == PREC_SINGLE || PREC_FLOAT32) {
|
||||
switch (prec) {
|
||||
case PREC_SINGLE:
|
||||
case PREC_FLOAT32:
|
||||
do {
|
||||
r = xorshift64star(r);
|
||||
} while (!float32_is_normal(r));
|
||||
} else if (prec == PREC_DOUBLE || PREC_FLOAT64) {
|
||||
break;
|
||||
case PREC_DOUBLE:
|
||||
case PREC_FLOAT64:
|
||||
do {
|
||||
r = xorshift64star(r);
|
||||
} while (!float64_is_normal(r));
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
random_ops[i] = r;
|
||||
@ -171,8 +176,6 @@ static void fill_random(union fp *ops, int n_ops, enum precision prec,
|
||||
if (no_neg && float32_is_neg(ops[i].f32)) {
|
||||
ops[i].f32 = float32_chs(ops[i].f32);
|
||||
}
|
||||
/* raise the exponent to limit the frequency of denormal results */
|
||||
ops[i].f32 |= 0x40000000;
|
||||
break;
|
||||
case PREC_DOUBLE:
|
||||
case PREC_FLOAT64:
|
||||
@ -180,8 +183,6 @@ static void fill_random(union fp *ops, int n_ops, enum precision prec,
|
||||
if (no_neg && float64_is_neg(ops[i].f64)) {
|
||||
ops[i].f64 = float64_chs(ops[i].f64);
|
||||
}
|
||||
/* raise the exponent to limit the frequency of denormal results */
|
||||
ops[i].f64 |= LIT64(0x4000000000000000);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -789,7 +789,7 @@ static int set_init_flags(const char *flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t slow_clear_flags(void)
|
||||
static uint_fast8_t slow_clear_flags(void)
|
||||
{
|
||||
uint8_t prev = slowfloat_exceptionFlags;
|
||||
|
||||
@ -797,7 +797,7 @@ static uint8_t slow_clear_flags(void)
|
||||
return prev;
|
||||
}
|
||||
|
||||
static uint8_t qemu_clear_flags(void)
|
||||
static uint_fast8_t qemu_clear_flags(void)
|
||||
{
|
||||
uint8_t prev = qemu_flags_to_sf(qsf.float_exception_flags);
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "config-host.h"
|
||||
|
||||
#ifndef HOST_WORDS_BIGENDIAN
|
||||
#define LITTLEENDIAN 1
|
||||
|
Loading…
Reference in New Issue
Block a user