mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
target/arm: Implement FP16 for Neon VADD, VSUB, VABD, VMUL
Implement FP16 support for the Neon insns which use the DO_3S_FP_GVEC macro: VADD, VSUB, VABD, VMUL. For VABD this requires us to implement a new gvec_fabd_h helper using the machinery we have already for the other helpers. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200828183354.27913-24-peter.maydell@linaro.org
This commit is contained in:
parent
46a4b85452
commit
e4a6d4a69e
3 changed files with 26 additions and 17 deletions
|
@ -629,6 +629,7 @@ DEF_HELPER_FLAGS_5(gvec_fmul_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_5(gvec_fabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
|
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
|
||||||
|
|
|
@ -1082,34 +1082,36 @@ static bool do_3same_fp(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#define WRAP_FP_GVEC(WRAPNAME, FPST, FUNC) \
|
||||||
* For all the functions using this macro, size == 1 means fp16,
|
static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
|
||||||
* which is an architecture extension we don't implement yet.
|
uint32_t rn_ofs, uint32_t rm_ofs, \
|
||||||
*/
|
uint32_t oprsz, uint32_t maxsz) \
|
||||||
#define DO_3S_FP_GVEC(INSN,FUNC) \
|
|
||||||
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
|
|
||||||
uint32_t rn_ofs, uint32_t rm_ofs, \
|
|
||||||
uint32_t oprsz, uint32_t maxsz) \
|
|
||||||
{ \
|
{ \
|
||||||
TCGv_ptr fpst = fpstatus_ptr(FPST_STD); \
|
TCGv_ptr fpst = fpstatus_ptr(FPST); \
|
||||||
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpst, \
|
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpst, \
|
||||||
oprsz, maxsz, 0, FUNC); \
|
oprsz, maxsz, 0, FUNC); \
|
||||||
tcg_temp_free_ptr(fpst); \
|
tcg_temp_free_ptr(fpst); \
|
||||||
} \
|
}
|
||||||
|
|
||||||
|
#define DO_3S_FP_GVEC(INSN,SFUNC,HFUNC) \
|
||||||
|
WRAP_FP_GVEC(gen_##INSN##_fp32_3s, FPST_STD, SFUNC) \
|
||||||
|
WRAP_FP_GVEC(gen_##INSN##_fp16_3s, FPST_STD_F16, HFUNC) \
|
||||||
static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
|
static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
|
||||||
{ \
|
{ \
|
||||||
if (a->size != 0) { \
|
if (a->size != 0) { \
|
||||||
/* TODO fp16 support */ \
|
if (!dc_isar_feature(aa32_fp16_arith, s)) { \
|
||||||
return false; \
|
return false; \
|
||||||
|
} \
|
||||||
|
return do_3same(s, a, gen_##INSN##_fp16_3s); \
|
||||||
} \
|
} \
|
||||||
return do_3same(s, a, gen_##INSN##_3s); \
|
return do_3same(s, a, gen_##INSN##_fp32_3s); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s)
|
DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s, gen_helper_gvec_fadd_h)
|
||||||
DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s)
|
DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s, gen_helper_gvec_fsub_h)
|
||||||
DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s)
|
DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s, gen_helper_gvec_fabd_h)
|
||||||
DO_3S_FP_GVEC(VMUL, gen_helper_gvec_fmul_s)
|
DO_3S_FP_GVEC(VMUL, gen_helper_gvec_fmul_s, gen_helper_gvec_fmul_h)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For all the functions using this macro, size == 1 means fp16,
|
* For all the functions using this macro, size == 1 means fp16,
|
||||||
|
|
|
@ -707,6 +707,11 @@ static float64 float64_ftsmul(float64 op1, uint64_t op2, float_status *stat)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float16 float16_abd(float16 op1, float16 op2, float_status *stat)
|
||||||
|
{
|
||||||
|
return float16_abs(float16_sub(op1, op2, stat));
|
||||||
|
}
|
||||||
|
|
||||||
static float32 float32_abd(float32 op1, float32 op2, float_status *stat)
|
static float32 float32_abd(float32 op1, float32 op2, float_status *stat)
|
||||||
{
|
{
|
||||||
return float32_abs(float32_sub(op1, op2, stat));
|
return float32_abs(float32_sub(op1, op2, stat));
|
||||||
|
@ -739,6 +744,7 @@ DO_3OP(gvec_ftsmul_h, float16_ftsmul, float16)
|
||||||
DO_3OP(gvec_ftsmul_s, float32_ftsmul, float32)
|
DO_3OP(gvec_ftsmul_s, float32_ftsmul, float32)
|
||||||
DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
|
DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
|
||||||
|
|
||||||
|
DO_3OP(gvec_fabd_h, float16_abd, float16)
|
||||||
DO_3OP(gvec_fabd_s, float32_abd, float32)
|
DO_3OP(gvec_fabd_s, float32_abd, float32)
|
||||||
|
|
||||||
#ifdef TARGET_AARCH64
|
#ifdef TARGET_AARCH64
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue