From 5f6e7bbdbdb5390ca4a222df3dda345d2ac399b4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 1 Mar 2018 18:21:05 -0500 Subject: [PATCH] tcg: Add opcode for ctpop The number of actual invocations of ctpop itself does not warrent an opcode, but it is very helpful for POWER7 to use in generating an expansion for ctz. Backports commit a768e4e99247911f00c5c0267c12d4e207d5f6cc from qemu --- qemu/aarch64.h | 4 ++++ qemu/aarch64eb.h | 4 ++++ qemu/arm.h | 4 ++++ qemu/armeb.h | 4 ++++ qemu/header_gen.py | 4 ++++ qemu/m68k.h | 4 ++++ qemu/mips.h | 4 ++++ qemu/mips64.h | 4 ++++ qemu/mips64el.h | 4 ++++ qemu/mipsel.h | 4 ++++ qemu/powerpc.h | 4 ++++ qemu/sparc.h | 4 ++++ qemu/sparc64.h | 4 ++++ qemu/tcg-runtime.c | 10 ++++++++++ qemu/tcg/aarch64/tcg-target.h | 2 ++ qemu/tcg/arm/tcg-target.h | 1 + qemu/tcg/i386/tcg-target.h | 2 ++ qemu/tcg/mips/tcg-target.h | 2 ++ qemu/tcg/optimize.c | 14 ++++++++++++++ qemu/tcg/ppc/tcg-target.h | 2 ++ qemu/tcg/s390/tcg-target.h | 2 ++ qemu/tcg/sparc/tcg-target.h | 2 ++ qemu/tcg/tcg-op.c | 29 +++++++++++++++++++++++++++++ qemu/tcg/tcg-op.h | 4 ++++ qemu/tcg/tcg-opc.h | 2 ++ qemu/tcg/tcg-runtime.h | 2 ++ qemu/tcg/tcg.h | 3 ++- qemu/x86_64.h | 4 ++++ 28 files changed, 132 insertions(+), 1 deletion(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 498ee982..befd3245 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_aarch64 #define helper_clz_i32 helper_clz_i32_aarch64 #define helper_clz_i64 helper_clz_i64_aarch64 +#define helper_ctpop_i32 helper_ctpop_i32_aarch64 +#define helper_ctpop_i64 helper_ctpop_i64_aarch64 #define helper_ctz_i32 helper_ctz_i32_aarch64 #define helper_ctz_i64 helper_ctz_i64_aarch64 #define helper_cpsr_read helper_cpsr_read_aarch64 @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_aarch64 #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_aarch64 #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_aarch64 +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_aarch64 +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_aarch64 #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_aarch64 #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_aarch64 #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index abc22d1f..780b94fd 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_aarch64eb #define helper_clz_i32 helper_clz_i32_aarch64eb #define helper_clz_i64 helper_clz_i64_aarch64eb +#define helper_ctpop_i32 helper_ctpop_i32_aarch64eb +#define helper_ctpop_i64 helper_ctpop_i64_aarch64eb #define helper_ctz_i32 helper_ctz_i32_aarch64eb #define helper_ctz_i64 helper_ctz_i64_aarch64eb #define helper_cpsr_read helper_cpsr_read_aarch64eb @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_aarch64eb #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_aarch64eb #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_aarch64eb +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_aarch64eb +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_aarch64eb #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_aarch64eb #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_aarch64eb #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 451ca6f0..d066a655 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_arm #define helper_clz_i32 helper_clz_i32_arm #define helper_clz_i64 helper_clz_i64_arm +#define helper_ctpop_i32 helper_ctpop_i32_arm +#define helper_ctpop_i64 helper_ctpop_i64_arm #define helper_ctz_i32 helper_ctz_i32_arm #define helper_ctz_i64 helper_ctz_i64_arm #define helper_cpsr_read helper_cpsr_read_arm @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_arm #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_arm #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_arm +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_arm +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_arm #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_arm #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_arm #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 1c97d147..3d43ded8 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_armeb #define helper_clz_i32 helper_clz_i32_armeb #define helper_clz_i64 helper_clz_i64_armeb +#define helper_ctpop_i32 helper_ctpop_i32_armeb +#define helper_ctpop_i64 helper_ctpop_i64_armeb #define helper_ctz_i32 helper_ctz_i32_armeb #define helper_ctz_i64 helper_ctz_i64_armeb #define helper_cpsr_read helper_cpsr_read_armeb @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_armeb #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_armeb #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_armeb +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_armeb +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_armeb #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_armeb #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_armeb #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 2a45720b..e09b7864 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1574,6 +1574,8 @@ symbols = ( 'helper_clrsb_i64', 'helper_clz_i32', 'helper_clz_i64', + 'helper_ctpop_i32', + 'helper_ctpop_i64', 'helper_ctz_i32', 'helper_ctz_i64', 'helper_cpsr_read', @@ -3023,6 +3025,8 @@ symbols = ( 'tcg_gen_clz_i64', 'tcg_gen_clzi_i32', 'tcg_gen_clzi_i64', + 'tcg_gen_ctpop_i32', + 'tcg_gen_ctpop_i64', 'tcg_gen_ctz_i32', 'tcg_gen_ctz_i64', 'tcg_gen_ctzi_i32', diff --git a/qemu/m68k.h b/qemu/m68k.h index e45f827e..a8c755f7 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_m68k #define helper_clz_i32 helper_clz_i32_m68k #define helper_clz_i64 helper_clz_i64_m68k +#define helper_ctpop_i32 helper_ctpop_i32_m68k +#define helper_ctpop_i64 helper_ctpop_i64_m68k #define helper_ctz_i32 helper_ctz_i32_m68k #define helper_ctz_i64 helper_ctz_i64_m68k #define helper_cpsr_read helper_cpsr_read_m68k @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_m68k #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_m68k #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_m68k +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_m68k +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_m68k #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_m68k #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_m68k #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index c4dff822..4042d903 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_mips #define helper_clz_i32 helper_clz_i32_mips #define helper_clz_i64 helper_clz_i64_mips +#define helper_ctpop_i32 helper_ctpop_i32_mips +#define helper_ctpop_i64 helper_ctpop_i64_mips #define helper_ctz_i32 helper_ctz_i32_mips #define helper_ctz_i64 helper_ctz_i64_mips #define helper_cpsr_read helper_cpsr_read_mips @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_mips #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_mips #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_mips +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_mips +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_mips #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_mips #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_mips #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index e0c00d82..392de206 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_mips64 #define helper_clz_i32 helper_clz_i32_mips64 #define helper_clz_i64 helper_clz_i64_mips64 +#define helper_ctpop_i32 helper_ctpop_i32_mips64 +#define helper_ctpop_i64 helper_ctpop_i64_mips64 #define helper_ctz_i32 helper_ctz_i32_mips64 #define helper_ctz_i64 helper_ctz_i64_mips64 #define helper_cpsr_read helper_cpsr_read_mips64 @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_mips64 #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_mips64 #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_mips64 +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_mips64 +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_mips64 #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_mips64 #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_mips64 #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index a7839ea2..6c23dc66 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_mips64el #define helper_clz_i32 helper_clz_i32_mips64el #define helper_clz_i64 helper_clz_i64_mips64el +#define helper_ctpop_i32 helper_ctpop_i32_mips64el +#define helper_ctpop_i64 helper_ctpop_i64_mips64el #define helper_ctz_i32 helper_ctz_i32_mips64el #define helper_ctz_i64 helper_ctz_i64_mips64el #define helper_cpsr_read helper_cpsr_read_mips64el @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_mips64el #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_mips64el #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_mips64el +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_mips64el +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_mips64el #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_mips64el #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_mips64el #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 0a779c65..b7416513 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_mipsel #define helper_clz_i32 helper_clz_i32_mipsel #define helper_clz_i64 helper_clz_i64_mipsel +#define helper_ctpop_i32 helper_ctpop_i32_mipsel +#define helper_ctpop_i64 helper_ctpop_i64_mipsel #define helper_ctz_i32 helper_ctz_i32_mipsel #define helper_ctz_i64 helper_ctz_i64_mipsel #define helper_cpsr_read helper_cpsr_read_mipsel @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_mipsel #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_mipsel #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_mipsel +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_mipsel +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_mipsel #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_mipsel #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_mipsel #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 05c1b7e0..b9a15a7e 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_powerpc #define helper_clz_i32 helper_clz_i32_powerpc #define helper_clz_i64 helper_clz_i64_powerpc +#define helper_ctpop_i32 helper_ctpop_i32_powerpc +#define helper_ctpop_i64 helper_ctpop_i64_powerpc #define helper_ctz_i32 helper_ctz_i32_powerpc #define helper_ctz_i64 helper_ctz_i64_powerpc #define helper_cpsr_read helper_cpsr_read_powerpc @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_powerpc #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_powerpc #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_powerpc +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_powerpc +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_powerpc #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_powerpc #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_powerpc #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 4887977d..c0a8a7d3 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_sparc #define helper_clz_i32 helper_clz_i32_sparc #define helper_clz_i64 helper_clz_i64_sparc +#define helper_ctpop_i32 helper_ctpop_i32_sparc +#define helper_ctpop_i64 helper_ctpop_i64_sparc #define helper_ctz_i32 helper_ctz_i32_sparc #define helper_ctz_i64 helper_ctz_i64_sparc #define helper_cpsr_read helper_cpsr_read_sparc @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_sparc #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_sparc #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_sparc +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_sparc +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_sparc #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_sparc #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_sparc #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index d036b260..1e507bb1 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_sparc64 #define helper_clz_i32 helper_clz_i32_sparc64 #define helper_clz_i64 helper_clz_i64_sparc64 +#define helper_ctpop_i32 helper_ctpop_i32_sparc64 +#define helper_ctpop_i64 helper_ctpop_i64_sparc64 #define helper_ctz_i32 helper_ctz_i32_sparc64 #define helper_ctz_i64 helper_ctz_i64_sparc64 #define helper_cpsr_read helper_cpsr_read_sparc64 @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_sparc64 #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_sparc64 #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_sparc64 +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_sparc64 +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_sparc64 #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_sparc64 #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_sparc64 #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_sparc64 diff --git a/qemu/tcg-runtime.c b/qemu/tcg-runtime.c index 7aad5823..494ad3e0 100644 --- a/qemu/tcg-runtime.c +++ b/qemu/tcg-runtime.c @@ -132,6 +132,16 @@ uint64_t HELPER(clrsb_i64)(uint64_t arg) return clrsb64(arg); } +uint32_t HELPER(ctpop_i32)(uint32_t arg) +{ + return ctpop32(arg); +} + +uint64_t HELPER(ctpop_i64)(uint64_t arg) +{ + return ctpop64(arg); +} + void HELPER(exit_atomic)(CPUArchState *env) { cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); diff --git a/qemu/tcg/aarch64/tcg-target.h b/qemu/tcg/aarch64/tcg-target.h index 9d6b00fb..1a5ea238 100644 --- a/qemu/tcg/aarch64/tcg-target.h +++ b/qemu/tcg/aarch64/tcg-target.h @@ -64,6 +64,7 @@ typedef enum { #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_deposit_i32 1 #define TCG_TARGET_HAS_extract_i32 1 #define TCG_TARGET_HAS_sextract_i32 1 @@ -98,6 +99,7 @@ typedef enum { #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_deposit_i64 1 #define TCG_TARGET_HAS_extract_i64 1 #define TCG_TARGET_HAS_sextract_i64 1 diff --git a/qemu/tcg/arm/tcg-target.h b/qemu/tcg/arm/tcg-target.h index 73f9a573..0977aa07 100644 --- a/qemu/tcg/arm/tcg-target.h +++ b/qemu/tcg/arm/tcg-target.h @@ -113,6 +113,7 @@ extern bool use_idiv_instructions_rt; #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_clz_i32 use_armv5t_instructions #define TCG_TARGET_HAS_ctz_i32 use_armv7_instructions +#define TCG_TARGET_HAS_ctpop_i32 0 #define TCG_TARGET_HAS_deposit_i32 use_armv7_instructions #define TCG_TARGET_HAS_extract_i32 use_armv7_instructions #define TCG_TARGET_HAS_sextract_i32 use_armv7_instructions diff --git a/qemu/tcg/i386/tcg-target.h b/qemu/tcg/i386/tcg-target.h index 3a4f1c6c..76a42a67 100644 --- a/qemu/tcg/i386/tcg-target.h +++ b/qemu/tcg/i386/tcg-target.h @@ -95,6 +95,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_deposit_i32 1 #define TCG_TARGET_HAS_extract_i32 1 #define TCG_TARGET_HAS_sextract_i32 1 @@ -129,6 +130,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_deposit_i64 1 #define TCG_TARGET_HAS_extract_i64 1 #define TCG_TARGET_HAS_sextract_i64 0 diff --git a/qemu/tcg/mips/tcg-target.h b/qemu/tcg/mips/tcg-target.h index a680f16e..f46d64a3 100644 --- a/qemu/tcg/mips/tcg-target.h +++ b/qemu/tcg/mips/tcg-target.h @@ -165,6 +165,7 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions #define TCG_TARGET_HAS_clz_i32 use_mips32r2_instructions #define TCG_TARGET_HAS_ctz_i32 0 +#define TCG_TARGET_HAS_ctpop_i32 0 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_movcond_i64 use_movnz_instructions @@ -179,6 +180,7 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_rot_i64 use_mips32r2_instructions #define TCG_TARGET_HAS_clz_i64 use_mips32r2_instructions #define TCG_TARGET_HAS_ctz_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 0 #endif /* optional instructions automatically implemented */ diff --git a/qemu/tcg/optimize.c b/qemu/tcg/optimize.c index 9bebff30..a64d69cd 100644 --- a/qemu/tcg/optimize.c +++ b/qemu/tcg/optimize.c @@ -312,6 +312,12 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) case INDEX_op_ctz_i64: return x ? ctz64(x) : y; + case INDEX_op_ctpop_i32: + return ctpop32(x); + + case INDEX_op_ctpop_i64: + return ctpop64(x); + CASE_OP_32_64(ext8s): return (int8_t)x; @@ -929,6 +935,13 @@ void tcg_optimize(TCGContext *s) mask = temps[args[2]].mask | 63; break; + case INDEX_op_ctpop_i32: + mask = 32 | 31; + break; + case INDEX_op_ctpop_i64: + mask = 64 | 63; + break; + CASE_OP_32_64(setcond): case INDEX_op_setcond2_i32: mask = 1; @@ -1042,6 +1055,7 @@ void tcg_optimize(TCGContext *s) CASE_OP_32_64(ext8u): CASE_OP_32_64(ext16s): CASE_OP_32_64(ext16u): + CASE_OP_32_64(ctpop): case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: diff --git a/qemu/tcg/ppc/tcg-target.h b/qemu/tcg/ppc/tcg-target.h index 698a5990..1de1155a 100644 --- a/qemu/tcg/ppc/tcg-target.h +++ b/qemu/tcg/ppc/tcg-target.h @@ -70,6 +70,7 @@ typedef enum { #define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_clz_i32 0 #define TCG_TARGET_HAS_ctz_i32 0 +#define TCG_TARGET_HAS_ctpop_i32 0 #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_extract_i32 1 #define TCG_TARGET_HAS_sextract_i32 0 @@ -105,6 +106,7 @@ typedef enum { #define TCG_TARGET_HAS_nor_i64 1 #define TCG_TARGET_HAS_clz_i64 0 #define TCG_TARGET_HAS_ctz_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 0 #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/s390/tcg-target.h b/qemu/tcg/s390/tcg-target.h index 22500ba8..cbdd2a62 100644 --- a/qemu/tcg/s390/tcg-target.h +++ b/qemu/tcg/s390/tcg-target.h @@ -79,6 +79,7 @@ extern uint64_t s390_facilities; #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_clz_i32 0 #define TCG_TARGET_HAS_ctz_i32 0 +#define TCG_TARGET_HAS_ctpop_i32 0 #define TCG_TARGET_HAS_deposit_i32 (s390_facilities & FACILITY_GEN_INST_EXT) #define TCG_TARGET_HAS_extract_i32 (s390_facilities & FACILITY_GEN_INST_EXT) #define TCG_TARGET_HAS_sextract_i32 0 @@ -112,6 +113,7 @@ extern uint64_t s390_facilities; #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_clz_i64 (s390_facilities & FACILITY_EXT_IMM) #define TCG_TARGET_HAS_ctz_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 0 #define TCG_TARGET_HAS_deposit_i64 (s390_facilities & FACILITY_GEN_INST_EXT) #define TCG_TARGET_HAS_extract_i64 (s390_facilities & FACILITY_GEN_INST_EXT) #define TCG_TARGET_HAS_sextract_i64 0 diff --git a/qemu/tcg/sparc/tcg-target.h b/qemu/tcg/sparc/tcg-target.h index 5afd4440..992b5cc5 100644 --- a/qemu/tcg/sparc/tcg-target.h +++ b/qemu/tcg/sparc/tcg-target.h @@ -112,6 +112,7 @@ extern bool use_vis3_instructions; #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_clz_i32 0 #define TCG_TARGET_HAS_ctz_i32 0 +#define TCG_TARGET_HAS_ctpop_i32 0 #define TCG_TARGET_HAS_deposit_i32 0 #define TCG_TARGET_HAS_extract_i32 0 #define TCG_TARGET_HAS_sextract_i32 0 @@ -146,6 +147,7 @@ extern bool use_vis3_instructions; #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_clz_i64 0 #define TCG_TARGET_HAS_ctz_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_extract_i64 0 #define TCG_TARGET_HAS_sextract_i64 0 diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 2d9d5fc7..320a1f46 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -549,6 +549,21 @@ void tcg_gen_clrsb_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg) } } +void tcg_gen_ctpop_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1) +{ + if (TCG_TARGET_HAS_ctpop_i32) { + tcg_gen_op2_i32(s, INDEX_op_ctpop_i32, ret, arg1); + } else if (TCG_TARGET_HAS_ctpop_i64) { + TCGv_i64 t = tcg_temp_new_i64(s); + tcg_gen_extu_i32_i64(s, t, arg1); + tcg_gen_ctpop_i64(s, t, t); + tcg_gen_extrl_i64_i32(s, ret, t); + tcg_temp_free_i64(s, t); + } else { + gen_helper_ctpop_i32(s, ret, arg1); + } +} + void tcg_gen_rotl_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { if (TCG_TARGET_HAS_rot_i32) { @@ -1880,6 +1895,20 @@ void tcg_gen_clrsb_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg) } } +void tcg_gen_ctpop_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1) +{ + if (TCG_TARGET_HAS_ctpop_i64) { + tcg_gen_op2_i64(s, INDEX_op_ctpop_i64, ret, arg1); + } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) { + tcg_gen_ctpop_i32(s, TCGV_HIGH(ret), TCGV_HIGH(arg1)); + tcg_gen_ctpop_i32(s, TCGV_LOW(ret), TCGV_LOW(arg1)); + tcg_gen_add_i32(s, TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret)); + tcg_gen_movi_i32(s, TCGV_HIGH(ret), 0); + } else { + gen_helper_ctpop_i64(s, ret, arg1); + } +} + void tcg_gen_rotl_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { if (TCG_TARGET_HAS_rot_i64) { diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 37b5d7ca..0e09c616 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -299,6 +299,7 @@ void tcg_gen_ctz_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_clzi_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2); void tcg_gen_ctzi_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2); void tcg_gen_clrsb_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg); +void tcg_gen_ctpop_i32(TCGContext *s, TCGv_i32 a1, TCGv_i32 a2); void tcg_gen_rotl_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_rotli_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2); void tcg_gen_rotr_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2); @@ -479,6 +480,7 @@ void tcg_gen_ctz_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_clzi_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2); void tcg_gen_ctzi_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2); void tcg_gen_clrsb_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg); +void tcg_gen_ctpop_i64(TCGContext *s, TCGv_i64 a1, TCGv_i64 a2); void tcg_gen_rotl_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_rotli_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2); void tcg_gen_rotr_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); @@ -975,6 +977,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGContext *, TCGv_i64, TCGv, TCGv_i64, TCGArg #define tcg_gen_clzi_tl tcg_gen_clzi_i64 #define tcg_gen_ctzi_tl tcg_gen_ctzi_i64 #define tcg_gen_clrsb_tl tcg_gen_clrsb_i64 +#define tcg_gen_ctpop_tl tcg_gen_ctpop_i64 #define tcg_gen_rotl_tl tcg_gen_rotl_i64 #define tcg_gen_rotli_tl tcg_gen_rotli_i64 #define tcg_gen_rotr_tl tcg_gen_rotr_i64 @@ -1071,6 +1074,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGContext *, TCGv_i64, TCGv, TCGv_i64, TCGArg #define tcg_gen_clzi_tl tcg_gen_clzi_i32 #define tcg_gen_ctzi_tl tcg_gen_ctzi_i32 #define tcg_gen_clrsb_tl tcg_gen_clrsb_i32 +#define tcg_gen_ctpop_tl tcg_gen_ctpop_i32 #define tcg_gen_rotl_tl tcg_gen_rotl_i32 #define tcg_gen_rotli_tl tcg_gen_rotli_i32 #define tcg_gen_rotr_tl tcg_gen_rotr_i32 diff --git a/qemu/tcg/tcg-opc.h b/qemu/tcg/tcg-opc.h index a515317c..7ad3781c 100644 --- a/qemu/tcg/tcg-opc.h +++ b/qemu/tcg/tcg-opc.h @@ -111,6 +111,7 @@ DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32)) DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32)) DEF(clz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_clz_i32)) DEF(ctz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_ctz_i32)) +DEF(ctpop_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ctpop_i32)) DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT) DEF(movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT) @@ -181,6 +182,7 @@ DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64)) DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64)) DEF(clz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_clz_i64)) DEF(ctz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctz_i64)) +DEF(ctpop_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctpop_i64)) DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64)) DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64)) diff --git a/qemu/tcg/tcg-runtime.h b/qemu/tcg/tcg-runtime.h index 9b22d2bd..5de6989f 100644 --- a/qemu/tcg/tcg-runtime.h +++ b/qemu/tcg/tcg-runtime.h @@ -21,6 +21,8 @@ DEF_HELPER_FLAGS_2(clz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(ctz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64) +DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32) +DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env) diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 8d95ef9f..d303f826 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -116,6 +116,7 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_clz_i64 0 #define TCG_TARGET_HAS_ctz_i64 0 +#define TCG_TARGET_HAS_ctpop_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_extract_i64 0 #define TCG_TARGET_HAS_sextract_i64 0 @@ -1014,7 +1015,7 @@ static inline bool tcg_op_buf_full(TCGContext *tcg_ctx) } // UNICORN: Added -#define TCG_OP_DEFS_TABLE_SIZE 133 +#define TCG_OP_DEFS_TABLE_SIZE 135 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 f8a30c3f..9cfe2317 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1568,6 +1568,8 @@ #define helper_clrsb_i64 helper_clrsb_i64_x86_64 #define helper_clz_i32 helper_clz_i32_x86_64 #define helper_clz_i64 helper_clz_i64_x86_64 +#define helper_ctpop_i32 helper_ctpop_i32_x86_64 +#define helper_ctpop_i64 helper_ctpop_i64_x86_64 #define helper_ctz_i32 helper_ctz_i32_x86_64 #define helper_ctz_i64 helper_ctz_i64_x86_64 #define helper_cpsr_read helper_cpsr_read_x86_64 @@ -3017,6 +3019,8 @@ #define tcg_gen_clz_i64 tcg_gen_clz_i64_x86_64 #define tcg_gen_clzi_i32 tcg_gen_clzi_i32_x86_64 #define tcg_gen_clzi_i64 tcg_gen_clzi_i64_x86_64 +#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_x86_64 +#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_x86_64 #define tcg_gen_ctz_i32 tcg_gen_ctz_i32_x86_64 #define tcg_gen_ctz_i64 tcg_gen_ctz_i64_x86_64 #define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_x86_64