diff mbox series

[v5,39/60] target/riscv: vector floating-point classify instructions

Message ID 20200312145900.2054-40-zhiwei_liu@c-sky.com
State New
Headers show
Series target/riscv: support vector extension v0.7.1 | expand

Commit Message

LIU Zhiwei March 12, 2020, 2:58 p.m. UTC
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/helper.h                   |  4 ++
 target/riscv/insn32.decode              |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c |  3 ++
 target/riscv/vector_helper.c            | 62 +++++++++++++++++++++++++
 4 files changed, 70 insertions(+)

Comments

Richard Henderson March 14, 2020, 9:10 a.m. UTC | #1
On 3/12/20 7:58 AM, LIU Zhiwei wrote:
> +/* Vector Floating-Point Classify Instruction */
> +static uint16_t fclass_f16(uint16_t frs1, float_status *s)
> +{
> +    float16 f = frs1;
> +    bool sign = float16_is_neg(f);
> +
> +    if (float16_is_infinity(f)) {
> +        return sign ? 1 << 0 : 1 << 7;
> +    } else if (float16_is_zero(f)) {
> +        return sign ? 1 << 3 : 1 << 4;
> +    } else if (float16_is_zero_or_denormal(f)) {
> +        return sign ? 1 << 2 : 1 << 5;
> +    } else if (float16_is_any_nan(f)) {
> +        float_status s = { }; /* for snan_bit_is_one */
> +        return float16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
> +    } else {
> +        return sign ? 1 << 1 : 1 << 6;
> +    }
> +}
> +static uint32_t fclass_s(uint32_t frs1, float_status *s)
> +{
> +    float32 f = frs1;
> +    bool sign = float32_is_neg(f);
> +
> +    if (float32_is_infinity(f)) {
> +        return sign ? 1 << 0 : 1 << 7;
> +    } else if (float32_is_zero(f)) {
> +        return sign ? 1 << 3 : 1 << 4;
> +    } else if (float32_is_zero_or_denormal(f)) {
> +        return sign ? 1 << 2 : 1 << 5;
> +    } else if (float32_is_any_nan(f)) {
> +        float_status s = { }; /* for snan_bit_is_one */
> +        return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
> +    } else {
> +        return sign ? 1 << 1 : 1 << 6;
> +    }
> +}
> +static uint64_t fclass_d(uint64_t frs1, float_status *s)
> +{
> +    float64 f = frs1;
> +    bool sign = float64_is_neg(f);
> +
> +    if (float64_is_infinity(f)) {
> +        return sign ? 1 << 0 : 1 << 7;
> +    } else if (float64_is_zero(f)) {
> +        return sign ? 1 << 3 : 1 << 4;
> +    } else if (float64_is_zero_or_denormal(f)) {
> +        return sign ? 1 << 2 : 1 << 5;
> +    } else if (float64_is_any_nan(f)) {
> +        float_status s = { }; /* for snan_bit_is_one */
> +        return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
> +    } else {
> +        return sign ? 1 << 1 : 1 << 6;
> +    }
> +}

These need to be moved out of fpu_helper.c so they can be shared.

r~
LIU Zhiwei March 14, 2020, 9:15 a.m. UTC | #2
On 2020/3/14 17:10, Richard Henderson wrote:
> On 3/12/20 7:58 AM, LIU Zhiwei wrote:
>> +/* Vector Floating-Point Classify Instruction */
>> +static uint16_t fclass_f16(uint16_t frs1, float_status *s)
>> +{
>> +    float16 f = frs1;
>> +    bool sign = float16_is_neg(f);
>> +
>> +    if (float16_is_infinity(f)) {
>> +        return sign ? 1 << 0 : 1 << 7;
>> +    } else if (float16_is_zero(f)) {
>> +        return sign ? 1 << 3 : 1 << 4;
>> +    } else if (float16_is_zero_or_denormal(f)) {
>> +        return sign ? 1 << 2 : 1 << 5;
>> +    } else if (float16_is_any_nan(f)) {
>> +        float_status s = { }; /* for snan_bit_is_one */
>> +        return float16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
>> +    } else {
>> +        return sign ? 1 << 1 : 1 << 6;
>> +    }
>> +}
>> +static uint32_t fclass_s(uint32_t frs1, float_status *s)
>> +{
>> +    float32 f = frs1;
>> +    bool sign = float32_is_neg(f);
>> +
>> +    if (float32_is_infinity(f)) {
>> +        return sign ? 1 << 0 : 1 << 7;
>> +    } else if (float32_is_zero(f)) {
>> +        return sign ? 1 << 3 : 1 << 4;
>> +    } else if (float32_is_zero_or_denormal(f)) {
>> +        return sign ? 1 << 2 : 1 << 5;
>> +    } else if (float32_is_any_nan(f)) {
>> +        float_status s = { }; /* for snan_bit_is_one */
>> +        return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
>> +    } else {
>> +        return sign ? 1 << 1 : 1 << 6;
>> +    }
>> +}
>> +static uint64_t fclass_d(uint64_t frs1, float_status *s)
>> +{
>> +    float64 f = frs1;
>> +    bool sign = float64_is_neg(f);
>> +
>> +    if (float64_is_infinity(f)) {
>> +        return sign ? 1 << 0 : 1 << 7;
>> +    } else if (float64_is_zero(f)) {
>> +        return sign ? 1 << 3 : 1 << 4;
>> +    } else if (float64_is_zero_or_denormal(f)) {
>> +        return sign ? 1 << 2 : 1 << 5;
>> +    } else if (float64_is_any_nan(f)) {
>> +        float_status s = { }; /* for snan_bit_is_one */
>> +        return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
>> +    } else {
>> +        return sign ? 1 << 1 : 1 << 6;
>> +    }
>> +}
> These need to be moved out of fpu_helper.c so they can be shared.
I will add an internals.h and move the declaration to internals.h.

