[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 33/47] target/arm: Implement fp16 for Neon VRSQRTS
From: |
Peter Maydell |
Subject: |
[PULL 33/47] target/arm: Implement fp16 for Neon VRSQRTS |
Date: |
Tue, 1 Sep 2020 16:18:09 +0100 |
Convert the Neon VRSQRTS insn to using a gvec helper,
and use this to implement the fp16 case.
As with VRECPS, we adjust the phrasing of the new implementation
slightly so that the fp32 version parallels the fp16 one.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200828183354.27913-35-peter.maydell@linaro.org
---
target/arm/helper.h | 4 +++-
target/arm/vec_helper.c | 30 ++++++++++++++++++++++++++++++
target/arm/vfp_helper.c | 15 ---------------
target/arm/translate-neon.c.inc | 21 +--------------------
4 files changed, 34 insertions(+), 36 deletions(-)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 114039c4c33..5a716498913 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -225,7 +225,6 @@ DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
DEF_HELPER_4(vfp_muladdh, f16, f16, f16, f16, ptr)
-DEF_HELPER_3(rsqrts_f32, f32, env, f32, f32)
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
@@ -676,6 +675,9 @@ DEF_HELPER_FLAGS_5(gvec_fminnum_s, TCG_CALL_NO_RWG, void,
ptr, ptr, ptr, ptr, i3
DEF_HELPER_FLAGS_5(gvec_recps_nf_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr,
i32)
DEF_HELPER_FLAGS_5(gvec_recps_nf_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr,
i32)
+DEF_HELPER_FLAGS_5(gvec_rsqrts_nf_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr,
ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_rsqrts_nf_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr,
ptr, i32)
+
DEF_HELPER_FLAGS_5(gvec_fmla_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmla_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
index 0111a230244..e5bb5e395cb 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/vec_helper.c
@@ -825,6 +825,33 @@ static float32 float32_recps_nf(float32 op1, float32 op2,
float_status *stat)
return float32_sub(float32_two, float32_mul(op1, op2, stat), stat);
}
+/* Reciprocal square-root step. AArch32 non-fused semantics. */
+static float16 float16_rsqrts_nf(float16 op1, float16 op2, float_status *stat)
+{
+ op1 = float16_squash_input_denormal(op1, stat);
+ op2 = float16_squash_input_denormal(op2, stat);
+
+ if ((float16_is_infinity(op1) && float16_is_zero(op2)) ||
+ (float16_is_infinity(op2) && float16_is_zero(op1))) {
+ return float16_one_point_five;
+ }
+ op1 = float16_sub(float16_three, float16_mul(op1, op2, stat), stat);
+ return float16_div(op1, float16_two, stat);
+}
+
+static float32 float32_rsqrts_nf(float32 op1, float32 op2, float_status *stat)
+{
+ op1 = float32_squash_input_denormal(op1, stat);
+ op2 = float32_squash_input_denormal(op2, stat);
+
+ if ((float32_is_infinity(op1) && float32_is_zero(op2)) ||
+ (float32_is_infinity(op2) && float32_is_zero(op1))) {
+ return float32_one_point_five;
+ }
+ op1 = float32_sub(float32_three, float32_mul(op1, op2, stat), stat);
+ return float32_div(op1, float32_two, stat);
+}
+
#define DO_3OP(NAME, FUNC, TYPE) \
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
{ \
@@ -885,6 +912,9 @@ DO_3OP(gvec_fminnum_s, float32_minnum, float32)
DO_3OP(gvec_recps_nf_h, float16_recps_nf, float16)
DO_3OP(gvec_recps_nf_s, float32_recps_nf, float32)
+DO_3OP(gvec_rsqrts_nf_h, float16_rsqrts_nf, float16)
+DO_3OP(gvec_rsqrts_nf_s, float32_rsqrts_nf, float32)
+
#ifdef TARGET_AARCH64
DO_3OP(gvec_recps_h, helper_recpsf_f16, float16)
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 1f452409d4d..8a3dd176819 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -529,21 +529,6 @@ uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void
*fpstp, uint32_t ahp_mode)
return r;
}
-float32 HELPER(rsqrts_f32)(CPUARMState *env, float32 a, float32 b)
-{
- float_status *s = &env->vfp.standard_fp_status;
- float32 product;
- if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
- (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
- if (!(float32_is_zero(a) || float32_is_zero(b))) {
- float_raise(float_flag_input_denormal, s);
- }
- return float32_one_point_five;
- }
- product = float32_mul(a, b, s);
- return float32_div(float32_sub(float32_three, product, s), float32_two, s);
-}
-
/* NEON helpers. */
/* Constants 256 and 512 are used in some helpers; we avoid relying on
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
index 63e7be8e01d..4c6d63be3d3 100644
--- a/target/arm/translate-neon.c.inc
+++ b/target/arm/translate-neon.c.inc
@@ -1075,6 +1075,7 @@ DO_3S_FP_GVEC(VMLS, gen_helper_gvec_fmls_s,
gen_helper_gvec_fmls_h)
DO_3S_FP_GVEC(VFMA, gen_helper_gvec_vfma_s, gen_helper_gvec_vfma_h)
DO_3S_FP_GVEC(VFMS, gen_helper_gvec_vfms_s, gen_helper_gvec_vfms_h)
DO_3S_FP_GVEC(VRECPS, gen_helper_gvec_recps_nf_s, gen_helper_gvec_recps_nf_h)
+DO_3S_FP_GVEC(VRSQRTS, gen_helper_gvec_rsqrts_nf_s,
gen_helper_gvec_rsqrts_nf_h)
WRAP_FP_GVEC(gen_VMAXNM_fp32_3s, FPST_STD, gen_helper_gvec_fmaxnum_s)
WRAP_FP_GVEC(gen_VMAXNM_fp16_3s, FPST_STD_F16, gen_helper_gvec_fmaxnum_h)
@@ -1111,26 +1112,6 @@ static bool trans_VMINNM_fp_3s(DisasContext *s,
arg_3same *a)
return do_3same(s, a, gen_VMINNM_fp32_3s);
}
-WRAP_ENV_FN(gen_VRSQRTS_tramp, gen_helper_rsqrts_f32)
-
-static void gen_VRSQRTS_fp_3s(unsigned vece, uint32_t rd_ofs,
- uint32_t rn_ofs, uint32_t rm_ofs,
- uint32_t oprsz, uint32_t maxsz)
-{
- static const GVecGen3 ops = { .fni4 = gen_VRSQRTS_tramp };
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops);
-}
-
-static bool trans_VRSQRTS_fp_3s(DisasContext *s, arg_3same *a)
-{
- if (a->size != 0) {
- /* TODO fp16 support */
- return false;
- }
-
- return do_3same(s, a, gen_VRSQRTS_fp_3s);
-}
-
static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
{
/* FP operations handled pairwise 32 bits at a time */
--
2.20.1
- [PULL 18/47] target/arm: Implement VFP fp16 VRINT*, (continued)
- [PULL 18/47] target/arm: Implement VFP fp16 VRINT*, Peter Maydell, 2020/09/01
- [PULL 23/47] target/arm: Implement fp16 for Neon VRECPE, VRSQRTE using gvec, Peter Maydell, 2020/09/01
- [PULL 24/47] target/arm: Implement fp16 for Neon VABS, VNEG of floats, Peter Maydell, 2020/09/01
- [PULL 25/47] target/arm: Implement fp16 for VCEQ, VCGE, VCGT comparisons, Peter Maydell, 2020/09/01
- [PULL 27/47] target/arm: Implement fp16 for Neon VMAX, VMIN, Peter Maydell, 2020/09/01
- [PULL 28/47] target/arm: Implement fp16 for Neon VMAXNM, VMINNM, Peter Maydell, 2020/09/01
- [PULL 29/47] target/arm: Implement fp16 for Neon VMLA, VMLS operations, Peter Maydell, 2020/09/01
- [PULL 30/47] target/arm: Implement fp16 for Neon VFMA, VMFS, Peter Maydell, 2020/09/01
- [PULL 26/47] target/arm: Implement fp16 for VACGE, VACGT, Peter Maydell, 2020/09/01
- [PULL 31/47] target/arm: Implement fp16 for Neon fp compare-vs-0, Peter Maydell, 2020/09/01
- [PULL 33/47] target/arm: Implement fp16 for Neon VRSQRTS,
Peter Maydell <=
- [PULL 34/47] target/arm: Implement fp16 for Neon pairwise fp ops, Peter Maydell, 2020/09/01
- [PULL 35/47] target/arm: Implement fp16 for Neon float-integer VCVT, Peter Maydell, 2020/09/01
- [PULL 32/47] target/arm: Implement fp16 for Neon VRECPS, Peter Maydell, 2020/09/01
- [PULL 36/47] target/arm: Convert Neon VCVT fixed-point to gvec, Peter Maydell, 2020/09/01
- [PULL 37/47] target/arm: Implement fp16 for Neon VCVT fixed-point, Peter Maydell, 2020/09/01
- [PULL 39/47] target/arm: Implement fp16 for Neon VRINT-with-specified-rounding-mode, Peter Maydell, 2020/09/01
- [PULL 40/47] target/arm: Implement fp16 for Neon VRINTX, Peter Maydell, 2020/09/01
- [PULL 38/47] target/arm: Implement fp16 for Neon VCVT with rounding modes, Peter Maydell, 2020/09/01
- [PULL 41/47] target/arm/vec_helper: Handle oprsz less than 16 bytes in indexed operations, Peter Maydell, 2020/09/01
- [PULL 42/47] target/arm/vec_helper: Add gvec fp indexed multiply-and-add operations, Peter Maydell, 2020/09/01