diff --git a/qemu/aarch64.h b/qemu/aarch64.h index a87afdbb..ba5ad03c 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_aarch64 #define helper_gvec_orc helper_gvec_orc_aarch64 #define helper_gvec_ors helper_gvec_ors_aarch64 +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_aarch64 +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_aarch64 +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_aarch64 +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_aarch64 #define helper_gvec_sar8i helper_gvec_sar8i_aarch64 #define helper_gvec_sar16i helper_gvec_sar16i_aarch64 #define helper_gvec_sar32i helper_gvec_sar32i_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index e924f8c3..c4aec7a7 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_aarch64eb #define helper_gvec_orc helper_gvec_orc_aarch64eb #define helper_gvec_ors helper_gvec_ors_aarch64eb +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_aarch64eb +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_aarch64eb +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_aarch64eb +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_aarch64eb #define helper_gvec_sar8i helper_gvec_sar8i_aarch64eb #define helper_gvec_sar16i helper_gvec_sar16i_aarch64eb #define helper_gvec_sar32i helper_gvec_sar32i_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 345824bb..71f84cb9 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_arm #define helper_gvec_orc helper_gvec_orc_arm #define helper_gvec_ors helper_gvec_ors_arm +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_arm +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_arm +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_arm +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_arm #define helper_gvec_sar8i helper_gvec_sar8i_arm #define helper_gvec_sar16i helper_gvec_sar16i_arm #define helper_gvec_sar32i helper_gvec_sar32i_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 8ccc30d1..9b4795ef 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_armeb #define helper_gvec_orc helper_gvec_orc_armeb #define helper_gvec_ors helper_gvec_ors_armeb +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_armeb +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_armeb +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_armeb +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_armeb #define helper_gvec_sar8i helper_gvec_sar8i_armeb #define helper_gvec_sar16i helper_gvec_sar16i_armeb #define helper_gvec_sar32i helper_gvec_sar32i_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 90ae2685..36481c54 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1036,6 +1036,10 @@ symbols = ( 'helper_gvec_or', 'helper_gvec_orc', 'helper_gvec_ors', + 'helper_gvec_qrdmlah_s16', + 'helper_gvec_qrdmlah_s32', + 'helper_gvec_qrdmlsh_s16', + 'helper_gvec_qrdmlsh_s32', 'helper_gvec_sar8i', 'helper_gvec_sar16i', 'helper_gvec_sar32i', diff --git a/qemu/m68k.h b/qemu/m68k.h index b56cc855..95eda856 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_m68k #define helper_gvec_orc helper_gvec_orc_m68k #define helper_gvec_ors helper_gvec_ors_m68k +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_m68k +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_m68k +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_m68k +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_m68k #define helper_gvec_sar8i helper_gvec_sar8i_m68k #define helper_gvec_sar16i helper_gvec_sar16i_m68k #define helper_gvec_sar32i helper_gvec_sar32i_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 58fee674..13758cc5 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_mips #define helper_gvec_orc helper_gvec_orc_mips #define helper_gvec_ors helper_gvec_ors_mips +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_mips #define helper_gvec_sar8i helper_gvec_sar8i_mips #define helper_gvec_sar16i helper_gvec_sar16i_mips #define helper_gvec_sar32i helper_gvec_sar32i_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 3ab54e8b..4538eabd 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_mips64 #define helper_gvec_orc helper_gvec_orc_mips64 #define helper_gvec_ors helper_gvec_ors_mips64 +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips64 +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips64 +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips64 +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_mips64 #define helper_gvec_sar8i helper_gvec_sar8i_mips64 #define helper_gvec_sar16i helper_gvec_sar16i_mips64 #define helper_gvec_sar32i helper_gvec_sar32i_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 8da63ed0..aa2d225b 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_mips64el #define helper_gvec_orc helper_gvec_orc_mips64el #define helper_gvec_ors helper_gvec_ors_mips64el +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips64el +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips64el +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips64el +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_mips64el #define helper_gvec_sar8i helper_gvec_sar8i_mips64el #define helper_gvec_sar16i helper_gvec_sar16i_mips64el #define helper_gvec_sar32i helper_gvec_sar32i_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 91fb61d4..8495d5a2 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_mipsel #define helper_gvec_orc helper_gvec_orc_mipsel #define helper_gvec_ors helper_gvec_ors_mipsel +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mipsel +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mipsel +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mipsel +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_mipsel #define helper_gvec_sar8i helper_gvec_sar8i_mipsel #define helper_gvec_sar16i helper_gvec_sar16i_mipsel #define helper_gvec_sar32i helper_gvec_sar32i_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 494433b1..b7fed034 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_powerpc #define helper_gvec_orc helper_gvec_orc_powerpc #define helper_gvec_ors helper_gvec_ors_powerpc +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_powerpc +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_powerpc +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_powerpc +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_powerpc #define helper_gvec_sar8i helper_gvec_sar8i_powerpc #define helper_gvec_sar16i helper_gvec_sar16i_powerpc #define helper_gvec_sar32i helper_gvec_sar32i_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 10e15cde..37bc689c 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_sparc #define helper_gvec_orc helper_gvec_orc_sparc #define helper_gvec_ors helper_gvec_ors_sparc +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_sparc +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_sparc +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_sparc +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_sparc #define helper_gvec_sar8i helper_gvec_sar8i_sparc #define helper_gvec_sar16i helper_gvec_sar16i_sparc #define helper_gvec_sar32i helper_gvec_sar32i_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index b3535f70..24449419 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_sparc64 #define helper_gvec_orc helper_gvec_orc_sparc64 #define helper_gvec_ors helper_gvec_ors_sparc64 +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_sparc64 +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_sparc64 +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_sparc64 +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_sparc64 #define helper_gvec_sar8i helper_gvec_sar8i_sparc64 #define helper_gvec_sar16i helper_gvec_sar16i_sparc64 #define helper_gvec_sar32i helper_gvec_sar32i_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 34b9db9d..fe5d6542 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -571,6 +571,15 @@ DEF_HELPER_2(dc_zva, void, env, i64) DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) + #ifdef TARGET_ARM #define helper_clz helper_clz_arm #define gen_helper_clz gen_helper_clz_arm diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 98c942da..b7838068 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -745,6 +745,20 @@ static void gen_gvec_op3(DisasContext *s, bool is_q, int rd, vec_full_reg_size(s), gvec_op); } +/* Expand a 3-operand + env pointer operation using + * an out-of-line helper. + */ +static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd, + int rn, int rm, gen_helper_gvec_3_ptr *fn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + + tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd), + vec_full_reg_offset(s, rn), + vec_full_reg_offset(s, rm), tcg_ctx->cpu_env, + is_q ? 16 : 8, vec_full_reg_size(s), 0, fn); +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -10938,6 +10952,76 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn) clear_vec_high(s, is_q, rd); } +/* AdvSIMD three same extra + * 31 30 29 28 24 23 22 21 20 16 15 14 11 10 9 5 4 0 + * +---+---+---+-----------+------+---+------+---+--------+---+----+----+ + * | 0 | Q | U | 0 1 1 1 0 | size | 0 | Rm | 1 | opcode | 1 | Rn | Rd | + * +---+---+---+-----------+------+---+------+---+--------+---+----+----+ + */ +static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) +{ + int rd = extract32(insn, 0, 5); + int rn = extract32(insn, 5, 5); + int opcode = extract32(insn, 11, 4); + int rm = extract32(insn, 16, 5); + int size = extract32(insn, 22, 2); + bool u = extract32(insn, 29, 1); + bool is_q = extract32(insn, 30, 1); + int feature; + + switch (u * 16 + opcode) { + case 0x10: /* SQRDMLAH (vector) */ + case 0x11: /* SQRDMLSH (vector) */ + if (size != 1 && size != 2) { + unallocated_encoding(s); + return; + } + feature = ARM_FEATURE_V8_RDM; + break; + default: + unallocated_encoding(s); + return; + } + if (!arm_dc_feature(s, feature)) { + unallocated_encoding(s); + return; + } + if (!fp_access_check(s)) { + return; + } + + switch (opcode) { + case 0x0: /* SQRDMLAH (vector) */ + switch (size) { + case 1: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s16); + break; + case 2: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s32); + break; + default: + g_assert_not_reached(); + } + return; + + case 0x1: /* SQRDMLSH (vector) */ + switch (size) { + case 1: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s16); + break; + case 2: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s32); + break; + default: + g_assert_not_reached(); + } + return; + + default: + g_assert_not_reached(); + } +} + static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, int size, int rn, int rd) { @@ -13032,6 +13116,7 @@ static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn) static const AArch64DecodeTable data_proc_simd[] = { /* pattern , mask , fn */ { 0x0e200400, 0x9f200400, disas_simd_three_reg_same }, + { 0x0e008400, 0x9f208400, disas_simd_three_reg_same_extra }, { 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff }, { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, { 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes }, diff --git a/qemu/x86_64.h b/qemu/x86_64.h index f9cccf35..22d48bdd 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1030,6 +1030,10 @@ #define helper_gvec_or helper_gvec_or_x86_64 #define helper_gvec_orc helper_gvec_orc_x86_64 #define helper_gvec_ors helper_gvec_ors_x86_64 +#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_x86_64 +#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_x86_64 +#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_x86_64 +#define helper_gvec_qrdmlsh_s32 helper_gvec_qrdmlsh_s32_x86_64 #define helper_gvec_sar8i helper_gvec_sar8i_x86_64 #define helper_gvec_sar16i helper_gvec_sar16i_x86_64 #define helper_gvec_sar32i helper_gvec_sar32i_x86_64