Skip to content

Commit

Permalink
arm/translate-a64: add FP16 FR[ECP/SQRT]S to simd_three_reg_same_fp16
Browse files Browse the repository at this point in the history
As some of the constants here will also be needed
elsewhere (specifically for the upcoming SVE support) we move them out
to softfloat.h.

Signed-off-by: Alex Bennée <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Message-id: [email protected]
Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
stsquad authored and pm215 committed Mar 1, 2018
1 parent 2deb992 commit 026e2d6
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
16 changes: 12 additions & 4 deletions include/fpu/softfloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,11 @@ static inline float16 float16_set_sign(float16 a, int sign)
}

#define float16_zero make_float16(0)
#define float16_one make_float16(0x3c00)
#define float16_half make_float16(0x3800)
#define float16_one make_float16(0x3c00)
#define float16_one_point_five make_float16(0x3e00)
#define float16_two make_float16(0x4000)
#define float16_three make_float16(0x4200)
#define float16_infinity make_float16(0x7c00)

/*----------------------------------------------------------------------------
Expand Down Expand Up @@ -415,11 +418,13 @@ static inline float32 float32_set_sign(float32 a, int sign)
}

#define float32_zero make_float32(0)
#define float32_one make_float32(0x3f800000)
#define float32_half make_float32(0x3f000000)
#define float32_one make_float32(0x3f800000)
#define float32_one_point_five make_float32(0x3fc00000)
#define float32_two make_float32(0x40000000)
#define float32_three make_float32(0x40400000)
#define float32_infinity make_float32(0x7f800000)


/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -526,9 +531,12 @@ static inline float64 float64_set_sign(float64 a, int sign)
}

#define float64_zero make_float64(0)
#define float64_half make_float64(0x3fe0000000000000LL)
#define float64_one make_float64(0x3ff0000000000000LL)
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
#define float64_two make_float64(0x4000000000000000ULL)
#define float64_three make_float64(0x4008000000000000ULL)
#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
#define float64_half make_float64(0x3fe0000000000000LL)
#define float64_infinity make_float64(0x7ff0000000000000LL)

/*----------------------------------------------------------------------------
Expand Down
34 changes: 34 additions & 0 deletions target/arm/helper-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
* versions, these do a fully fused multiply-add or
* multiply-add-and-halve.
*/
#define float16_two make_float16(0x4000)
#define float16_three make_float16(0x4200)
#define float16_one_point_five make_float16(0x3e00)

#define float32_two make_float32(0x40000000)
#define float32_three make_float32(0x40400000)
#define float32_one_point_five make_float32(0x3fc00000)
Expand All @@ -200,6 +204,21 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
#define float64_three make_float64(0x4008000000000000ULL)
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)

float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
{
float_status *fpst = fpstp;

a = float16_squash_input_denormal(a, fpst);
b = float16_squash_input_denormal(b, fpst);

a = float16_chs(a);
if ((float16_is_infinity(a) && float16_is_zero(b)) ||
(float16_is_infinity(b) && float16_is_zero(a))) {
return float16_two;
}
return float16_muladd(a, b, float16_two, 0, fpst);
}

float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp)
{
float_status *fpst = fpstp;
Expand Down Expand Up @@ -230,6 +249,21 @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
return float64_muladd(a, b, float64_two, 0, fpst);
}

float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
{
float_status *fpst = fpstp;

a = float16_squash_input_denormal(a, fpst);
b = float16_squash_input_denormal(b, fpst);

a = float16_chs(a);
if ((float16_is_infinity(a) && float16_is_zero(b)) ||
(float16_is_infinity(b) && float16_is_zero(a))) {
return float16_one_point_five;
}
return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
}

float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp)
{
float_status *fpst = fpstp;
Expand Down
2 changes: 2 additions & 0 deletions target/arm/helper-a64.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
DEF_HELPER_FLAGS_3(recpsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64)
Expand Down
6 changes: 6 additions & 0 deletions target/arm/translate-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -10303,6 +10303,9 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
case 0x6: /* FMAX */
gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
break;
case 0x7: /* FRECPS */
gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
break;
case 0x8: /* FMINNM */
gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
break;
Expand All @@ -10319,6 +10322,9 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
case 0xe: /* FMIN */
gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
break;
case 0xf: /* FRSQRTS */
gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
break;
case 0x13: /* FMUL */
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
break;
Expand Down

0 comments on commit 026e2d6

Please sign in to comment.