Skip to content

Commit 7619129

Browse files
rth7680pm215
authored andcommitted
target/arm: Fix FJCVTZS vs flush-to-zero
Input denormals cause the Javascript inexact bit (output to Z) to be set. Cc: [email protected] Fixes: 6c1f6f2 ("target/arm: Implement ARMv8.3-JSConv") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375 Reviewed-by: Peter Maydell <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Message-id: [email protected] [PMM: fixed hardcoded tab in test case] Signed-off-by: Peter Maydell <[email protected]>
1 parent a5b72cc commit 7619129

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

target/arm/vfp_helper.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -1091,22 +1091,22 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
10911091
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
10921092
{
10931093
float_status *status = vstatus;
1094-
uint32_t inexact, frac;
1095-
uint32_t e_old, e_new;
1094+
uint32_t frac, e_old, e_new;
1095+
bool inexact;
10961096

10971097
e_old = get_float_exception_flags(status);
10981098
set_float_exception_flags(0, status);
10991099
frac = float64_to_int32_modulo(value, float_round_to_zero, status);
11001100
e_new = get_float_exception_flags(status);
11011101
set_float_exception_flags(e_old | e_new, status);
11021102

1103-
if (value == float64_chs(float64_zero)) {
1104-
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
1105-
inexact = 1;
1106-
} else {
1107-
/* Normal inexact or overflow or NaN */
1108-
inexact = e_new & (float_flag_inexact | float_flag_invalid);
1109-
}
1103+
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
1104+
inexact = e_new & (float_flag_inexact |
1105+
float_flag_input_denormal |
1106+
float_flag_invalid);
1107+
1108+
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
1109+
inexact |= value == float64_chs(float64_zero);
11101110

11111111
/* Pack the result and the env->ZF representation of Z together. */
11121112
return deposit64(frac, 32, 32, inexact);

tests/tcg/aarch64/Makefile.target

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ endif
4141

4242
# Pauth Tests
4343
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
44-
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
44+
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375
4545
pauth-%: CFLAGS += -march=armv8.3-a
46+
test-2375: CFLAGS += -march=armv8.3-a
4647
run-pauth-1: QEMU_OPTS += -cpu max
4748
run-pauth-2: QEMU_OPTS += -cpu max
4849
# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].

tests/tcg/aarch64/test-2375.c

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/* Copyright (c) 2024 Linaro Ltd */
3+
/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
4+
5+
#include <assert.h>
6+
7+
int main(void)
8+
{
9+
int r, z;
10+
11+
asm("msr fpcr, %2\n\t"
12+
"fjcvtzs %w0, %d3\n\t"
13+
"cset %1, eq"
14+
: "=r"(r), "=r"(z)
15+
: "r"(0x01000000L), /* FZ = 1 */
16+
"w"(0xfcff00L)); /* denormal */
17+
18+
assert(r == 0);
19+
assert(z == 0);
20+
return 0;
21+
}

0 commit comments

Comments
 (0)