diff --git a/qemu/aarch64.h b/qemu/aarch64.h index a62e3f3a..afca0ee8 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_aarch64 #define helper_gvec_sdot_b helper_gvec_sdot_b_aarch64 #define helper_gvec_sdot_h helper_gvec_sdot_h_aarch64 +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_aarch64 +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_aarch64 #define helper_gvec_shl8i helper_gvec_shl8i_aarch64 #define helper_gvec_shl16i helper_gvec_shl16i_aarch64 #define helper_gvec_shl32i helper_gvec_shl32i_aarch64 @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_aarch64 #define helper_gvec_udot_b helper_gvec_udot_b_aarch64 #define helper_gvec_udot_h helper_gvec_udot_h_aarch64 +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_aarch64 +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_aarch64 #define helper_gvec_usadd8 helper_gvec_usadd8_aarch64 #define helper_gvec_usadd16 helper_gvec_usadd16_aarch64 #define helper_gvec_usadd32 helper_gvec_usadd32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 2de5a7f8..46b5920e 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_aarch64eb #define helper_gvec_sdot_b helper_gvec_sdot_b_aarch64eb #define helper_gvec_sdot_h helper_gvec_sdot_h_aarch64eb +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_aarch64eb +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_aarch64eb #define helper_gvec_shl8i helper_gvec_shl8i_aarch64eb #define helper_gvec_shl16i helper_gvec_shl16i_aarch64eb #define helper_gvec_shl32i helper_gvec_shl32i_aarch64eb @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_aarch64eb #define helper_gvec_udot_b helper_gvec_udot_b_aarch64eb #define helper_gvec_udot_h helper_gvec_udot_h_aarch64eb +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_aarch64eb +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_aarch64eb #define helper_gvec_usadd8 helper_gvec_usadd8_aarch64eb #define helper_gvec_usadd16 helper_gvec_usadd16_aarch64eb #define helper_gvec_usadd32 helper_gvec_usadd32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 61ee263b..fbb62ddc 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_arm #define helper_gvec_sdot_b helper_gvec_sdot_b_arm #define helper_gvec_sdot_h helper_gvec_sdot_h_arm +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_arm +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_arm #define helper_gvec_shl8i helper_gvec_shl8i_arm #define helper_gvec_shl16i helper_gvec_shl16i_arm #define helper_gvec_shl32i helper_gvec_shl32i_arm @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_arm #define helper_gvec_udot_b helper_gvec_udot_b_arm #define helper_gvec_udot_h helper_gvec_udot_h_arm +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_arm +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_arm #define helper_gvec_usadd8 helper_gvec_usadd8_arm #define helper_gvec_usadd16 helper_gvec_usadd16_arm #define helper_gvec_usadd32 helper_gvec_usadd32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 59f2b322..1067c020 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_armeb #define helper_gvec_sdot_b helper_gvec_sdot_b_armeb #define helper_gvec_sdot_h helper_gvec_sdot_h_armeb +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_armeb +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_armeb #define helper_gvec_shl8i helper_gvec_shl8i_armeb #define helper_gvec_shl16i helper_gvec_shl16i_armeb #define helper_gvec_shl32i helper_gvec_shl32i_armeb @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_armeb #define helper_gvec_udot_b helper_gvec_udot_b_armeb #define helper_gvec_udot_h helper_gvec_udot_h_armeb +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_armeb +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_armeb #define helper_gvec_usadd8 helper_gvec_usadd8_armeb #define helper_gvec_usadd16 helper_gvec_usadd16_armeb #define helper_gvec_usadd32 helper_gvec_usadd32_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index df3745c7..73a7e46d 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1197,6 +1197,8 @@ symbols = ( 'helper_gvec_sar64i', 'helper_gvec_sdot_b', 'helper_gvec_sdot_h', + 'helper_gvec_sdot_idx_b', + 'helper_gvec_sdot_idx_h', 'helper_gvec_shl8i', 'helper_gvec_shl16i', 'helper_gvec_shl32i', @@ -1223,6 +1225,8 @@ symbols = ( 'helper_gvec_sssub64', 'helper_gvec_udot_b', 'helper_gvec_udot_h', + 'helper_gvec_udot_idx_b', + 'helper_gvec_udot_idx_h', 'helper_gvec_usadd8', 'helper_gvec_usadd16', 'helper_gvec_usadd32', diff --git a/qemu/m68k.h b/qemu/m68k.h index 06f2008e..3e87436a 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_m68k #define helper_gvec_sdot_b helper_gvec_sdot_b_m68k #define helper_gvec_sdot_h helper_gvec_sdot_h_m68k +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_m68k +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_m68k #define helper_gvec_shl8i helper_gvec_shl8i_m68k #define helper_gvec_shl16i helper_gvec_shl16i_m68k #define helper_gvec_shl32i helper_gvec_shl32i_m68k @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_m68k #define helper_gvec_udot_b helper_gvec_udot_b_m68k #define helper_gvec_udot_h helper_gvec_udot_h_m68k +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_m68k +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_m68k #define helper_gvec_usadd8 helper_gvec_usadd8_m68k #define helper_gvec_usadd16 helper_gvec_usadd16_m68k #define helper_gvec_usadd32 helper_gvec_usadd32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 1f48b68d..ec6380f8 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_mips #define helper_gvec_sdot_b helper_gvec_sdot_b_mips #define helper_gvec_sdot_h helper_gvec_sdot_h_mips +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_mips +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_mips #define helper_gvec_shl8i helper_gvec_shl8i_mips #define helper_gvec_shl16i helper_gvec_shl16i_mips #define helper_gvec_shl32i helper_gvec_shl32i_mips @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_mips #define helper_gvec_udot_b helper_gvec_udot_b_mips #define helper_gvec_udot_h helper_gvec_udot_h_mips +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_mips +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_mips #define helper_gvec_usadd8 helper_gvec_usadd8_mips #define helper_gvec_usadd16 helper_gvec_usadd16_mips #define helper_gvec_usadd32 helper_gvec_usadd32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 8476e51c..e87e4ff0 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_mips64 #define helper_gvec_sdot_b helper_gvec_sdot_b_mips64 #define helper_gvec_sdot_h helper_gvec_sdot_h_mips64 +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_mips64 +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_mips64 #define helper_gvec_shl8i helper_gvec_shl8i_mips64 #define helper_gvec_shl16i helper_gvec_shl16i_mips64 #define helper_gvec_shl32i helper_gvec_shl32i_mips64 @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_mips64 #define helper_gvec_udot_b helper_gvec_udot_b_mips64 #define helper_gvec_udot_h helper_gvec_udot_h_mips64 +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_mips64 +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_mips64 #define helper_gvec_usadd8 helper_gvec_usadd8_mips64 #define helper_gvec_usadd16 helper_gvec_usadd16_mips64 #define helper_gvec_usadd32 helper_gvec_usadd32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index fb87de92..33890649 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_mips64el #define helper_gvec_sdot_b helper_gvec_sdot_b_mips64el #define helper_gvec_sdot_h helper_gvec_sdot_h_mips64el +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_mips64el +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_mips64el #define helper_gvec_shl8i helper_gvec_shl8i_mips64el #define helper_gvec_shl16i helper_gvec_shl16i_mips64el #define helper_gvec_shl32i helper_gvec_shl32i_mips64el @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_mips64el #define helper_gvec_udot_b helper_gvec_udot_b_mips64el #define helper_gvec_udot_h helper_gvec_udot_h_mips64el +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_mips64el +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_mips64el #define helper_gvec_usadd8 helper_gvec_usadd8_mips64el #define helper_gvec_usadd16 helper_gvec_usadd16_mips64el #define helper_gvec_usadd32 helper_gvec_usadd32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 654f8031..777ff2ce 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_mipsel #define helper_gvec_sdot_b helper_gvec_sdot_b_mipsel #define helper_gvec_sdot_h helper_gvec_sdot_h_mipsel +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_mipsel +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_mipsel #define helper_gvec_shl8i helper_gvec_shl8i_mipsel #define helper_gvec_shl16i helper_gvec_shl16i_mipsel #define helper_gvec_shl32i helper_gvec_shl32i_mipsel @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_mipsel #define helper_gvec_udot_b helper_gvec_udot_b_mipsel #define helper_gvec_udot_h helper_gvec_udot_h_mipsel +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_mipsel +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_mipsel #define helper_gvec_usadd8 helper_gvec_usadd8_mipsel #define helper_gvec_usadd16 helper_gvec_usadd16_mipsel #define helper_gvec_usadd32 helper_gvec_usadd32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 3c8b3c92..bee4f568 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_powerpc #define helper_gvec_sdot_b helper_gvec_sdot_b_powerpc #define helper_gvec_sdot_h helper_gvec_sdot_h_powerpc +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_powerpc +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_powerpc #define helper_gvec_shl8i helper_gvec_shl8i_powerpc #define helper_gvec_shl16i helper_gvec_shl16i_powerpc #define helper_gvec_shl32i helper_gvec_shl32i_powerpc @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_powerpc #define helper_gvec_udot_b helper_gvec_udot_b_powerpc #define helper_gvec_udot_h helper_gvec_udot_h_powerpc +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_powerpc +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_powerpc #define helper_gvec_usadd8 helper_gvec_usadd8_powerpc #define helper_gvec_usadd16 helper_gvec_usadd16_powerpc #define helper_gvec_usadd32 helper_gvec_usadd32_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index ce9f5855..155c6633 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_sparc #define helper_gvec_sdot_b helper_gvec_sdot_b_sparc #define helper_gvec_sdot_h helper_gvec_sdot_h_sparc +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_sparc +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_sparc #define helper_gvec_shl8i helper_gvec_shl8i_sparc #define helper_gvec_shl16i helper_gvec_shl16i_sparc #define helper_gvec_shl32i helper_gvec_shl32i_sparc @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_sparc #define helper_gvec_udot_b helper_gvec_udot_b_sparc #define helper_gvec_udot_h helper_gvec_udot_h_sparc +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_sparc +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_sparc #define helper_gvec_usadd8 helper_gvec_usadd8_sparc #define helper_gvec_usadd16 helper_gvec_usadd16_sparc #define helper_gvec_usadd32 helper_gvec_usadd32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 9cc0f56d..68474ecd 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_sparc64 #define helper_gvec_sdot_b helper_gvec_sdot_b_sparc64 #define helper_gvec_sdot_h helper_gvec_sdot_h_sparc64 +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_sparc64 +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_sparc64 #define helper_gvec_shl8i helper_gvec_shl8i_sparc64 #define helper_gvec_shl16i helper_gvec_shl16i_sparc64 #define helper_gvec_shl32i helper_gvec_shl32i_sparc64 @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_sparc64 #define helper_gvec_udot_b helper_gvec_udot_b_sparc64 #define helper_gvec_udot_h helper_gvec_udot_h_sparc64 +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_sparc64 +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_sparc64 #define helper_gvec_usadd8 helper_gvec_usadd8_sparc64 #define helper_gvec_usadd16 helper_gvec_usadd16_sparc64 #define helper_gvec_usadd32 helper_gvec_usadd32_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 4455646d..86afa4bf 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -590,6 +590,11 @@ DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_sdot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_udot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_sdot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_udot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG, diff --git a/qemu/target/arm/sve.decode b/qemu/target/arm/sve.decode index 074a658c..72879c43 100644 --- a/qemu/target/arm/sve.decode +++ b/qemu/target/arm/sve.decode @@ -738,6 +738,12 @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s # SVE integer dot product (unpredicated) DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx +# SVE integer dot product (indexed) +DOT_zzx 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \ + sz=0 ra=%reg_movprfx +DOT_zzx 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \ + sz=1 ra=%reg_movprfx + # SVE floating-point complex add (predicated) FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \ rn=%reg_movprfx diff --git a/qemu/target/arm/translate-sve.c b/qemu/target/arm/translate-sve.c index 6bc55a7d..dd7f9e93 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -864,6 +864,24 @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn) return true; } +static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a, uint32_t insn) +{ + static gen_helper_gvec_3 * const fns[2][2] = { + { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h }, + { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h } + }; + + if (sve_access_check(s)) { + TCGContext *tcg_ctx = s->uc->tcg_ctx; + unsigned vsz = vec_full_reg_size(s); + tcg_gen_gvec_3_ool(tcg_ctx, vec_full_reg_offset(s, a->rd), + vec_full_reg_offset(s, a->rn), + vec_full_reg_offset(s, a->rm), + vsz, vsz, a->index, fns[a->u][a->sz]); + } + return true; +} + /* *** SVE Integer Multiply-Add Group */ diff --git a/qemu/target/arm/vec_helper.c b/qemu/target/arm/vec_helper.c index 29f483bb..d77057c1 100644 --- a/qemu/target/arm/vec_helper.c +++ b/qemu/target/arm/vec_helper.c @@ -262,6 +262,130 @@ void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc) clear_tail(d, opr_sz, simd_maxsz(desc)); } +void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc) +{ + intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4; + intptr_t index = simd_data(desc); + uint32_t *d = vd; + int8_t *n = vn; + int8_t *m_indexed = (int8_t *)vm + index * 4; + + /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd. + * Otherwise opr_sz is a multiple of 16. + */ + segend = MIN(4, opr_sz_4); + i = 0; + do { + int8_t m0 = m_indexed[i * 4 + 0]; + int8_t m1 = m_indexed[i * 4 + 1]; + int8_t m2 = m_indexed[i * 4 + 2]; + int8_t m3 = m_indexed[i * 4 + 3]; + + do { + d[i] += n[i * 4 + 0] * m0 + + n[i * 4 + 1] * m1 + + n[i * 4 + 2] * m2 + + n[i * 4 + 3] * m3; + } while (++i < segend); + segend = i + 4; + } while (i < opr_sz_4); + + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc) +{ + intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4; + intptr_t index = simd_data(desc); + uint32_t *d = vd; + uint8_t *n = vn; + uint8_t *m_indexed = (uint8_t *)vm + index * 4; + + /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd. + * Otherwise opr_sz is a multiple of 16. + */ + segend = MIN(4, opr_sz_4); + i = 0; + do { + uint8_t m0 = m_indexed[i * 4 + 0]; + uint8_t m1 = m_indexed[i * 4 + 1]; + uint8_t m2 = m_indexed[i * 4 + 2]; + uint8_t m3 = m_indexed[i * 4 + 3]; + + do { + d[i] += n[i * 4 + 0] * m0 + + n[i * 4 + 1] * m1 + + n[i * 4 + 2] * m2 + + n[i * 4 + 3] * m3; + } while (++i < segend); + segend = i + 4; + } while (i < opr_sz_4); + + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8; + intptr_t index = simd_data(desc); + uint64_t *d = vd; + int16_t *n = vn; + int16_t *m_indexed = (int16_t *)vm + index * 4; + + /* This is supported by SVE only, so opr_sz is always a multiple of 16. + * Process the entire segment all at once, writing back the results + * only after we've consumed all of the inputs. + */ + for (i = 0; i < opr_sz_8 ; i += 2) { + uint64_t d0, d1; + + d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0]; + d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1]; + d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2]; + d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3]; + d1 = n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0]; + d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1]; + d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2]; + d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3]; + + d[i + 0] += d0; + d[i + 1] += d1; + } + + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8; + intptr_t index = simd_data(desc); + uint64_t *d = vd; + uint16_t *n = vn; + uint16_t *m_indexed = (uint16_t *)vm + index * 4; + + /* This is supported by SVE only, so opr_sz is always a multiple of 16. + * Process the entire segment all at once, writing back the results + * only after we've consumed all of the inputs. + */ + for (i = 0; i < opr_sz_8 ; i += 2) { + uint64_t d0, d1; + + d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0]; + d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1]; + d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2]; + d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3]; + d1 = n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0]; + d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1]; + d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2]; + d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3]; + + d[i + 0] += d0; + d[i + 1] += d1; + } + + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm, void *vfpst, uint32_t desc) { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 8ab54ae0..fa983091 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1191,6 +1191,8 @@ #define helper_gvec_sar64i helper_gvec_sar64i_x86_64 #define helper_gvec_sdot_b helper_gvec_sdot_b_x86_64 #define helper_gvec_sdot_h helper_gvec_sdot_h_x86_64 +#define helper_gvec_sdot_idx_b helper_gvec_sdot_idx_b_x86_64 +#define helper_gvec_sdot_idx_h helper_gvec_sdot_idx_h_x86_64 #define helper_gvec_shl8i helper_gvec_shl8i_x86_64 #define helper_gvec_shl16i helper_gvec_shl16i_x86_64 #define helper_gvec_shl32i helper_gvec_shl32i_x86_64 @@ -1217,6 +1219,8 @@ #define helper_gvec_sssub64 helper_gvec_sssub64_x86_64 #define helper_gvec_udot_b helper_gvec_udot_b_x86_64 #define helper_gvec_udot_h helper_gvec_udot_h_x86_64 +#define helper_gvec_udot_idx_b helper_gvec_udot_idx_b_x86_64 +#define helper_gvec_udot_idx_h helper_gvec_udot_idx_h_x86_64 #define helper_gvec_usadd8 helper_gvec_usadd8_x86_64 #define helper_gvec_usadd16 helper_gvec_usadd16_x86_64 #define helper_gvec_usadd32 helper_gvec_usadd32_x86_64