From 21dd7ed0aba0d58fb81f93b1063f54b42cc9b4f4 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Mon, 11 May 2020 23:35:38 -0700 Subject: [PATCH] rvv: handle inactive and NaN case for vfredsum Signed-off-by: Chih-Min Chao --- riscv/decode.h | 53 +++++++++++++++++++++++++++++++++++-- riscv/insns/vfredmax_vs.h | 1 + riscv/insns/vfredmin_vs.h | 1 + riscv/insns/vfredosum_vs.h | 1 + riscv/insns/vfredsum_vs.h | 1 + riscv/insns/vfwredosum_vs.h | 1 + riscv/insns/vfwredsum_vs.h | 1 + 7 files changed, 57 insertions(+), 2 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index c3feec3e..7790fa43 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -1691,11 +1691,13 @@ for (reg_t i = 0; i < vlmax && P.VU.vl != 0; ++i) { \ #define VI_VFP_LOOP_REDUCTION_BASE(width) \ float##width##_t vd_0 = P.VU.elt(rd_num, 0); \ float##width##_t vs1_0 = P.VU.elt(rs1_num, 0); \ - vd_0 = vs1_0;\ + vd_0 = vs1_0; \ + bool is_active = false; \ for (reg_t i=P.VU.vstart; i(rd_num, i, true); \ float##width##_t vs2 = P.VU.elt(rs2_num, i); \ + is_active = true; \ #define VI_VFP_LOOP_WIDE_REDUCTION_BASE \ VI_VFP_COMMON \ @@ -1711,7 +1713,51 @@ for (reg_t i = 0; i < vlmax && P.VU.vl != 0; ++i) { \ } \ P.VU.vstart = 0; \ if (vl > 0) { \ - P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + if (is_propagate && !is_active) { \ + switch (x) { \ + case e16: {\ + auto ret = f16_classify(f16(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt::type>(rd_num, 0, true) = defaultNaNF16UI; \ + } else { \ + P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + case e32: { \ + auto ret = f32_classify(f32(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt::type>(rd_num, 0, true) = defaultNaNF32UI; \ + } else { \ + P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + case e64: {\ + auto ret = f64_classify(f64(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt::type>(rd_num, 0, true) = defaultNaNF64UI; \ + } else { \ + P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + } \ + } else { \ + P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + } \ } #define VI_VFP_LOOP_CMP_END \ @@ -1799,11 +1845,13 @@ for (reg_t i = 0; i < vlmax && P.VU.vl != 0; ++i) { \ VI_VFP_COMMON \ require((P.VU.vsew == e16 && p->supports_extension('F')) || \ (P.VU.vsew == e32 && p->supports_extension('D'))); \ + bool is_active = false; \ switch(P.VU.vsew) { \ case e16: {\ float32_t vd_0 = P.VU.elt(rs1_num, 0); \ for (reg_t i=P.VU.vstart; i(rs2_num, i)); \ BODY16; \ set_fp_exceptions; \ @@ -1814,6 +1862,7 @@ for (reg_t i = 0; i < vlmax && P.VU.vl != 0; ++i) { \ float64_t vd_0 = P.VU.elt(rs1_num, 0); \ for (reg_t i=P.VU.vstart; i(rs2_num, i)); \ BODY32; \ set_fp_exceptions; \ diff --git a/riscv/insns/vfredmax_vs.h b/riscv/insns/vfredmax_vs.h index 1ab856b0..f19ec597 100644 --- a/riscv/insns/vfredmax_vs.h +++ b/riscv/insns/vfredmax_vs.h @@ -1,4 +1,5 @@ // vfredmax vd, vs2, vs1 +bool is_propagate = false; VI_VFP_VV_LOOP_REDUCTION ({ vd_0 = f16_max(vd_0, vs2); diff --git a/riscv/insns/vfredmin_vs.h b/riscv/insns/vfredmin_vs.h index 37256cbc..e3cf1513 100644 --- a/riscv/insns/vfredmin_vs.h +++ b/riscv/insns/vfredmin_vs.h @@ -1,4 +1,5 @@ // vfredmin vd, vs2, vs1 +bool is_propagate = false; VI_VFP_VV_LOOP_REDUCTION ({ vd_0 = f16_min(vd_0, vs2); diff --git a/riscv/insns/vfredosum_vs.h b/riscv/insns/vfredosum_vs.h index 4564f9c6..2438a7ba 100644 --- a/riscv/insns/vfredosum_vs.h +++ b/riscv/insns/vfredosum_vs.h @@ -1,4 +1,5 @@ // vfredosum: vd[0] = sum( vs2[*] , vs1[0] ) +bool is_propagate = false; VI_VFP_VV_LOOP_REDUCTION ({ vd_0 = f16_add(vd_0, vs2); diff --git a/riscv/insns/vfredsum_vs.h b/riscv/insns/vfredsum_vs.h index d18b63ed..bad7308e 100644 --- a/riscv/insns/vfredsum_vs.h +++ b/riscv/insns/vfredsum_vs.h @@ -1,4 +1,5 @@ // vfredsum: vd[0] = sum( vs2[*] , vs1[0] ) +bool is_propagate = true; VI_VFP_VV_LOOP_REDUCTION ({ vd_0 = f16_add(vd_0, vs2); diff --git a/riscv/insns/vfwredosum_vs.h b/riscv/insns/vfwredosum_vs.h index 22fb4dfb..1f42d8ff 100644 --- a/riscv/insns/vfwredosum_vs.h +++ b/riscv/insns/vfwredosum_vs.h @@ -1,4 +1,5 @@ // vfwredosum.vs vd, vs2, vs1 +bool is_propagate = false; VI_VFP_VV_LOOP_WIDE_REDUCTION ({ vd_0 = f32_add(vd_0, vs2); diff --git a/riscv/insns/vfwredsum_vs.h b/riscv/insns/vfwredsum_vs.h index 277cf417..4ef28969 100644 --- a/riscv/insns/vfwredsum_vs.h +++ b/riscv/insns/vfwredsum_vs.h @@ -1,4 +1,5 @@ // vfwredsum.vs vd, vs2, vs1 +bool is_propagate = true; VI_VFP_VV_LOOP_WIDE_REDUCTION ({ vd_0 = f32_add(vd_0, vs2);