Hexagon: fix F2_conv_* instructions for negative zero
The implementation for these instructions handles -0 as an invalid float point value, whereas the Hexagon hardware considers it the same as +0 (which is valid). Let's fix that and add a regression test. Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> Reviewed-by: Brian Cain <bcain@quicinc.com> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <bcain@quicinc.com>
This commit is contained in:
parent
4c395ac42e
commit
6146060a68
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -683,7 +683,7 @@ uint32_t HELPER(conv_sf2uw)(CPUHexagonState *env, float32 RsV)
|
|||||||
uint32_t RdV;
|
uint32_t RdV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV)) {
|
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RdV = 0;
|
RdV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -713,7 +713,7 @@ uint64_t HELPER(conv_sf2ud)(CPUHexagonState *env, float32 RsV)
|
|||||||
uint64_t RddV;
|
uint64_t RddV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV)) {
|
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RddV = 0;
|
RddV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -743,7 +743,7 @@ uint32_t HELPER(conv_df2uw)(CPUHexagonState *env, float64 RssV)
|
|||||||
uint32_t RdV;
|
uint32_t RdV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV)) {
|
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RdV = 0;
|
RdV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -773,7 +773,7 @@ uint64_t HELPER(conv_df2ud)(CPUHexagonState *env, float64 RssV)
|
|||||||
uint64_t RddV;
|
uint64_t RddV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV)) {
|
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RddV = 0;
|
RddV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -803,7 +803,7 @@ uint32_t HELPER(conv_sf2uw_chop)(CPUHexagonState *env, float32 RsV)
|
|||||||
uint32_t RdV;
|
uint32_t RdV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV)) {
|
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RdV = 0;
|
RdV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -833,7 +833,7 @@ uint64_t HELPER(conv_sf2ud_chop)(CPUHexagonState *env, float32 RsV)
|
|||||||
uint64_t RddV;
|
uint64_t RddV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV)) {
|
if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RddV = 0;
|
RddV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -863,7 +863,7 @@ uint32_t HELPER(conv_df2uw_chop)(CPUHexagonState *env, float64 RssV)
|
|||||||
uint32_t RdV;
|
uint32_t RdV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV)) {
|
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RdV = 0;
|
RdV = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -893,7 +893,7 @@ uint64_t HELPER(conv_df2ud_chop)(CPUHexagonState *env, float64 RssV)
|
|||||||
uint64_t RddV;
|
uint64_t RddV;
|
||||||
arch_fpop_start(env);
|
arch_fpop_start(env);
|
||||||
/* Hexagon checks the sign before rounding */
|
/* Hexagon checks the sign before rounding */
|
||||||
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV)) {
|
if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
|
||||||
float_raise(float_flag_invalid, &env->fp_status);
|
float_raise(float_flag_invalid, &env->fp_status);
|
||||||
RddV = 0;
|
RddV = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -1007,6 +1007,11 @@ int main()
|
|||||||
TEST_P_OP_R(conv_sf2d_chop, SF_QNaN, 0xffffffffffffffffULL, USR_FPINVF);
|
TEST_P_OP_R(conv_sf2d_chop, SF_QNaN, 0xffffffffffffffffULL, USR_FPINVF);
|
||||||
TEST_P_OP_R(conv_sf2d_chop, SF_SNaN, 0xffffffffffffffffULL, USR_FPINVF);
|
TEST_P_OP_R(conv_sf2d_chop, SF_SNaN, 0xffffffffffffffffULL, USR_FPINVF);
|
||||||
|
|
||||||
|
TEST_R_OP_R(conv_sf2uw, SF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_R_OP_R(conv_sf2uw_chop, SF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_P_OP_R(conv_sf2ud, SF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_P_OP_R(conv_sf2ud_chop, SF_zero_neg, 0, USR_CLEAR);
|
||||||
|
|
||||||
TEST_R_OP_P(conv_df2sf, DF_QNaN, SF_HEX_NaN, USR_CLEAR);
|
TEST_R_OP_P(conv_df2sf, DF_QNaN, SF_HEX_NaN, USR_CLEAR);
|
||||||
TEST_R_OP_P(conv_df2sf, DF_SNaN, SF_HEX_NaN, USR_FPINVF);
|
TEST_R_OP_P(conv_df2sf, DF_SNaN, SF_HEX_NaN, USR_FPINVF);
|
||||||
TEST_R_OP_P(conv_df2uw, DF_QNaN, 0xffffffff, USR_FPINVF);
|
TEST_R_OP_P(conv_df2uw, DF_QNaN, 0xffffffff, USR_FPINVF);
|
||||||
@ -1020,6 +1025,11 @@ int main()
|
|||||||
TEST_R_OP_P(conv_df2uw_chop, DF_QNaN, 0xffffffff, USR_FPINVF);
|
TEST_R_OP_P(conv_df2uw_chop, DF_QNaN, 0xffffffff, USR_FPINVF);
|
||||||
TEST_R_OP_P(conv_df2uw_chop, DF_SNaN, 0xffffffff, USR_FPINVF);
|
TEST_R_OP_P(conv_df2uw_chop, DF_SNaN, 0xffffffff, USR_FPINVF);
|
||||||
|
|
||||||
|
TEST_R_OP_P(conv_df2uw, DF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_R_OP_P(conv_df2uw_chop, DF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_P_OP_P(conv_df2ud, DF_zero_neg, 0, USR_CLEAR);
|
||||||
|
TEST_P_OP_P(conv_df2ud_chop, DF_zero_neg, 0, USR_CLEAR);
|
||||||
|
|
||||||
/* Test for typo in HELPER(conv_df2uw_chop) */
|
/* Test for typo in HELPER(conv_df2uw_chop) */
|
||||||
TEST_R_OP_P(conv_df2uw_chop, 0xffffff7f00000001ULL, 0xffffffff, USR_FPINVF);
|
TEST_R_OP_P(conv_df2uw_chop, 0xffffff7f00000001ULL, 0xffffffff, USR_FPINVF);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user