Hexagon (target/hexagon) use softfloat default NaN and tininess
Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-11-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8c36752435
commit
c0336c87b7
@ -145,6 +145,9 @@ static FloatParts parts_default_nan(float_status *status)
|
||||
#elif defined(TARGET_HPPA)
|
||||
/* snan_bit_is_one, set msb-1. */
|
||||
frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
|
||||
#elif defined(TARGET_HEXAGON)
|
||||
sign = 1;
|
||||
frac = ~0ULL;
|
||||
#else
|
||||
/* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
|
||||
* S390, SH4, TriCore, and Xtensa. I cannot find documentation
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "exec/exec-all.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
|
||||
static void hexagon_v67_cpu_init(Object *obj)
|
||||
{
|
||||
@ -205,8 +206,12 @@ static void hexagon_cpu_reset(DeviceState *dev)
|
||||
CPUState *cs = CPU(dev);
|
||||
HexagonCPU *cpu = HEXAGON_CPU(cs);
|
||||
HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(cpu);
|
||||
CPUHexagonState *env = &cpu->env;
|
||||
|
||||
mcc->parent_reset(dev);
|
||||
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
|
||||
}
|
||||
|
||||
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
|
||||
|
@ -296,26 +296,6 @@ int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, int32_t M, int32_t CS)
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hexagon FP operations return ~0 instead of NaN
|
||||
* The hex_check_sfnan/hex_check_dfnan functions perform this check
|
||||
*/
|
||||
static float32 hex_check_sfnan(float32 x)
|
||||
{
|
||||
if (float32_is_any_nan(x)) {
|
||||
return make_float32(0xFFFFFFFFU);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static float64 hex_check_dfnan(float64 x)
|
||||
{
|
||||
if (float64_is_any_nan(x)) {
|
||||
return make_float64(0xFFFFFFFFFFFFFFFFULL);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_noshuf
|
||||
* Section 5.5 of the Hexagon V67 Programmer's Reference Manual
|
||||
@ -373,7 +353,6 @@ float64 HELPER(conv_sf2df)(CPUHexagonState *env, float32 RsV)
|
||||
float64 out_f64;
|
||||
arch_fpop_start(env);
|
||||
out_f64 = float32_to_float64(RsV, &env->fp_status);
|
||||
out_f64 = hex_check_dfnan(out_f64);
|
||||
arch_fpop_end(env);
|
||||
return out_f64;
|
||||
}
|
||||
@ -383,7 +362,6 @@ float32 HELPER(conv_df2sf)(CPUHexagonState *env, float64 RssV)
|
||||
float32 out_f32;
|
||||
arch_fpop_start(env);
|
||||
out_f32 = float64_to_float32(RssV, &env->fp_status);
|
||||
out_f32 = hex_check_sfnan(out_f32);
|
||||
arch_fpop_end(env);
|
||||
return out_f32;
|
||||
}
|
||||
@ -393,7 +371,6 @@ float32 HELPER(conv_uw2sf)(CPUHexagonState *env, int32_t RsV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = uint32_to_float32(RsV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -403,7 +380,6 @@ float64 HELPER(conv_uw2df)(CPUHexagonState *env, int32_t RsV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = uint32_to_float64(RsV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -413,7 +389,6 @@ float32 HELPER(conv_w2sf)(CPUHexagonState *env, int32_t RsV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = int32_to_float32(RsV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -423,7 +398,6 @@ float64 HELPER(conv_w2df)(CPUHexagonState *env, int32_t RsV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = int32_to_float64(RsV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -433,7 +407,6 @@ float32 HELPER(conv_ud2sf)(CPUHexagonState *env, int64_t RssV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = uint64_to_float32(RssV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -443,7 +416,6 @@ float64 HELPER(conv_ud2df)(CPUHexagonState *env, int64_t RssV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = uint64_to_float64(RssV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -453,7 +425,6 @@ float32 HELPER(conv_d2sf)(CPUHexagonState *env, int64_t RssV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = int64_to_float32(RssV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -463,7 +434,6 @@ float64 HELPER(conv_d2df)(CPUHexagonState *env, int64_t RssV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = int64_to_float64(RssV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -625,7 +595,6 @@ float32 HELPER(sfadd)(CPUHexagonState *env, float32 RsV, float32 RtV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = float32_add(RsV, RtV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -635,7 +604,6 @@ float32 HELPER(sfsub)(CPUHexagonState *env, float32 RsV, float32 RtV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = float32_sub(RsV, RtV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -687,7 +655,6 @@ float32 HELPER(sfmax)(CPUHexagonState *env, float32 RsV, float32 RtV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = float32_maxnum(RsV, RtV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -697,7 +664,6 @@ float32 HELPER(sfmin)(CPUHexagonState *env, float32 RsV, float32 RtV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = float32_minnum(RsV, RtV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -764,7 +730,6 @@ float64 HELPER(dfadd)(CPUHexagonState *env, float64 RssV, float64 RttV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = float64_add(RssV, RttV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -774,7 +739,6 @@ float64 HELPER(dfsub)(CPUHexagonState *env, float64 RssV, float64 RttV)
|
||||
float64 RddV;
|
||||
arch_fpop_start(env);
|
||||
RddV = float64_sub(RssV, RttV, &env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -787,7 +751,6 @@ float64 HELPER(dfmax)(CPUHexagonState *env, float64 RssV, float64 RttV)
|
||||
if (float64_is_any_nan(RssV) || float64_is_any_nan(RttV)) {
|
||||
float_raise(float_flag_invalid, &env->fp_status);
|
||||
}
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -800,7 +763,6 @@ float64 HELPER(dfmin)(CPUHexagonState *env, float64 RssV, float64 RttV)
|
||||
if (float64_is_any_nan(RssV) || float64_is_any_nan(RttV)) {
|
||||
float_raise(float_flag_invalid, &env->fp_status);
|
||||
}
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
arch_fpop_end(env);
|
||||
return RddV;
|
||||
}
|
||||
@ -876,7 +838,6 @@ float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV)
|
||||
float32 RdV;
|
||||
arch_fpop_start(env);
|
||||
RdV = internal_mpyf(RsV, RtV, &env->fp_status);
|
||||
RdV = hex_check_sfnan(RdV);
|
||||
arch_fpop_end(env);
|
||||
return RdV;
|
||||
}
|
||||
@ -886,7 +847,6 @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
|
||||
{
|
||||
arch_fpop_start(env);
|
||||
RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
|
||||
RxV = hex_check_sfnan(RxV);
|
||||
arch_fpop_end(env);
|
||||
return RxV;
|
||||
}
|
||||
@ -918,7 +878,6 @@ float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
|
||||
RxV = check_nan(RxV, RsV, &env->fp_status);
|
||||
RxV = check_nan(RxV, RtV, &env->fp_status);
|
||||
tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
|
||||
tmp = hex_check_sfnan(tmp);
|
||||
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
|
||||
RxV = tmp;
|
||||
}
|
||||
@ -933,7 +892,6 @@ float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
|
||||
arch_fpop_start(env);
|
||||
neg_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
|
||||
RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
|
||||
RxV = hex_check_sfnan(RxV);
|
||||
arch_fpop_end(env);
|
||||
return RxV;
|
||||
}
|
||||
@ -964,7 +922,6 @@ float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
|
||||
RxV = check_nan(RxV, RsV, &env->fp_status);
|
||||
RxV = check_nan(RxV, RtV, &env->fp_status);
|
||||
tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
|
||||
tmp = hex_check_sfnan(tmp);
|
||||
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
|
||||
RxV = tmp;
|
||||
}
|
||||
@ -999,7 +956,6 @@ float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
|
||||
RxV = check_nan(RxV, RtV, &env->fp_status);
|
||||
float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
|
||||
tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status);
|
||||
tmp = hex_check_sfnan(tmp);
|
||||
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
|
||||
RxV = tmp;
|
||||
}
|
||||
@ -1023,13 +979,11 @@ float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)
|
||||
float64_is_normal(RttV)) {
|
||||
RddV = float64_mul(RssV, make_float64(0x4330000000000000),
|
||||
&env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
} else if (float64_is_denormal(RttV) &&
|
||||
(float64_getexp(RssV) >= 512) &&
|
||||
float64_is_normal(RssV)) {
|
||||
RddV = float64_mul(RssV, make_float64(0x3cb0000000000000),
|
||||
&env->fp_status);
|
||||
RddV = hex_check_dfnan(RddV);
|
||||
} else {
|
||||
RddV = RssV;
|
||||
}
|
||||
@ -1042,7 +996,6 @@ float64 HELPER(dfmpyhh)(CPUHexagonState *env, float64 RxxV,
|
||||
{
|
||||
arch_fpop_start(env);
|
||||
RxxV = internal_mpyhh(RssV, RttV, RxxV, &env->fp_status);
|
||||
RxxV = hex_check_dfnan(RxxV);
|
||||
arch_fpop_end(env);
|
||||
return RxxV;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user