From 7211d415a430ee648f3b385127c60aff2a3c2a90 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Jun 2018 13:17:45 -0400 Subject: [PATCH] target/arm: Implement SVE Select Vectors Group Backports commit d3fe4a29d754dee73cbf3cb7584db222981179ac from qemu --- qemu/aarch64.h | 4 +++ qemu/aarch64eb.h | 4 +++ qemu/header_gen.py | 4 +++ qemu/target/arm/helper-sve.h | 9 ++++++ qemu/target/arm/sve.decode | 6 ++++ qemu/target/arm/sve_helper.c | 55 +++++++++++++++++++++++++++++++++ qemu/target/arm/translate-sve.c | 2 ++ 7 files changed, 84 insertions(+) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 437f6af3..7c68a22f 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3469,6 +3469,10 @@ #define helper_sve_sdiv_zpzz_d helper_sve_sdiv_zpzz_d_aarch64 #define helper_sve_sdiv_zpzz_s helper_sve_sdiv_zpzz_s_aarch64 #define helper_sve_sel_pppp helper_sve_sel_pppp_aarch64 +#define helper_sve_sel_zpzz_b helper_sve_sel_zpzz_b_aarch64 +#define helper_sve_sel_zpzz_d helper_sve_sel_zpzz_d_aarch64 +#define helper_sve_sel_zpzz_h helper_sve_sel_zpzz_h_aarch64 +#define helper_sve_sel_zpzz_s helper_sve_sel_zpzz_s_aarch64 #define helper_sve_smax_zpzz_b helper_sve_smax_zpzz_b_aarch64 #define helper_sve_smax_zpzz_d helper_sve_smax_zpzz_d_aarch64 #define helper_sve_smax_zpzz_h helper_sve_smax_zpzz_h_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 3a94f259..31d1b74a 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3469,6 +3469,10 @@ #define helper_sve_sdiv_zpzz_d helper_sve_sdiv_zpzz_d_aarch64eb #define helper_sve_sdiv_zpzz_s helper_sve_sdiv_zpzz_s_aarch64eb #define helper_sve_sel_pppp helper_sve_sel_pppp_aarch64eb +#define helper_sve_sel_zpzz_b helper_sve_sel_zpzz_b_aarch64eb +#define helper_sve_sel_zpzz_d helper_sve_sel_zpzz_d_aarch64eb +#define helper_sve_sel_zpzz_h helper_sve_sel_zpzz_h_aarch64eb +#define helper_sve_sel_zpzz_s helper_sve_sel_zpzz_s_aarch64eb #define helper_sve_smax_zpzz_b helper_sve_smax_zpzz_b_aarch64eb #define helper_sve_smax_zpzz_d helper_sve_smax_zpzz_d_aarch64eb #define helper_sve_smax_zpzz_h helper_sve_smax_zpzz_h_aarch64eb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 969f5806..437850ba 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3490,6 +3490,10 @@ aarch64_symbols = ( 'helper_sve_sdiv_zpzz_d', 'helper_sve_sdiv_zpzz_s', 'helper_sve_sel_pppp', + 'helper_sve_sel_zpzz_b', + 'helper_sve_sel_zpzz_d', + 'helper_sve_sel_zpzz_h', + 'helper_sve_sel_zpzz_s', 'helper_sve_smax_zpzz_b', 'helper_sve_smax_zpzz_d', 'helper_sve_smax_zpzz_h', diff --git a/qemu/target/arm/helper-sve.h b/qemu/target/arm/helper-sve.h index c3f8a2b5..0f57f648 100644 --- a/qemu/target/arm/helper-sve.h +++ b/qemu/target/arm/helper-sve.h @@ -195,6 +195,15 @@ DEF_HELPER_FLAGS_5(sve_lsl_zpzz_s, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_5(sve_lsl_zpzz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(sve_sel_zpzz_b, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(sve_sel_zpzz_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_5(sve_asr_zpzw_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(sve_asr_zpzw_h, TCG_CALL_NO_RWG, diff --git a/qemu/target/arm/sve.decode b/qemu/target/arm/sve.decode index e6a9b5e3..0eaa0a50 100644 --- a/qemu/target/arm/sve.decode +++ b/qemu/target/arm/sve.decode @@ -98,6 +98,7 @@ &rprr_esz rn=%reg_movprfx @rdm_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 \ &rprr_esz rm=%reg_movprfx +@rd_pg4_rn_rm ........ esz:2 . rm:5 .. pg:4 rn:5 rd:5 &rprr_esz # One register operand, with governing predicate, vector element size @rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz @@ -466,6 +467,11 @@ RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn # SVE vector splice (predicated) SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm +### SVE Select Vectors Group + +# SVE select vector elements (predicated) +SEL_zpzz 00000101 .. 1 ..... 11 .... ..... ..... @rd_pg4_rn_rm + ### SVE Predicate Logical Operations Group # SVE predicate logical operations diff --git a/qemu/target/arm/sve_helper.c b/qemu/target/arm/sve_helper.c index 27dd8ecd..47bb1dc9 100644 --- a/qemu/target/arm/sve_helper.c +++ b/qemu/target/arm/sve_helper.c @@ -2145,3 +2145,58 @@ void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) } swap_memmove(vd + len, vm, opr_sz * 8 - len); } + +void HELPER(sve_sel_zpzz_b)(void *vd, void *vn, void *vm, + void *vg, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc) / 8; + uint64_t *d = vd, *n = vn, *m = vm; + uint8_t *pg = vg; + + for (i = 0; i < opr_sz; i += 1) { + uint64_t nn = n[i], mm = m[i]; + uint64_t pp = expand_pred_b(pg[H1(i)]); + d[i] = (nn & pp) | (mm & ~pp); + } +} + +void HELPER(sve_sel_zpzz_h)(void *vd, void *vn, void *vm, + void *vg, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc) / 8; + uint64_t *d = vd, *n = vn, *m = vm; + uint8_t *pg = vg; + + for (i = 0; i < opr_sz; i += 1) { + uint64_t nn = n[i], mm = m[i]; + uint64_t pp = expand_pred_h(pg[H1(i)]); + d[i] = (nn & pp) | (mm & ~pp); + } +} + +void HELPER(sve_sel_zpzz_s)(void *vd, void *vn, void *vm, + void *vg, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc) / 8; + uint64_t *d = vd, *n = vn, *m = vm; + uint8_t *pg = vg; + + for (i = 0; i < opr_sz; i += 1) { + uint64_t nn = n[i], mm = m[i]; + uint64_t pp = expand_pred_s(pg[H1(i)]); + d[i] = (nn & pp) | (mm & ~pp); + } +} + +void HELPER(sve_sel_zpzz_d)(void *vd, void *vn, void *vm, + void *vg, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc) / 8; + uint64_t *d = vd, *n = vn, *m = vm; + uint8_t *pg = vg; + + for (i = 0; i < opr_sz; i += 1) { + uint64_t nn = n[i], mm = m[i]; + d[i] = (pg[H1(i)] & 1 ? nn : mm); + } +} diff --git a/qemu/target/arm/translate-sve.c b/qemu/target/arm/translate-sve.c index b3a5cae8..b4643f5f 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -380,6 +380,8 @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn) return do_zpzz_ool(s, a, fns[a->esz]); } +DO_ZPZZ(SEL, sel) + #undef DO_ZPZZ /*