Skip to content

Commit 10f230b

Browse files
rth7680Michael Tokarev
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]> (cherry picked from commit 7619129) Signed-off-by: Michael Tokarev <[email protected]>
1 parent 10b9e0c commit 10f230b

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

target/arm/vfp_helper.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,22 +1121,22 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
11211121
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
11221122
{
11231123
float_status *status = vstatus;
1124-
uint32_t inexact, frac;
1125-
uint32_t e_old, e_new;
1124+
uint32_t frac, e_old, e_new;
1125+
bool inexact;
11261126

11271127
e_old = get_float_exception_flags(status);
11281128
set_float_exception_flags(0, status);
11291129
frac = float64_to_int32_modulo(value, float_round_to_zero, status);
11301130
e_new = get_float_exception_flags(status);
11311131
set_float_exception_flags(e_old | e_new, status);
11321132

1133-
if (value == float64_chs(float64_zero)) {
1134-
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
1135-
inexact = 1;
1136-
} else {
1137-
/* Normal inexact or overflow or NaN */
1138-
inexact = e_new & (float_flag_inexact | float_flag_invalid);
1139-
}
1133+
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
1134+
inexact = e_new & (float_flag_inexact |
1135+
float_flag_input_denormal |
1136+
float_flag_invalid);
1137+
1138+
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
1139+
inexact |= value == float64_chs(float64_zero);
11401140

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

tests/tcg/aarch64/Makefile.target

Lines changed: 2 additions & 1 deletion
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

Lines changed: 21 additions & 0 deletions
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)