Zhiwei

>
> r~
Richard Henderson March 14, 2020, 10:06 p.m. UTC | #3
On 3/14/20 2:15 AM, LIU Zhiwei wrote:
>>> +static uint64_t fclass_d(uint64_t frs1, float_status *s)
>>> +{
>>> +    float64 f = frs1;
>>> +    bool sign = float64_is_neg(f);
>>> +
>>> +    if (float64_is_infinity(f)) {
>>> +        return sign ? 1 << 0 : 1 << 7;
>>> +    } else if (float64_is_zero(f)) {
>>> +        return sign ? 1 << 3 : 1 << 4;
>>> +    } else if (float64_is_zero_or_denormal(f)) {
>>> +        return sign ? 1 << 2 : 1 << 5;
>>> +    } else if (float64_is_any_nan(f)) {
>>> +        float_status s = { }; /* for snan_bit_is_one */
>>> +        return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
>>> +    } else {
>>> +        return sign ? 1 << 1 : 1 << 6;
>>> +    }
>>> +}
>> These need to be moved out of fpu_helper.c so they can be shared.
> I will add an internals.h and move the declaration to internals.h.

Actually, let's just put declarations for them in internals.h and remove the
static.  They are large enough that they don't need to be inlined.


r~
diff mbox series

Patch

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 323bed038e..86f1498c06 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -978,3 +978,7 @@  DEF_HELPER_6(vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 2d61256981..18b78ed82d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -507,6 +507,7 @@  vmfgt_vf        011101 . ..... ..... 101 ..... 1010111 @r_vm
 vmfge_vf        011111 . ..... ..... 101 ..... 1010111 @r_vm
 vmford_vv       011010 . ..... ..... 001 ..... 1010111 @r_vm
 vmford_vf       011010 . ..... ..... 101 ..... 1010111 @r_vm
+vfclass_v       100011 . ..... 10000 001 ..... 1010111 @r2_vm
 
 vsetvli         0 ........... ..... 111 ..... 1010111  @r2_zimm
 vsetvl          1000000 ..... ..... 111 ..... 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
index 9d9653e605..3971c3ebdb 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -1918,3 +1918,6 @@  GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check)
+
+/* Vector Floating-Point Classify Instruction */
+GEN_OPFV_TRANS(vfclass_v, opfv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index dd44cc57a3..e9f278643f 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3852,3 +3852,65 @@  GEN_VEXT_CMP_VV_ENV(vmford_vv_d, uint64_t, H8, !float64_unordered_quiet)
 GEN_VEXT_CMP_VF(vmford_vf_h, uint16_t, H2, !float16_unordered_quiet)
 GEN_VEXT_CMP_VF(vmford_vf_w, uint32_t, H4, !float32_unordered_quiet)
 GEN_VEXT_CMP_VF(vmford_vf_d, uint64_t, H8, !float64_unordered_quiet)
+
+/* Vector Floating-Point Classify Instruction */
+static uint16_t fclass_f16(uint16_t frs1, float_status *s)
+{
+    float16 f = frs1;
+    bool sign = float16_is_neg(f);
+
+    if (float16_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (float16_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (float16_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (float16_is_any_nan(f)) {
+        float_status s = { }; /* for snan_bit_is_one */
+        return float16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
+static uint32_t fclass_s(uint32_t frs1, float_status *s)
+{
+    float32 f = frs1;
+    bool sign = float32_is_neg(f);
+
+    if (float32_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (float32_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (float32_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (float32_is_any_nan(f)) {
+        float_status s = { }; /* for snan_bit_is_one */
+        return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
+static uint64_t fclass_d(uint64_t frs1, float_status *s)
+{
+    float64 f = frs1;
+    bool sign = float64_is_neg(f);
+
+    if (float64_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (float64_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (float64_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (float64_is_any_nan(f)) {
+        float_status s = { }; /* for snan_bit_is_one */
+        return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
+RVVCALL(OPFVV1, vfclass_v_h, OP_UU_H, H2, H2, fclass_f16)
+RVVCALL(OPFVV1, vfclass_v_w, OP_UU_W, H4, H4, fclass_s)
+RVVCALL(OPFVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
+GEN_VEXT_V_ENV(vfclass_v_h, 2, 2, clearh)
+GEN_VEXT_V_ENV(vfclass_v_w, 4, 4, clearl)
+GEN_VEXT_V_ENV(vfclass_v_d, 8, 8, clearq)