diff --git a/qemu/aarch64.h b/qemu/aarch64.h index befd3245..bb64e025 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_aarch64 #define have_bmi1 have_bmi1_aarch64 #define have_bmi2 have_bmi2_aarch64 +#define have_popcnt have_popcnt_aarch64 #define hcr_write hcr_write_aarch64 #define helper_access_check_cp_reg helper_access_check_cp_reg_aarch64 #define helper_add_saturate helper_add_saturate_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 780b94fd..f22a0dfc 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_aarch64eb #define have_bmi1 have_bmi1_aarch64eb #define have_bmi2 have_bmi2_aarch64eb +#define have_popcnt have_popcnt_aarch64eb #define hcr_write hcr_write_aarch64eb #define helper_access_check_cp_reg helper_access_check_cp_reg_aarch64eb #define helper_add_saturate helper_add_saturate_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index d066a655..85e3978d 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_arm #define have_bmi1 have_bmi1_arm #define have_bmi2 have_bmi2_arm +#define have_popcnt have_popcnt_arm #define hcr_write hcr_write_arm #define helper_access_check_cp_reg helper_access_check_cp_reg_arm #define helper_add_saturate helper_add_saturate_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 3d43ded8..616608de 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_armeb #define have_bmi1 have_bmi1_armeb #define have_bmi2 have_bmi2_armeb +#define have_popcnt have_popcnt_armeb #define hcr_write hcr_write_armeb #define helper_access_check_cp_reg helper_access_check_cp_reg_armeb #define helper_add_saturate helper_add_saturate_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index e09b7864..cd6943cd 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1398,6 +1398,7 @@ symbols = ( 'has_help_option', 'have_bmi1', 'have_bmi2', + 'have_popcnt', 'hcr_write', 'helper_access_check_cp_reg', 'helper_add_saturate', diff --git a/qemu/m68k.h b/qemu/m68k.h index a8c755f7..986b2648 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_m68k #define have_bmi1 have_bmi1_m68k #define have_bmi2 have_bmi2_m68k +#define have_popcnt have_popcnt_m68k #define hcr_write hcr_write_m68k #define helper_access_check_cp_reg helper_access_check_cp_reg_m68k #define helper_add_saturate helper_add_saturate_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 4042d903..5244987d 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_mips #define have_bmi1 have_bmi1_mips #define have_bmi2 have_bmi2_mips +#define have_popcnt have_popcnt_mips #define hcr_write hcr_write_mips #define helper_access_check_cp_reg helper_access_check_cp_reg_mips #define helper_add_saturate helper_add_saturate_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 392de206..89dfa38d 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_mips64 #define have_bmi1 have_bmi1_mips64 #define have_bmi2 have_bmi2_mips64 +#define have_popcnt have_popcnt_mips64 #define hcr_write hcr_write_mips64 #define helper_access_check_cp_reg helper_access_check_cp_reg_mips64 #define helper_add_saturate helper_add_saturate_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 6c23dc66..8b1a201b 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_mips64el #define have_bmi1 have_bmi1_mips64el #define have_bmi2 have_bmi2_mips64el +#define have_popcnt have_popcnt_mips64el #define hcr_write hcr_write_mips64el #define helper_access_check_cp_reg helper_access_check_cp_reg_mips64el #define helper_add_saturate helper_add_saturate_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index b7416513..97ddf1b1 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_mipsel #define have_bmi1 have_bmi1_mipsel #define have_bmi2 have_bmi2_mipsel +#define have_popcnt have_popcnt_mipsel #define hcr_write hcr_write_mipsel #define helper_access_check_cp_reg helper_access_check_cp_reg_mipsel #define helper_add_saturate helper_add_saturate_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index b9a15a7e..c2bfa9f1 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_powerpc #define have_bmi1 have_bmi1_powerpc #define have_bmi2 have_bmi2_powerpc +#define have_popcnt have_popcnt_powerpc #define hcr_write hcr_write_powerpc #define helper_access_check_cp_reg helper_access_check_cp_reg_powerpc #define helper_add_saturate helper_add_saturate_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index c0a8a7d3..c9df1da2 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_sparc #define have_bmi1 have_bmi1_sparc #define have_bmi2 have_bmi2_sparc +#define have_popcnt have_popcnt_sparc #define hcr_write hcr_write_sparc #define helper_access_check_cp_reg helper_access_check_cp_reg_sparc #define helper_add_saturate helper_add_saturate_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 1e507bb1..ed92ed5a 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_sparc64 #define have_bmi1 have_bmi1_sparc64 #define have_bmi2 have_bmi2_sparc64 +#define have_popcnt have_popcnt_sparc64 #define hcr_write hcr_write_sparc64 #define helper_access_check_cp_reg helper_access_check_cp_reg_sparc64 #define helper_add_saturate helper_add_saturate_sparc64 diff --git a/qemu/tcg/i386/tcg-target.h b/qemu/tcg/i386/tcg-target.h index 76a42a67..be17bf4f 100644 --- a/qemu/tcg/i386/tcg-target.h +++ b/qemu/tcg/i386/tcg-target.h @@ -76,6 +76,7 @@ typedef enum { #endif extern bool have_bmi1; +extern bool have_popcnt; /* optional instructions */ #define TCG_TARGET_HAS_div2_i32 1 @@ -95,7 +96,7 @@ extern bool have_bmi1; #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_clz_i32 1 #define TCG_TARGET_HAS_ctz_i32 1 -#define TCG_TARGET_HAS_ctpop_i32 0 +#define TCG_TARGET_HAS_ctpop_i32 have_popcnt #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_extract_i32 1 #define TCG_TARGET_HAS_sextract_i32 1 @@ -130,7 +131,7 @@ extern bool have_bmi1; #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_clz_i64 1 #define TCG_TARGET_HAS_ctz_i64 1 -#define TCG_TARGET_HAS_ctpop_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 have_popcnt #define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_extract_i64 1 #define TCG_TARGET_HAS_sextract_i64 0 diff --git a/qemu/tcg/i386/tcg-target.inc.c b/qemu/tcg/i386/tcg-target.inc.c index 4f83d7ad..abe7343a 100644 --- a/qemu/tcg/i386/tcg-target.inc.c +++ b/qemu/tcg/i386/tcg-target.inc.c @@ -139,9 +139,10 @@ static bool have_cmov; # define have_cmov 0 #endif -/* We need this symbol in tcg-target.h, and we can't properly conditionalize +/* We need these symbols in tcg-target.h, and we can't properly conditionalize it there. Therefore we always define the variable. */ bool have_bmi1; +bool have_popcnt; #if defined(CONFIG_CPUID_H) && defined(bit_BMI2) static bool have_bmi2; @@ -344,6 +345,7 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, #define OPC_MOVZBL (0xb6 | P_EXT) #define OPC_MOVZWL (0xb7 | P_EXT) #define OPC_POP_r32 (0x58) +#define OPC_POPCNT (0xb8 | P_EXT | P_SIMDF3) #define OPC_PUSH_r32 (0x50) #define OPC_PUSH_Iv (0x68) #define OPC_PUSH_Ib (0x6a) @@ -2175,6 +2177,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, OP_32_64(clz): tcg_out_clz(s, rexw, args[0], args[1], args[2], const_args[2]); break; + OP_32_64(ctpop): + tcg_out_modrm(s, OPC_POPCNT + rexw, a0, a1); + break; case INDEX_op_brcond_i32: tcg_out_brcond32(s, a2, a0, a1, const_args[1], arg_label(s, args[3]), 0); @@ -2486,6 +2491,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) case INDEX_op_extract_i32: case INDEX_op_extract_i64: case INDEX_op_sextract_i32: + case INDEX_op_ctpop_i32: + case INDEX_op_ctpop_i64: return &r_r; case INDEX_op_deposit_i32: @@ -2698,6 +2705,9 @@ static void tcg_target_init(TCGContext *s) /* MOVBE is only available on Intel Atom and Haswell CPUs, so we need to probe for it. */ s->have_movbe = (c & bit_MOVBE) != 0; +#endif +#ifdef bit_POPCNT + have_popcnt = (c & bit_POPCNT) != 0; #endif } diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 9cfe2317..d54b552f 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1392,6 +1392,7 @@ #define has_help_option has_help_option_x86_64 #define have_bmi1 have_bmi1_x86_64 #define have_bmi2 have_bmi2_x86_64 +#define have_popcnt have_popcnt_x86_64 #define hcr_write hcr_write_x86_64 #define helper_access_check_cp_reg helper_access_check_cp_reg_x86_64 #define helper_add_saturate helper_add_saturate_x86_64