target/arm: Fix FJCVTZS vs flush-to-zero
Input denormals cause the Javascript inexact bit
(output to Z) to be set.
Cc: qemu-stable@nongnu.org
Fixes: 6c1f6f2733
("target/arm: Implement ARMv8.3-JSConv")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240625183536.1672454-4-richard.henderson@linaro.org
[PMM: fixed hardcoded tab in test case]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a5b72ccc0f
commit
7619129f0d
@ -1091,8 +1091,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
|
||||
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
|
||||
{
|
||||
float_status *status = vstatus;
|
||||
uint32_t inexact, frac;
|
||||
uint32_t e_old, e_new;
|
||||
uint32_t frac, e_old, e_new;
|
||||
bool inexact;
|
||||
|
||||
e_old = get_float_exception_flags(status);
|
||||
set_float_exception_flags(0, status);
|
||||
@ -1100,13 +1100,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
|
||||
e_new = get_float_exception_flags(status);
|
||||
set_float_exception_flags(e_old | e_new, status);
|
||||
|
||||
if (value == float64_chs(float64_zero)) {
|
||||
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
inexact = 1;
|
||||
} else {
|
||||
/* Normal inexact or overflow or NaN */
|
||||
inexact = e_new & (float_flag_inexact | float_flag_invalid);
|
||||
}
|
||||
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
|
||||
inexact = e_new & (float_flag_inexact |
|
||||
float_flag_input_denormal |
|
||||
float_flag_invalid);
|
||||
|
||||
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
inexact |= value == float64_chs(float64_zero);
|
||||
|
||||
/* Pack the result and the env->ZF representation of Z together. */
|
||||
return deposit64(frac, 32, 32, inexact);
|
||||
|
@ -41,8 +41,9 @@ endif
|
||||
|
||||
# Pauth Tests
|
||||
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
|
||||
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
|
||||
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375
|
||||
pauth-%: CFLAGS += -march=armv8.3-a
|
||||
test-2375: CFLAGS += -march=armv8.3-a
|
||||
run-pauth-1: QEMU_OPTS += -cpu max
|
||||
run-pauth-2: QEMU_OPTS += -cpu max
|
||||
# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].
|
||||
|
21
tests/tcg/aarch64/test-2375.c
Normal file
21
tests/tcg/aarch64/test-2375.c
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (c) 2024 Linaro Ltd */
|
||||
/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r, z;
|
||||
|
||||
asm("msr fpcr, %2\n\t"
|
||||
"fjcvtzs %w0, %d3\n\t"
|
||||
"cset %1, eq"
|
||||
: "=r"(r), "=r"(z)
|
||||
: "r"(0x01000000L), /* FZ = 1 */
|
||||
"w"(0xfcff00L)); /* denormal */
|
||||
|
||||
assert(r == 0);
|
||||
assert(z == 0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user