From 942f3c835e4560fad7dd375f93920c564b4a43ba Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 3 Jul 2018 03:44:37 -0400 Subject: [PATCH] target/arm: Implement SVE Floating Point Unary Operations - Unpredicated Group Backports commit 3887c0388d39930ab419d4ae6e8ca5ea67a74ad5 from qemu --- qemu/aarch64.h | 6 +++++ qemu/aarch64eb.h | 6 +++++ qemu/arm.h | 6 +++++ qemu/armeb.h | 6 +++++ qemu/header_gen.py | 6 +++++ qemu/m68k.h | 6 +++++ qemu/mips.h | 6 +++++ qemu/mips64.h | 6 +++++ qemu/mips64el.h | 6 +++++ qemu/mipsel.h | 6 +++++ qemu/powerpc.h | 6 +++++ qemu/sparc.h | 6 +++++ qemu/sparc64.h | 6 +++++ qemu/target/arm/helper.h | 8 ++++++ qemu/target/arm/sve.decode | 5 ++++ qemu/target/arm/translate-sve.c | 48 +++++++++++++++++++++++++++++++++ qemu/target/arm/vec_helper.c | 20 ++++++++++++++ qemu/x86_64.h | 6 +++++ 18 files changed, 165 insertions(+) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 3d92629e..c8ee7f30 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_aarch64 #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_aarch64 #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_aarch64 +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_aarch64 +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_aarch64 +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_aarch64 +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_aarch64 +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_aarch64 +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_aarch64 #define helper_gvec_fsub_d helper_gvec_fsub_d_aarch64 #define helper_gvec_fsub_h helper_gvec_fsub_h_aarch64 #define helper_gvec_fsub_s helper_gvec_fsub_s_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 1eaf1b1b..d35afe86 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_aarch64eb #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_aarch64eb #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_aarch64eb +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_aarch64eb +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_aarch64eb +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_aarch64eb +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_aarch64eb +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_aarch64eb +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_aarch64eb #define helper_gvec_fsub_d helper_gvec_fsub_d_aarch64eb #define helper_gvec_fsub_h helper_gvec_fsub_h_aarch64eb #define helper_gvec_fsub_s helper_gvec_fsub_s_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 0831161d..f559899c 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_arm #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_arm #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_arm +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_arm +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_arm +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_arm +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_arm +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_arm +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_arm #define helper_gvec_fsub_d helper_gvec_fsub_d_arm #define helper_gvec_fsub_h helper_gvec_fsub_h_arm #define helper_gvec_fsub_s helper_gvec_fsub_s_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 6d8dfb95..4c39118b 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_armeb #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_armeb #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_armeb +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_armeb +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_armeb +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_armeb +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_armeb +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_armeb +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_armeb #define helper_gvec_fsub_d helper_gvec_fsub_d_armeb #define helper_gvec_fsub_h helper_gvec_fsub_h_armeb #define helper_gvec_fsub_s helper_gvec_fsub_s_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 767bb396..d4d6db54 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1138,6 +1138,12 @@ symbols = ( 'helper_gvec_fmul_idx_d', 'helper_gvec_fmul_idx_h', 'helper_gvec_fmul_idx_s', + 'helper_gvec_frecpe_d', + 'helper_gvec_frecpe_h', + 'helper_gvec_frecpe_s', + 'helper_gvec_frsqrte_d', + 'helper_gvec_frsqrte_h', + 'helper_gvec_frsqrte_s', 'helper_gvec_fsub_d', 'helper_gvec_fsub_h', 'helper_gvec_fsub_s', diff --git a/qemu/m68k.h b/qemu/m68k.h index c3c413ae..86619375 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_m68k #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_m68k #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_m68k +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_m68k +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_m68k +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_m68k +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_m68k +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_m68k +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_m68k #define helper_gvec_fsub_d helper_gvec_fsub_d_m68k #define helper_gvec_fsub_h helper_gvec_fsub_h_m68k #define helper_gvec_fsub_s helper_gvec_fsub_s_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 54c134bc..51eba449 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_mips #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_mips #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_mips +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_mips +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_mips +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_mips +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_mips +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_mips +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_mips #define helper_gvec_fsub_d helper_gvec_fsub_d_mips #define helper_gvec_fsub_h helper_gvec_fsub_h_mips #define helper_gvec_fsub_s helper_gvec_fsub_s_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 24e08047..4cbf93e1 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_mips64 #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_mips64 #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_mips64 +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_mips64 +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_mips64 +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_mips64 +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_mips64 +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_mips64 +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_mips64 #define helper_gvec_fsub_d helper_gvec_fsub_d_mips64 #define helper_gvec_fsub_h helper_gvec_fsub_h_mips64 #define helper_gvec_fsub_s helper_gvec_fsub_s_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 1aa2df26..c5c4bf78 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_mips64el #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_mips64el #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_mips64el +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_mips64el +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_mips64el +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_mips64el +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_mips64el +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_mips64el +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_mips64el #define helper_gvec_fsub_d helper_gvec_fsub_d_mips64el #define helper_gvec_fsub_h helper_gvec_fsub_h_mips64el #define helper_gvec_fsub_s helper_gvec_fsub_s_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 1ad968ef..62348d11 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_mipsel #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_mipsel #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_mipsel +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_mipsel +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_mipsel +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_mipsel +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_mipsel +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_mipsel +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_mipsel #define helper_gvec_fsub_d helper_gvec_fsub_d_mipsel #define helper_gvec_fsub_h helper_gvec_fsub_h_mipsel #define helper_gvec_fsub_s helper_gvec_fsub_s_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index fdb4d6cb..20b2101d 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_powerpc #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_powerpc #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_powerpc +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_powerpc +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_powerpc +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_powerpc +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_powerpc +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_powerpc +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_powerpc #define helper_gvec_fsub_d helper_gvec_fsub_d_powerpc #define helper_gvec_fsub_h helper_gvec_fsub_h_powerpc #define helper_gvec_fsub_s helper_gvec_fsub_s_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index dd88f941..da0e643a 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_sparc #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_sparc #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_sparc +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_sparc +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_sparc +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_sparc +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_sparc +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_sparc +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_sparc #define helper_gvec_fsub_d helper_gvec_fsub_d_sparc #define helper_gvec_fsub_h helper_gvec_fsub_h_sparc #define helper_gvec_fsub_s helper_gvec_fsub_s_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 2972efcf..afdb2b58 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_sparc64 #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_sparc64 #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_sparc64 +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_sparc64 +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_sparc64 +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_sparc64 +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_sparc64 +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_sparc64 +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_sparc64 #define helper_gvec_fsub_d helper_gvec_fsub_d_sparc64 #define helper_gvec_fsub_h helper_gvec_fsub_h_sparc64 #define helper_gvec_fsub_s helper_gvec_fsub_s_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 28291c1f..bb087df2 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -603,6 +603,14 @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(gvec_frsqrte_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_frsqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) diff --git a/qemu/target/arm/sve.decode b/qemu/target/arm/sve.decode index 5b515821..f03e7eac 100644 --- a/qemu/target/arm/sve.decode +++ b/qemu/target/arm/sve.decode @@ -753,6 +753,11 @@ FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn +## SVE Floating Point Unary Operations - Unpredicated Group + +FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn +FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn + ### SVE FP Accumulating Reduction Group # SVE floating-point serial reduction (predicated) diff --git a/qemu/target/arm/translate-sve.c b/qemu/target/arm/translate-sve.c index dbf0511c..4ea625cd 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -3653,6 +3653,54 @@ DO_VPZ(FMAXNMV, fmaxnmv) DO_VPZ(FMINV, fminv) DO_VPZ(FMAXV, fmaxv) +/* + *** SVE Floating Point Unary Operations - Unpredicated Group + */ + +static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + unsigned vsz = vec_full_reg_size(s); + TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); + + tcg_gen_gvec_2_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), + vec_full_reg_offset(s, a->rn), + status, vsz, vsz, 0, fn); + tcg_temp_free_ptr(tcg_ctx, status); +} + +static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a, uint32_t insn) +{ + static gen_helper_gvec_2_ptr * const fns[3] = { + gen_helper_gvec_frecpe_h, + gen_helper_gvec_frecpe_s, + gen_helper_gvec_frecpe_d, + }; + if (a->esz == 0) { + return false; + } + if (sve_access_check(s)) { + do_zz_fp(s, a, fns[a->esz - 1]); + } + return true; +} + +static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn) +{ + static gen_helper_gvec_2_ptr * const fns[3] = { + gen_helper_gvec_frsqrte_h, + gen_helper_gvec_frsqrte_s, + gen_helper_gvec_frsqrte_d, + }; + if (a->esz == 0) { + return false; + } + if (sve_access_check(s)) { + do_zz_fp(s, a, fns[a->esz - 1]); + } + return true; +} + /* *** SVE Floating Point Accumulating Reduction Group */ diff --git a/qemu/target/arm/vec_helper.c b/qemu/target/arm/vec_helper.c index df6d4ca7..a84dc149 100644 --- a/qemu/target/arm/vec_helper.c +++ b/qemu/target/arm/vec_helper.c @@ -428,6 +428,26 @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm, clear_tail(d, opr_sz, simd_maxsz(desc)); } +#define DO_2OP(NAME, FUNC, TYPE) \ +void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \ +{ \ + intptr_t i, oprsz = simd_oprsz(desc); \ + TYPE *d = vd, *n = vn; \ + for (i = 0; i < oprsz / sizeof(TYPE); i++) { \ + d[i] = FUNC(n[i], stat); \ + } \ +} + +DO_2OP(gvec_frecpe_h, helper_recpe_f16, float16) +DO_2OP(gvec_frecpe_s, helper_recpe_f32, float32) +DO_2OP(gvec_frecpe_d, helper_recpe_f64, float64) + +DO_2OP(gvec_frsqrte_h, helper_rsqrte_f16, float16) +DO_2OP(gvec_frsqrte_s, helper_rsqrte_f32, float32) +DO_2OP(gvec_frsqrte_d, helper_rsqrte_f64, float64) + +#undef DO_2OP + /* Floating-point trigonometric starting value. * See the ARM ARM pseudocode function FPTrigSMul. */ diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 7ef7d191..4c6e8e0f 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1132,6 +1132,12 @@ #define helper_gvec_fmul_idx_d helper_gvec_fmul_idx_d_x86_64 #define helper_gvec_fmul_idx_h helper_gvec_fmul_idx_h_x86_64 #define helper_gvec_fmul_idx_s helper_gvec_fmul_idx_s_x86_64 +#define helper_gvec_frecpe_d helper_gvec_frecpe_d_x86_64 +#define helper_gvec_frecpe_h helper_gvec_frecpe_h_x86_64 +#define helper_gvec_frecpe_s helper_gvec_frecpe_s_x86_64 +#define helper_gvec_frsqrte_d helper_gvec_frsqrte_d_x86_64 +#define helper_gvec_frsqrte_h helper_gvec_frsqrte_h_x86_64 +#define helper_gvec_frsqrte_s helper_gvec_frsqrte_s_x86_64 #define helper_gvec_fsub_d helper_gvec_fsub_d_x86_64 #define helper_gvec_fsub_h helper_gvec_fsub_h_x86_64 #define helper_gvec_fsub_s helper_gvec_fsub_s_x86_64