diff --git a/qemu/aarch64.h b/qemu/aarch64.h index f40a298d..89e6cb51 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_aarch64 #define tcg_gen_smin_i32 tcg_gen_smin_i32_aarch64 #define tcg_gen_smin_i64 tcg_gen_smin_i64_aarch64 +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_aarch64 +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_aarch64 #define tcg_gen_st_i32 tcg_gen_st_i32_aarch64 #define tcg_gen_st_i64 tcg_gen_st_i64_aarch64 #define tcg_gen_st_vec tcg_gen_st_vec_aarch64 @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_aarch64 #define tcg_gen_umin_i32 tcg_gen_umin_i32_aarch64 #define tcg_gen_umin_i64 tcg_gen_umin_i64_aarch64 +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_aarch64 +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_aarch64 #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_aarch64 #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_aarch64 #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 4c91266f..b112cd83 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_aarch64eb #define tcg_gen_smin_i32 tcg_gen_smin_i32_aarch64eb #define tcg_gen_smin_i64 tcg_gen_smin_i64_aarch64eb +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_aarch64eb +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_aarch64eb #define tcg_gen_st_i32 tcg_gen_st_i32_aarch64eb #define tcg_gen_st_i64 tcg_gen_st_i64_aarch64eb #define tcg_gen_st_vec tcg_gen_st_vec_aarch64eb @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_aarch64eb #define tcg_gen_umin_i32 tcg_gen_umin_i32_aarch64eb #define tcg_gen_umin_i64 tcg_gen_umin_i64_aarch64eb +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_aarch64eb +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_aarch64eb #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_aarch64eb #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_aarch64eb #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 1879ae3f..0bd730d1 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_arm #define tcg_gen_smin_i32 tcg_gen_smin_i32_arm #define tcg_gen_smin_i64 tcg_gen_smin_i64_arm +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_arm +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_arm #define tcg_gen_st_i32 tcg_gen_st_i32_arm #define tcg_gen_st_i64 tcg_gen_st_i64_arm #define tcg_gen_st_vec tcg_gen_st_vec_arm @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_arm #define tcg_gen_umin_i32 tcg_gen_umin_i32_arm #define tcg_gen_umin_i64 tcg_gen_umin_i64_arm +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_arm +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_arm #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_arm #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_arm #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 00acc299..1df8399f 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_armeb #define tcg_gen_smin_i32 tcg_gen_smin_i32_armeb #define tcg_gen_smin_i64 tcg_gen_smin_i64_armeb +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_armeb +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_armeb #define tcg_gen_st_i32 tcg_gen_st_i32_armeb #define tcg_gen_st_i64 tcg_gen_st_i64_armeb #define tcg_gen_st_vec tcg_gen_st_vec_armeb @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_armeb #define tcg_gen_umin_i32 tcg_gen_umin_i32_armeb #define tcg_gen_umin_i64 tcg_gen_umin_i64_armeb +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_armeb +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_armeb #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_armeb #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_armeb #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 3bee22ee..daab1732 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2979,6 +2979,8 @@ symbols = ( 'tcg_gen_smax_i64', 'tcg_gen_smin_i32', 'tcg_gen_smin_i64', + 'tcg_gen_ssadd_vec', + 'tcg_gen_sssub_vec', 'tcg_gen_st_i32', 'tcg_gen_st_i64', 'tcg_gen_st_vec', @@ -2996,6 +2998,8 @@ symbols = ( 'tcg_gen_umax_i64', 'tcg_gen_umin_i32', 'tcg_gen_umin_i64', + 'tcg_gen_usadd_vec', + 'tcg_gen_ussub_vec', 'tcg_gen_vec_add8_i64', 'tcg_gen_vec_add16_i64', 'tcg_gen_vec_add32_i64', diff --git a/qemu/m68k.h b/qemu/m68k.h index cccdae2a..b39b3956 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_m68k #define tcg_gen_smin_i32 tcg_gen_smin_i32_m68k #define tcg_gen_smin_i64 tcg_gen_smin_i64_m68k +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_m68k +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_m68k #define tcg_gen_st_i32 tcg_gen_st_i32_m68k #define tcg_gen_st_i64 tcg_gen_st_i64_m68k #define tcg_gen_st_vec tcg_gen_st_vec_m68k @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_m68k #define tcg_gen_umin_i32 tcg_gen_umin_i32_m68k #define tcg_gen_umin_i64 tcg_gen_umin_i64_m68k +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_m68k +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_m68k #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_m68k #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_m68k #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 4c8676e0..7b397115 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_mips #define tcg_gen_smin_i32 tcg_gen_smin_i32_mips #define tcg_gen_smin_i64 tcg_gen_smin_i64_mips +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_mips +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_mips #define tcg_gen_st_i32 tcg_gen_st_i32_mips #define tcg_gen_st_i64 tcg_gen_st_i64_mips #define tcg_gen_st_vec tcg_gen_st_vec_mips @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_mips #define tcg_gen_umin_i32 tcg_gen_umin_i32_mips #define tcg_gen_umin_i64 tcg_gen_umin_i64_mips +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_mips +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_mips #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_mips #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_mips #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index b6ac57b1..3a46e3c0 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_mips64 #define tcg_gen_smin_i32 tcg_gen_smin_i32_mips64 #define tcg_gen_smin_i64 tcg_gen_smin_i64_mips64 +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_mips64 +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_mips64 #define tcg_gen_st_i32 tcg_gen_st_i32_mips64 #define tcg_gen_st_i64 tcg_gen_st_i64_mips64 #define tcg_gen_st_vec tcg_gen_st_vec_mips64 @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_mips64 #define tcg_gen_umin_i32 tcg_gen_umin_i32_mips64 #define tcg_gen_umin_i64 tcg_gen_umin_i64_mips64 +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_mips64 +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_mips64 #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_mips64 #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_mips64 #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 5781191b..c09e7017 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_mips64el #define tcg_gen_smin_i32 tcg_gen_smin_i32_mips64el #define tcg_gen_smin_i64 tcg_gen_smin_i64_mips64el +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_mips64el +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_mips64el #define tcg_gen_st_i32 tcg_gen_st_i32_mips64el #define tcg_gen_st_i64 tcg_gen_st_i64_mips64el #define tcg_gen_st_vec tcg_gen_st_vec_mips64el @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_mips64el #define tcg_gen_umin_i32 tcg_gen_umin_i32_mips64el #define tcg_gen_umin_i64 tcg_gen_umin_i64_mips64el +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_mips64el +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_mips64el #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_mips64el #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_mips64el #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 1ed05dd1..4666c97f 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_mipsel #define tcg_gen_smin_i32 tcg_gen_smin_i32_mipsel #define tcg_gen_smin_i64 tcg_gen_smin_i64_mipsel +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_mipsel +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_mipsel #define tcg_gen_st_i32 tcg_gen_st_i32_mipsel #define tcg_gen_st_i64 tcg_gen_st_i64_mipsel #define tcg_gen_st_vec tcg_gen_st_vec_mipsel @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_mipsel #define tcg_gen_umin_i32 tcg_gen_umin_i32_mipsel #define tcg_gen_umin_i64 tcg_gen_umin_i64_mipsel +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_mipsel +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_mipsel #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_mipsel #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_mipsel #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 21fbcfc7..c72907b6 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_powerpc #define tcg_gen_smin_i32 tcg_gen_smin_i32_powerpc #define tcg_gen_smin_i64 tcg_gen_smin_i64_powerpc +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_powerpc +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_powerpc #define tcg_gen_st_i32 tcg_gen_st_i32_powerpc #define tcg_gen_st_i64 tcg_gen_st_i64_powerpc #define tcg_gen_st_vec tcg_gen_st_vec_powerpc @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_powerpc #define tcg_gen_umin_i32 tcg_gen_umin_i32_powerpc #define tcg_gen_umin_i64 tcg_gen_umin_i64_powerpc +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_powerpc +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_powerpc #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_powerpc #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_powerpc #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index b6ce450d..0df067a7 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_sparc #define tcg_gen_smin_i32 tcg_gen_smin_i32_sparc #define tcg_gen_smin_i64 tcg_gen_smin_i64_sparc +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_sparc +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_sparc #define tcg_gen_st_i32 tcg_gen_st_i32_sparc #define tcg_gen_st_i64 tcg_gen_st_i64_sparc #define tcg_gen_st_vec tcg_gen_st_vec_sparc @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_sparc #define tcg_gen_umin_i32 tcg_gen_umin_i32_sparc #define tcg_gen_umin_i64 tcg_gen_umin_i64_sparc +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_sparc +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_sparc #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_sparc #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_sparc #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index dfa878ce..9fd9aea8 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_sparc64 #define tcg_gen_smin_i32 tcg_gen_smin_i32_sparc64 #define tcg_gen_smin_i64 tcg_gen_smin_i64_sparc64 +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_sparc64 +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_sparc64 #define tcg_gen_st_i32 tcg_gen_st_i32_sparc64 #define tcg_gen_st_i64 tcg_gen_st_i64_sparc64 #define tcg_gen_st_vec tcg_gen_st_vec_sparc64 @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_sparc64 #define tcg_gen_umin_i32 tcg_gen_umin_i32_sparc64 #define tcg_gen_umin_i64 tcg_gen_umin_i64_sparc64 +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_sparc64 +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_sparc64 #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_sparc64 #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_sparc64 #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_sparc64 diff --git a/qemu/tcg/README b/qemu/tcg/README index 7eebcfff..94488ca3 100644 --- a/qemu/tcg/README +++ b/qemu/tcg/README @@ -549,6 +549,15 @@ E.g. VECL=1 -> 64 << 1 -> v128, and VECE=2 -> 1 << 2 -> i32. Similarly, v0 = -v1. +* ssadd_vec: +* sssub_vec: +* usadd_vec: +* ussub_vec: + + Signed and unsigned saturating addition and subtraction. If the true + result is not representable within the element type, the element is + set to the minimum or maximum value for the type. + * and_vec v0, v1, v2 * or_vec v0, v1, v2 * xor_vec v0, v1, v2 diff --git a/qemu/tcg/aarch64/tcg-target.h b/qemu/tcg/aarch64/tcg-target.h index f966a4fc..98556bcf 100644 --- a/qemu/tcg/aarch64/tcg-target.h +++ b/qemu/tcg/aarch64/tcg-target.h @@ -135,6 +135,7 @@ typedef enum { #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 +#define TCG_TARGET_HAS_sat_vec 0 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 diff --git a/qemu/tcg/i386/tcg-target.h b/qemu/tcg/i386/tcg-target.h index 9d6446ac..bcb9af8c 100644 --- a/qemu/tcg/i386/tcg-target.h +++ b/qemu/tcg/i386/tcg-target.h @@ -218,6 +218,7 @@ extern bool have_avx2; #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 +#define TCG_TARGET_HAS_sat_vec 0 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ diff --git a/qemu/tcg/tcg-op-gvec.c b/qemu/tcg/tcg-op-gvec.c index 3d2a3c12..f71fe73b 100644 --- a/qemu/tcg/tcg-op-gvec.c +++ b/qemu/tcg/tcg-op-gvec.c @@ -1679,10 +1679,22 @@ void tcg_gen_gvec_ssadd(TCGContext *s, unsigned vece, uint32_t dofs, uint32_t ao uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { - { .fno = gen_helper_gvec_ssadd8, .vece = MO_8 }, - { .fno = gen_helper_gvec_ssadd16, .vece = MO_16 }, - { .fno = gen_helper_gvec_ssadd32, .vece = MO_32 }, - { .fno = gen_helper_gvec_ssadd64, .vece = MO_64 } + { .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd8, + .opc = INDEX_op_ssadd_vec, + .vece = MO_8 }, + { .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd16, + .opc = INDEX_op_ssadd_vec, + .vece = MO_16 }, + { .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd32, + .opc = INDEX_op_ssadd_vec, + .vece = MO_32 }, + { .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd64, + .opc = INDEX_op_ssadd_vec, + .vece = MO_64 }, }; tcg_debug_assert(vece <= MO_64); tcg_gen_gvec_3(s, dofs, aofs, bofs, oprsz, maxsz, &g[vece]); @@ -1692,16 +1704,28 @@ void tcg_gen_gvec_sssub(TCGContext *s, unsigned vece, uint32_t dofs, uint32_t ao uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { - { .fno = gen_helper_gvec_sssub8, .vece = MO_8 }, - { .fno = gen_helper_gvec_sssub16, .vece = MO_16 }, - { .fno = gen_helper_gvec_sssub32, .vece = MO_32 }, - { .fno = gen_helper_gvec_sssub64, .vece = MO_64 } + { .fniv = tcg_gen_sssub_vec, + .fno = gen_helper_gvec_sssub8, + .opc = INDEX_op_sssub_vec, + .vece = MO_8 }, + { .fniv = tcg_gen_sssub_vec, + .fno = gen_helper_gvec_sssub16, + .opc = INDEX_op_sssub_vec, + .vece = MO_16 }, + { .fniv = tcg_gen_sssub_vec, + .fno = gen_helper_gvec_sssub32, + .opc = INDEX_op_sssub_vec, + .vece = MO_32 }, + { .fniv = tcg_gen_sssub_vec, + .fno = gen_helper_gvec_sssub64, + .opc = INDEX_op_sssub_vec, + .vece = MO_64 }, }; tcg_debug_assert(vece <= MO_64); tcg_gen_gvec_3(s, dofs, aofs, bofs, oprsz, maxsz, &g[vece]); } -static void tcg_gen_vec_usadd32_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b) +static void tcg_gen_usadd_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b) { TCGv_i32 max = tcg_const_i32(s, -1); tcg_gen_add_i32(s, d, a, b); @@ -1709,7 +1733,7 @@ static void tcg_gen_vec_usadd32_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_ tcg_temp_free_i32(s, max); } -static void tcg_gen_vec_usadd32_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) +static void tcg_gen_usadd_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) { TCGv_i64 max = tcg_const_i64(s, -1); tcg_gen_add_i64(s, d, a, b); @@ -1721,20 +1745,30 @@ void tcg_gen_gvec_usadd(TCGContext *s, unsigned vece, uint32_t dofs, uint32_t ao uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { - { .fno = gen_helper_gvec_usadd8, .vece = MO_8 }, - { .fno = gen_helper_gvec_usadd16, .vece = MO_16 }, - { .fni4 = tcg_gen_vec_usadd32_i32, + { .fniv = tcg_gen_usadd_vec, + .fno = gen_helper_gvec_usadd8, + .opc = INDEX_op_usadd_vec, + .vece = MO_8 }, + { .fniv = tcg_gen_usadd_vec, + .fno = gen_helper_gvec_usadd16, + .opc = INDEX_op_usadd_vec, + .vece = MO_16 }, + { .fni4 = tcg_gen_usadd_i32, + .fniv = tcg_gen_usadd_vec, .fno = gen_helper_gvec_usadd32, + .opc = INDEX_op_usadd_vec, .vece = MO_32 }, - { .fni8 = tcg_gen_vec_usadd32_i64, + { .fni8 = tcg_gen_usadd_i64, + .fniv = tcg_gen_usadd_vec, .fno = gen_helper_gvec_usadd64, + .opc = INDEX_op_usadd_vec, .vece = MO_64 } }; tcg_debug_assert(vece <= MO_64); tcg_gen_gvec_3(s, dofs, aofs, bofs, oprsz, maxsz, &g[vece]); } -static void tcg_gen_vec_ussub32_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b) +static void tcg_gen_ussub_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b) { TCGv_i32 min = tcg_const_i32(s, 0); tcg_gen_sub_i32(s, d, a, b); @@ -1742,7 +1776,7 @@ static void tcg_gen_vec_ussub32_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_ tcg_temp_free_i32(s, min); } -static void tcg_gen_vec_ussub32_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) +static void tcg_gen_ussub_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) { TCGv_i64 min = tcg_const_i64(s, 0); tcg_gen_sub_i64(s, d, a, b); @@ -1754,13 +1788,23 @@ void tcg_gen_gvec_ussub(TCGContext *s, unsigned vece, uint32_t dofs, uint32_t ao uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { - { .fno = gen_helper_gvec_ussub8, .vece = MO_8 }, - { .fno = gen_helper_gvec_ussub16, .vece = MO_16 }, - { .fni4 = tcg_gen_vec_ussub32_i32, + { .fniv = tcg_gen_ussub_vec, + .fno = gen_helper_gvec_ussub8, + .opc = INDEX_op_ussub_vec, + .vece = MO_8 }, + { .fniv = tcg_gen_ussub_vec, + .fno = gen_helper_gvec_ussub16, + .opc = INDEX_op_ussub_vec, + .vece = MO_16 }, + { .fni4 = tcg_gen_ussub_i32, + .fniv = tcg_gen_ussub_vec, .fno = gen_helper_gvec_ussub32, + .opc = INDEX_op_ussub_vec, .vece = MO_32 }, - { .fni8 = tcg_gen_vec_ussub32_i64, + { .fni8 = tcg_gen_ussub_i64, + .fniv = tcg_gen_ussub_vec, .fno = gen_helper_gvec_ussub64, + .opc = INDEX_op_ussub_vec, .vece = MO_64 } }; tcg_debug_assert(vece <= MO_64); diff --git a/qemu/tcg/tcg-op-vec.c b/qemu/tcg/tcg-op-vec.c index c7a1c04a..03f07a78 100644 --- a/qemu/tcg/tcg-op-vec.c +++ b/qemu/tcg/tcg-op-vec.c @@ -387,7 +387,8 @@ void tcg_gen_cmp_vec(TCGContext *s, TCGCond cond, unsigned vece, } } -void tcg_gen_mul_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +static void do_op3(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, + TCGv_vec b, TCGOpcode opc) { TCGTemp *rt = tcgv_vec_temp(s, r); TCGTemp *at = tcgv_vec_temp(s, a); @@ -400,11 +401,36 @@ void tcg_gen_mul_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_ tcg_debug_assert(at->base_type >= type); tcg_debug_assert(bt->base_type >= type); - can = tcg_can_emit_vec_op(INDEX_op_mul_vec, type, vece); + can = tcg_can_emit_vec_op(opc, type, vece); if (can > 0) { - vec_gen_3(s, INDEX_op_mul_vec, type, vece, ri, ai, bi); + vec_gen_3(s, opc, type, vece, ri, ai, bi); } else { tcg_debug_assert(can < 0); - tcg_expand_vec_op(s, INDEX_op_mul_vec, type, vece, ri, ai, bi); + tcg_expand_vec_op(s, opc, type, vece, ri, ai, bi); } } + +void tcg_gen_mul_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +{ + do_op3(s, vece, r, a, b, INDEX_op_mul_vec); +} + +void tcg_gen_ssadd_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +{ + do_op3(s, vece, r, a, b, INDEX_op_ssadd_vec); +} + +void tcg_gen_usadd_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +{ + do_op3(s, vece, r, a, b, INDEX_op_usadd_vec); +} + +void tcg_gen_sssub_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +{ + do_op3(s, vece, r, a, b, INDEX_op_sssub_vec); +} + +void tcg_gen_ussub_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) +{ + do_op3(s, vece, r, a, b, INDEX_op_ussub_vec); +} diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 3ff62e20..db4a5cf9 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -975,6 +975,10 @@ void tcg_gen_nor_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_v void tcg_gen_eqv_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_not_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a); void tcg_gen_neg_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a); +void tcg_gen_ssadd_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_usadd_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_sssub_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_ussub_vec(TCGContext *s, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_shli_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i); void tcg_gen_shri_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i); diff --git a/qemu/tcg/tcg-opc.h b/qemu/tcg/tcg-opc.h index 4dd37c60..9656b05b 100644 --- a/qemu/tcg/tcg-opc.h +++ b/qemu/tcg/tcg-opc.h @@ -226,6 +226,10 @@ DEF(add_vec, 1, 2, 0, IMPLVEC) DEF(sub_vec, 1, 2, 0, IMPLVEC) DEF(mul_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_mul_vec)) DEF(neg_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_neg_vec)) +DEF(ssadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(usadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(sssub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(ussub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) DEF(and_vec, 1, 2, 0, IMPLVEC) DEF(or_vec, 1, 2, 0, IMPLVEC) diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 2108e5b0..e34c3dde 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -1049,6 +1049,11 @@ bool tcg_op_supported(TCGOpcode op) case INDEX_op_shrv_vec: case INDEX_op_sarv_vec: return have_vec && TCG_TARGET_HAS_shv_vec; + case INDEX_op_ssadd_vec: + case INDEX_op_usadd_vec: + case INDEX_op_sssub_vec: + case INDEX_op_ussub_vec: + return have_vec && TCG_TARGET_HAS_sat_vec; default: tcg_debug_assert(op > INDEX_op_last_generic && op < NB_OPS); diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 57f67c9a..e2ece0e6 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -186,6 +186,7 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_shs_vec 0 #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_mul_vec 0 +#define TCG_TARGET_HAS_sat_vec 0 #else #define TCG_TARGET_MAYBE_vec 1 #endif @@ -1153,7 +1154,7 @@ static inline TCGv_ptr tcg_temp_local_new_ptr(TCGContext *s) } // UNICORN: Added -#define TCG_OP_DEFS_TABLE_SIZE 171 +#define TCG_OP_DEFS_TABLE_SIZE 175 extern const TCGOpDef tcg_op_defs_org[TCG_OP_DEFS_TABLE_SIZE]; typedef struct TCGTargetOpDef { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 2c927007..fbe22c70 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2973,6 +2973,8 @@ #define tcg_gen_smax_i64 tcg_gen_smax_i64_x86_64 #define tcg_gen_smin_i32 tcg_gen_smin_i32_x86_64 #define tcg_gen_smin_i64 tcg_gen_smin_i64_x86_64 +#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_x86_64 +#define tcg_gen_sssub_vec tcg_gen_sssub_vec_x86_64 #define tcg_gen_st_i32 tcg_gen_st_i32_x86_64 #define tcg_gen_st_i64 tcg_gen_st_i64_x86_64 #define tcg_gen_st_vec tcg_gen_st_vec_x86_64 @@ -2990,6 +2992,8 @@ #define tcg_gen_umax_i64 tcg_gen_umax_i64_x86_64 #define tcg_gen_umin_i32 tcg_gen_umin_i32_x86_64 #define tcg_gen_umin_i64 tcg_gen_umin_i64_x86_64 +#define tcg_gen_usadd_vec tcg_gen_usadd_vec_x86_64 +#define tcg_gen_ussub_vec tcg_gen_ussub_vec_x86_64 #define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_x86_64 #define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_x86_64 #define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_x86_64