* [PATCH v4 0/2] add APIs to handle alternative sNaN propagation for fmax/fmin
@ 2021-10-16 8:54 frank.chang
2021-10-16 8:54 ` frank.chang
2021-10-16 8:54 ` frank.chang
0 siblings, 2 replies; 10+ messages in thread
From: frank.chang @ 2021-10-16 8:54 UTC (permalink / raw)
To: qemu-devel, qemu-riscv; +Cc: Frank Chang
From: Frank Chang <frank.chang@sifive.com>
In IEEE 754-2019, minNum, maxNum, minNumMag and maxNumMag are removed
and replaced with minimum, minimumNumber, maximum and maximumNumber.
minimumNumber/maximumNumber behavior for SNaN is changed to:
* If both operands are NaNs, a QNaN is returned.
* If either operand is a SNaN, an invalid operation exception is signaled,
but unless both operands are NaNs, the SNaN is otherwise ignored and
not converted to a QNaN.
This patchset add support of the above alternative sNaN propagation for
fmax/fmin, which is required by RISC-V floating-point v2.2.
Changelog:
v2:
* Change API names from *_noprop() to *_maximum_number()
and *_minimum_number().
* Pick softfloat min/max APIs based on CPU privilege spec version.
Chih-Min Chao (2):
softfloat: add APIs to handle alternative sNaN propagation for
fmax/fmin
target/riscv: change the api for RVF/RVD fmin/fmax
fpu/softfloat-parts.c.inc | 25 +++++++++++++++++++++++--
fpu/softfloat.c | 19 +++++++++++++------
include/fpu/softfloat.h | 10 ++++++++++
target/riscv/fpu_helper.c | 16 ++++++++++++----
4 files changed, 58 insertions(+), 12 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] softfloat: add APIs to handle alternative sNaN propagation for fmax/fmin
2021-10-16 8:54 [PATCH v4 0/2] add APIs to handle alternative sNaN propagation for fmax/fmin frank.chang
@ 2021-10-16 8:54 ` frank.chang
2021-10-16 8:54 ` frank.chang
1 sibling, 0 replies; 10+ messages in thread
From: frank.chang @ 2021-10-16 8:54 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Frank Chang, Chih-Min Chao, Alex Bennée, Aurelien Jarno,
Peter Maydell
From: Chih-Min Chao <chihmin.chao@sifive.com>
For "fmax/fmin ft0, ft1, ft2" and if one of the inputs is sNaN,
The original logic:
Return NaN and set invalid flag if ft1 == sNaN || ft2 == sNan.
The alternative path:
Set invalid flag if ft1 == sNaN || ft2 == sNaN.
Return NaN only if ft1 == NaN && ft2 == NaN.
The IEEE 754 spec allows both implementation and some architecture such
as riscv choose different defintions in two spec versions.
(riscv-spec-v2.2 use original version, riscv-spec-20191213 changes to
alternative)
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
fpu/softfloat-parts.c.inc | 25 +++++++++++++++++++++++--
fpu/softfloat.c | 19 +++++++++++++------
include/fpu/softfloat.h | 10 ++++++++++
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index dddee92d6ee..41d4b17e419 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1219,14 +1219,35 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
if (unlikely(ab_mask & float_cmask_anynan)) {
/*
- * For minnum/maxnum, if one operand is a QNaN, and the other
+ * For minNum/maxNum (IEEE 754-2008)
+ * or minimumNumber/maximumNumber (IEEE 754-2019),
+ * if one operand is a QNaN, and the other
* operand is numerical, then return numerical argument.
*/
- if ((flags & minmax_isnum)
+ if ((flags & (minmax_isnum | minmax_isnumber))
&& !(ab_mask & float_cmask_snan)
&& (ab_mask & ~float_cmask_qnan)) {
return is_nan(a->cls) ? b : a;
}
+
+ /*
+ * In IEEE 754-2019, minNum, maxNum, minNumMag and maxNumMag
+ * are removed and replaced with minimum, minimumNumber, maximum
+ * and maximumNumber.
+ * minimumNumber/maximumNumber behavior for SNaN is changed to:
+ * If both operands are NaNs, a QNaN is returned.
+ * If either operand is a SNaN,
+ * an invalid operation exception is signaled,
+ * but unless both operands are NaNs,
+ * the SNaN is otherwise ignored and not converted to a QNaN.
+ */
+ if ((flags & minmax_isnumber)
+ && (ab_mask & float_cmask_snan)
+ && (ab_mask & ~float_cmask_anynan)) {
+ float_raise(float_flag_invalid, s);
+ return is_nan(a->cls) ? b : a;
+ }
+
return parts_pick_nan(a, b, s);
}
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6e769f990c2..9a28720d82a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -436,6 +436,11 @@ enum {
minmax_isnum = 2,
/* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */
minmax_ismag = 4,
+ /*
+ * Set for the IEEE 754-2019 minimumNumber() and maximumNumber()
+ * operations.
+ */
+ minmax_isnumber = 8,
};
/* Simple helpers for checking if, or what kind of, NaN we have */
@@ -3927,12 +3932,14 @@ static float128 float128_minmax(float128 a, float128 b,
{ return type##_minmax(a, b, s, flags); }
#define MINMAX_2(type) \
- MINMAX_1(type, max, 0) \
- MINMAX_1(type, maxnum, minmax_isnum) \
- MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
- MINMAX_1(type, min, minmax_ismin) \
- MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
- MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag)
+ MINMAX_1(type, max, 0) \
+ MINMAX_1(type, maxnum, minmax_isnum) \
+ MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
+ MINMAX_1(type, maximum_number, minmax_isnumber) \
+ MINMAX_1(type, min, minmax_ismin) \
+ MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
+ MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \
+ MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \
MINMAX_2(float16)
MINMAX_2(bfloat16)
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index ec7dca09606..a249991e612 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -243,6 +243,8 @@ float16 float16_minnum(float16, float16, float_status *status);
float16 float16_maxnum(float16, float16, float_status *status);
float16 float16_minnummag(float16, float16, float_status *status);
float16 float16_maxnummag(float16, float16, float_status *status);
+float16 float16_minimum_number(float16, float16, float_status *status);
+float16 float16_maximum_number(float16, float16, float_status *status);
float16 float16_sqrt(float16, float_status *status);
FloatRelation float16_compare(float16, float16, float_status *status);
FloatRelation float16_compare_quiet(float16, float16, float_status *status);
@@ -422,6 +424,8 @@ bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_sqrt(bfloat16, float_status *status);
FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status);
FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status);
@@ -589,6 +593,8 @@ float32 float32_minnum(float32, float32, float_status *status);
float32 float32_maxnum(float32, float32, float_status *status);
float32 float32_minnummag(float32, float32, float_status *status);
float32 float32_maxnummag(float32, float32, float_status *status);
+float32 float32_minimum_number(float32, float32, float_status *status);
+float32 float32_maximum_number(float32, float32, float_status *status);
bool float32_is_quiet_nan(float32, float_status *status);
bool float32_is_signaling_nan(float32, float_status *status);
float32 float32_silence_nan(float32, float_status *status);
@@ -778,6 +784,8 @@ float64 float64_minnum(float64, float64, float_status *status);
float64 float64_maxnum(float64, float64, float_status *status);
float64 float64_minnummag(float64, float64, float_status *status);
float64 float64_maxnummag(float64, float64, float_status *status);
+float64 float64_minimum_number(float64, float64, float_status *status);
+float64 float64_maximum_number(float64, float64, float_status *status);
bool float64_is_quiet_nan(float64 a, float_status *status);
bool float64_is_signaling_nan(float64, float_status *status);
float64 float64_silence_nan(float64, float_status *status);
@@ -1210,6 +1218,8 @@ float128 float128_minnum(float128, float128, float_status *status);
float128 float128_maxnum(float128, float128, float_status *status);
float128 float128_minnummag(float128, float128, float_status *status);
float128 float128_maxnummag(float128, float128, float_status *status);
+float128 float128_minimum_number(float128, float128, float_status *status);
+float128 float128_maximum_number(float128, float128, float_status *status);
bool float128_is_quiet_nan(float128, float_status *status);
bool float128_is_signaling_nan(float128, float_status *status);
float128 float128_silence_nan(float128, float_status *status);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] softfloat: add APIs to handle alternative sNaN propagation for fmax/fmin
@ 2021-10-16 8:54 ` frank.chang
0 siblings, 0 replies; 10+ messages in thread
From: frank.chang @ 2021-10-16 8:54 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Chih-Min Chao, Frank Chang, Aurelien Jarno, Peter Maydell,
Alex Bennée
From: Chih-Min Chao <chihmin.chao@sifive.com>
For "fmax/fmin ft0, ft1, ft2" and if one of the inputs is sNaN,
The original logic:
Return NaN and set invalid flag if ft1 == sNaN || ft2 == sNan.
The alternative path:
Set invalid flag if ft1 == sNaN || ft2 == sNaN.
Return NaN only if ft1 == NaN && ft2 == NaN.
The IEEE 754 spec allows both implementation and some architecture such
as riscv choose different defintions in two spec versions.
(riscv-spec-v2.2 use original version, riscv-spec-20191213 changes to
alternative)
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
fpu/softfloat-parts.c.inc | 25 +++++++++++++++++++++++--
fpu/softfloat.c | 19 +++++++++++++------
include/fpu/softfloat.h | 10 ++++++++++
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index dddee92d6ee..41d4b17e419 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1219,14 +1219,35 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
if (unlikely(ab_mask & float_cmask_anynan)) {
/*
- * For minnum/maxnum, if one operand is a QNaN, and the other
+ * For minNum/maxNum (IEEE 754-2008)
+ * or minimumNumber/maximumNumber (IEEE 754-2019),
+ * if one operand is a QNaN, and the other
* operand is numerical, then return numerical argument.
*/
- if ((flags & minmax_isnum)
+ if ((flags & (minmax_isnum | minmax_isnumber))
&& !(ab_mask & float_cmask_snan)
&& (ab_mask & ~float_cmask_qnan)) {
return is_nan(a->cls) ? b : a;
}
+
+ /*
+ * In IEEE 754-2019, minNum, maxNum, minNumMag and maxNumMag
+ * are removed and replaced with minimum, minimumNumber, maximum
+ * and maximumNumber.
+ * minimumNumber/maximumNumber behavior for SNaN is changed to:
+ * If both operands are NaNs, a QNaN is returned.
+ * If either operand is a SNaN,
+ * an invalid operation exception is signaled,
+ * but unless both operands are NaNs,
+ * the SNaN is otherwise ignored and not converted to a QNaN.
+ */
+ if ((flags & minmax_isnumber)
+ && (ab_mask & float_cmask_snan)
+ && (ab_mask & ~float_cmask_anynan)) {
+ float_raise(float_flag_invalid, s);
+ return is_nan(a->cls) ? b : a;
+ }
+
return parts_pick_nan(a, b, s);
}
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6e769f990c2..9a28720d82a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -436,6 +436,11 @@ enum {
minmax_isnum = 2,
/* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */
minmax_ismag = 4,
+ /*
+ * Set for the IEEE 754-2019 minimumNumber() and maximumNumber()
+ * operations.
+ */
+ minmax_isnumber = 8,
};
/* Simple helpers for checking if, or what kind of, NaN we have */
@@ -3927,12 +3932,14 @@ static float128 float128_minmax(float128 a, float128 b,
{ return type##_minmax(a, b, s, flags); }
#define MINMAX_2(type) \
- MINMAX_1(type, max, 0) \
- MINMAX_1(type, maxnum, minmax_isnum) \
- MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
- MINMAX_1(type, min, minmax_ismin) \
- MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
- MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag)
+ MINMAX_1(type, max, 0) \
+ MINMAX_1(type, maxnum, minmax_isnum) \
+ MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
+ MINMAX_1(type, maximum_number, minmax_isnumber) \
+ MINMAX_1(type, min, minmax_ismin) \
+ MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
+ MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \
+ MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \
MINMAX_2(float16)
MINMAX_2(bfloat16)
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index ec7dca09606..a249991e612 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -243,6 +243,8 @@ float16 float16_minnum(float16, float16, float_status *status);
float16 float16_maxnum(float16, float16, float_status *status);
float16 float16_minnummag(float16, float16, float_status *status);
float16 float16_maxnummag(float16, float16, float_status *status);
+float16 float16_minimum_number(float16, float16, float_status *status);
+float16 float16_maximum_number(float16, float16, float_status *status);
float16 float16_sqrt(float16, float_status *status);
FloatRelation float16_compare(float16, float16, float_status *status);
FloatRelation float16_compare_quiet(float16, float16, float_status *status);
@@ -422,6 +424,8 @@ bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_sqrt(bfloat16, float_status *status);
FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status);
FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status);
@@ -589,6 +593,8 @@ float32 float32_minnum(float32, float32, float_status *status);
float32 float32_maxnum(float32, float32, float_status *status);
float32 float32_minnummag(float32, float32, float_status *status);
float32 float32_maxnummag(float32, float32, float_status *status);
+float32 float32_minimum_number(float32, float32, float_status *status);
+float32 float32_maximum_number(float32, float32, float_status *status);
bool float32_is_quiet_nan(float32, float_status *status);
bool float32_is_signaling_nan(float32, float_status *status);
float32 float32_silence_nan(float32, float_status *status);
@@ -778,6 +784,8 @@ float64 float64_minnum(float64, float64, float_status *status);
float64 float64_maxnum(float64, float64, float_status *status);
float64 float64_minnummag(float64, float64, float_status *status);
float64 float64_maxnummag(float64, float64, float_status *status);
+float64 float64_minimum_number(float64, float64, float_status *status);
+float64 float64_maximum_number(float64, float64, float_status *status);
bool float64_is_quiet_nan(float64 a, float_status *status);
bool float64_is_signaling_nan(float64, float_status *status);
float64 float64_silence_nan(float64, float_status *status);
@@ -1210,6 +1218,8 @@ float128 float128_minnum(float128, float128, float_status *status);
float128 float128_maxnum(float128, float128, float_status *status);
float128 float128_minnummag(float128, float128, float_status *status);
float128 float128_maxnummag(float128, float128, float_status *status);
+float128 float128_minimum_number(float128, float128, float_status *status);
+float128 float128_maximum_number(float128, float128, float_status *status);
bool float128_is_quiet_nan(float128, float_status *status);
bool float128_is_signaling_nan(float128, float_status *status);
float128 float128_silence_nan(float128, float_status *status);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
2021-10-16 8:54 [PATCH v4 0/2] add APIs to handle alternative sNaN propagation for fmax/fmin frank.chang
@ 2021-10-16 8:54 ` frank.chang
2021-10-16 8:54 ` frank.chang
1 sibling, 0 replies; 10+ messages in thread
From: frank.chang @ 2021-10-16 8:54 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Frank Chang, Chih-Min Chao, Alistair Francis, Bin Meng, Palmer Dabbelt
From: Chih-Min Chao <chihmin.chao@sifive.com>
The sNaN propagation behavior has been changed since
cd20cee7 in https://github.com/riscv/riscv-isa-manual.
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
target/riscv/fpu_helper.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 8700516a14c..d62f4709002 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
{
float32 frs1 = check_nanbox_s(rs1);
float32 frs2 = check_nanbox_s(rs2);
- return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
+ return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float32_minnum(frs1, frs2, &env->fp_status) :
+ float32_minimum_number(frs1, frs2, &env->fp_status));
}
uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
{
float32 frs1 = check_nanbox_s(rs1);
float32 frs2 = check_nanbox_s(rs2);
- return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
+ return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float32_maxnum(frs1, frs2, &env->fp_status) :
+ float32_maximum_number(frs1, frs2, &env->fp_status));
}
uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
@@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
{
- return float64_minnum(frs1, frs2, &env->fp_status);
+ return env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float64_minnum(frs1, frs2, &env->fp_status) :
+ float64_minimum_number(frs1, frs2, &env->fp_status);
}
uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
{
- return float64_maxnum(frs1, frs2, &env->fp_status);
+ return env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float64_maxnum(frs1, frs2, &env->fp_status) :
+ float64_maximum_number(frs1, frs2, &env->fp_status);
}
uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
@ 2021-10-16 8:54 ` frank.chang
0 siblings, 0 replies; 10+ messages in thread
From: frank.chang @ 2021-10-16 8:54 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Chih-Min Chao, Frank Chang, Palmer Dabbelt, Alistair Francis, Bin Meng
From: Chih-Min Chao <chihmin.chao@sifive.com>
The sNaN propagation behavior has been changed since
cd20cee7 in https://github.com/riscv/riscv-isa-manual.
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
target/riscv/fpu_helper.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 8700516a14c..d62f4709002 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
{
float32 frs1 = check_nanbox_s(rs1);
float32 frs2 = check_nanbox_s(rs2);
- return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
+ return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float32_minnum(frs1, frs2, &env->fp_status) :
+ float32_minimum_number(frs1, frs2, &env->fp_status));
}
uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
{
float32 frs1 = check_nanbox_s(rs1);
float32 frs2 = check_nanbox_s(rs2);
- return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
+ return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float32_maxnum(frs1, frs2, &env->fp_status) :
+ float32_maximum_number(frs1, frs2, &env->fp_status));
}
uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
@@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
{
- return float64_minnum(frs1, frs2, &env->fp_status);
+ return env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float64_minnum(frs1, frs2, &env->fp_status) :
+ float64_minimum_number(frs1, frs2, &env->fp_status);
}
uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
{
- return float64_maxnum(frs1, frs2, &env->fp_status);
+ return env->priv_ver < PRIV_VERSION_1_11_0 ?
+ float64_maxnum(frs1, frs2, &env->fp_status) :
+ float64_maximum_number(frs1, frs2, &env->fp_status);
}
uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] softfloat: add APIs to handle alternative sNaN propagation for fmax/fmin
2021-10-16 8:54 ` frank.chang
(?)
@ 2021-10-16 17:59 ` Richard Henderson
-1 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-10-16 17:59 UTC (permalink / raw)
To: frank.chang, qemu-devel, qemu-riscv
Cc: Chih-Min Chao, Alex Bennée, Aurelien Jarno, Peter Maydell
On 10/16/21 1:54 AM, frank.chang@sifive.com wrote:
> From: Chih-Min Chao<chihmin.chao@sifive.com>
>
> For "fmax/fmin ft0, ft1, ft2" and if one of the inputs is sNaN,
>
> The original logic:
> Return NaN and set invalid flag if ft1 == sNaN || ft2 == sNan.
>
> The alternative path:
> Set invalid flag if ft1 == sNaN || ft2 == sNaN.
> Return NaN only if ft1 == NaN && ft2 == NaN.
>
> The IEEE 754 spec allows both implementation and some architecture such
> as riscv choose different defintions in two spec versions.
> (riscv-spec-v2.2 use original version, riscv-spec-20191213 changes to
> alternative)
>
> Signed-off-by: Chih-Min Chao<chihmin.chao@sifive.com>
> Signed-off-by: Frank Chang<frank.chang@sifive.com>
> ---
> fpu/softfloat-parts.c.inc | 25 +++++++++++++++++++++++--
> fpu/softfloat.c | 19 +++++++++++++------
> include/fpu/softfloat.h | 10 ++++++++++
> 3 files changed, 46 insertions(+), 8 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
2021-10-16 8:54 ` frank.chang
@ 2021-10-20 2:56 ` Frank Chang
-1 siblings, 0 replies; 10+ messages in thread
From: Frank Chang @ 2021-10-20 2:56 UTC (permalink / raw)
To: qemu-devel@nongnu.org Developers, open list:RISC-V
Cc: Chih-Min Chao, Alistair Francis, Bin Meng, Palmer Dabbelt
[-- Attachment #1: Type: text/plain, Size: 2740 bytes --]
On Sat, Oct 16, 2021 at 4:54 PM <frank.chang@sifive.com> wrote:
> From: Chih-Min Chao <chihmin.chao@sifive.com>
>
> The sNaN propagation behavior has been changed since
> cd20cee7 in https://github.com/riscv/riscv-isa-manual.
>
> Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
> ---
> target/riscv/fpu_helper.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 8700516a14c..d62f4709002 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t
> rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_minnum(frs1, frs2, &env->fp_status) :
> + float32_minimum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_maxnum(frs1, frs2, &env->fp_status) :
> + float32_maximum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
> @@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t
> frs1, uint64_t frs2)
>
> uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_minnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_minnum(frs1, frs2, &env->fp_status) :
> + float64_minimum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_maxnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_maxnum(frs1, frs2, &env->fp_status) :
> + float64_maximum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
> --
> 2.25.1
>
>
If we have decided to tie RVF with Privilege spec version for now as
discussed in:
https://patchew.org/QEMU/20211015065500.3850513-1-frank.chang@sifive.com/20211015065500.3850513-3-frank.chang@sifive.com/
then I think this patch doesn't require any further changes, right?
Regards,
Frank Chang
[-- Attachment #2: Type: text/html, Size: 3905 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
@ 2021-10-20 2:56 ` Frank Chang
0 siblings, 0 replies; 10+ messages in thread
From: Frank Chang @ 2021-10-20 2:56 UTC (permalink / raw)
To: qemu-devel@nongnu.org Developers, open list:RISC-V
Cc: Chih-Min Chao, Palmer Dabbelt, Alistair Francis, Bin Meng
[-- Attachment #1: Type: text/plain, Size: 2740 bytes --]
On Sat, Oct 16, 2021 at 4:54 PM <frank.chang@sifive.com> wrote:
> From: Chih-Min Chao <chihmin.chao@sifive.com>
>
> The sNaN propagation behavior has been changed since
> cd20cee7 in https://github.com/riscv/riscv-isa-manual.
>
> Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
> ---
> target/riscv/fpu_helper.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 8700516a14c..d62f4709002 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t
> rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_minnum(frs1, frs2, &env->fp_status) :
> + float32_minimum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_maxnum(frs1, frs2, &env->fp_status) :
> + float32_maximum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
> @@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t
> frs1, uint64_t frs2)
>
> uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_minnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_minnum(frs1, frs2, &env->fp_status) :
> + float64_minimum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_maxnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_maxnum(frs1, frs2, &env->fp_status) :
> + float64_maximum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
> --
> 2.25.1
>
>
If we have decided to tie RVF with Privilege spec version for now as
discussed in:
https://patchew.org/QEMU/20211015065500.3850513-1-frank.chang@sifive.com/20211015065500.3850513-3-frank.chang@sifive.com/
then I think this patch doesn't require any further changes, right?
Regards,
Frank Chang
[-- Attachment #2: Type: text/html, Size: 3905 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
2021-10-16 8:54 ` frank.chang
@ 2021-10-20 23:24 ` Alistair Francis
-1 siblings, 0 replies; 10+ messages in thread
From: Alistair Francis @ 2021-10-20 23:24 UTC (permalink / raw)
To: Frank Chang
Cc: open list:RISC-V, Bin Meng, qemu-devel@nongnu.org Developers,
Chih-Min Chao, Alistair Francis, Palmer Dabbelt
On Sat, Oct 16, 2021 at 6:55 PM <frank.chang@sifive.com> wrote:
>
> From: Chih-Min Chao <chihmin.chao@sifive.com>
>
> The sNaN propagation behavior has been changed since
> cd20cee7 in https://github.com/riscv/riscv-isa-manual.
It would be a good idea to justify why we are using the priv spec for
the version check.
>
> Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/fpu_helper.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 8700516a14c..d62f4709002 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_minnum(frs1, frs2, &env->fp_status) :
> + float32_minimum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_maxnum(frs1, frs2, &env->fp_status) :
> + float32_maximum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
> @@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
>
> uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_minnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_minnum(frs1, frs2, &env->fp_status) :
> + float64_minimum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_maxnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_maxnum(frs1, frs2, &env->fp_status) :
> + float64_maximum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax
@ 2021-10-20 23:24 ` Alistair Francis
0 siblings, 0 replies; 10+ messages in thread
From: Alistair Francis @ 2021-10-20 23:24 UTC (permalink / raw)
To: Frank Chang
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Chih-Min Chao, Alistair Francis, Bin Meng, Palmer Dabbelt
On Sat, Oct 16, 2021 at 6:55 PM <frank.chang@sifive.com> wrote:
>
> From: Chih-Min Chao <chihmin.chao@sifive.com>
>
> The sNaN propagation behavior has been changed since
> cd20cee7 in https://github.com/riscv/riscv-isa-manual.
It would be a good idea to justify why we are using the priv spec for
the version check.
>
> Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/fpu_helper.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 8700516a14c..d62f4709002 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -174,14 +174,18 @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_minnum(frs1, frs2, &env->fp_status) :
> + float32_minimum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> {
> float32 frs1 = check_nanbox_s(rs1);
> float32 frs2 = check_nanbox_s(rs2);
> - return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
> + return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float32_maxnum(frs1, frs2, &env->fp_status) :
> + float32_maximum_number(frs1, frs2, &env->fp_status));
> }
>
> uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
> @@ -283,12 +287,16 @@ uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
>
> uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_minnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_minnum(frs1, frs2, &env->fp_status) :
> + float64_minimum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> {
> - return float64_maxnum(frs1, frs2, &env->fp_status);
> + return env->priv_ver < PRIV_VERSION_1_11_0 ?
> + float64_maxnum(frs1, frs2, &env->fp_status) :
> + float64_maximum_number(frs1, frs2, &env->fp_status);
> }
>
> uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-10-20 23:28 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-16 8:54 [PATCH v4 0/2] add APIs to handle alternative sNaN propagation for fmax/fmin frank.chang
2021-10-16 8:54 ` [PATCH v4 1/2] softfloat: " frank.chang
2021-10-16 8:54 ` frank.chang
2021-10-16 17:59 ` Richard Henderson
2021-10-16 8:54 ` [PATCH v4 2/2] target/riscv: change the api for RVF/RVD fmin/fmax frank.chang
2021-10-16 8:54 ` frank.chang
2021-10-20 2:56 ` Frank Chang
2021-10-20 2:56 ` Frank Chang
2021-10-20 23:24 ` Alistair Francis
2021-10-20 23:24 ` Alistair Francis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.