Revision | 993508e43e6d180e9ba9b747a9657eac69aec5bb (tree) |
---|---|
Zeit | 2017-01-11 01:49:59 |
Autor | Richard Henderson <rth@twid...> |
Commiter | Richard Henderson |
tcg/i386: Handle ctpop opcode
Signed-off-by: Richard Henderson <rth@twiddle.net>
@@ -76,6 +76,7 @@ typedef enum { | ||
76 | 76 | #endif |
77 | 77 | |
78 | 78 | extern bool have_bmi1; |
79 | +extern bool have_popcnt; | |
79 | 80 | |
80 | 81 | /* optional instructions */ |
81 | 82 | #define TCG_TARGET_HAS_div2_i32 1 |
@@ -95,7 +96,7 @@ extern bool have_bmi1; | ||
95 | 96 | #define TCG_TARGET_HAS_nor_i32 0 |
96 | 97 | #define TCG_TARGET_HAS_clz_i32 1 |
97 | 98 | #define TCG_TARGET_HAS_ctz_i32 1 |
98 | -#define TCG_TARGET_HAS_ctpop_i32 0 | |
99 | +#define TCG_TARGET_HAS_ctpop_i32 have_popcnt | |
99 | 100 | #define TCG_TARGET_HAS_deposit_i32 1 |
100 | 101 | #define TCG_TARGET_HAS_extract_i32 1 |
101 | 102 | #define TCG_TARGET_HAS_sextract_i32 1 |
@@ -130,7 +131,7 @@ extern bool have_bmi1; | ||
130 | 131 | #define TCG_TARGET_HAS_nor_i64 0 |
131 | 132 | #define TCG_TARGET_HAS_clz_i64 1 |
132 | 133 | #define TCG_TARGET_HAS_ctz_i64 1 |
133 | -#define TCG_TARGET_HAS_ctpop_i64 0 | |
134 | +#define TCG_TARGET_HAS_ctpop_i64 have_popcnt | |
134 | 135 | #define TCG_TARGET_HAS_deposit_i64 1 |
135 | 136 | #define TCG_TARGET_HAS_extract_i64 1 |
136 | 137 | #define TCG_TARGET_HAS_sextract_i64 0 |
@@ -130,9 +130,10 @@ static bool have_movbe; | ||
130 | 130 | # define have_movbe 0 |
131 | 131 | #endif |
132 | 132 | |
133 | -/* We need this symbol in tcg-target.h, and we can't properly conditionalize | |
133 | +/* We need these symbols in tcg-target.h, and we can't properly conditionalize | |
134 | 134 | it there. Therefore we always define the variable. */ |
135 | 135 | bool have_bmi1; |
136 | +bool have_popcnt; | |
136 | 137 | |
137 | 138 | #if defined(CONFIG_CPUID_H) && defined(bit_BMI2) |
138 | 139 | static bool have_bmi2; |
@@ -337,6 +338,7 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, | ||
337 | 338 | #define OPC_MOVZBL (0xb6 | P_EXT) |
338 | 339 | #define OPC_MOVZWL (0xb7 | P_EXT) |
339 | 340 | #define OPC_POP_r32 (0x58) |
341 | +#define OPC_POPCNT (0xb8 | P_EXT | P_SIMDF3) | |
340 | 342 | #define OPC_PUSH_r32 (0x50) |
341 | 343 | #define OPC_PUSH_Iv (0x68) |
342 | 344 | #define OPC_PUSH_Ib (0x6a) |
@@ -2083,6 +2085,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, | ||
2083 | 2085 | OP_32_64(clz): |
2084 | 2086 | tcg_out_clz(s, rexw, args[0], args[1], args[2], const_args[2]); |
2085 | 2087 | break; |
2088 | + OP_32_64(ctpop): | |
2089 | + tcg_out_modrm(s, OPC_POPCNT + rexw, a0, a1); | |
2090 | + break; | |
2086 | 2091 | |
2087 | 2092 | case INDEX_op_brcond_i32: |
2088 | 2093 | tcg_out_brcond32(s, a2, a0, a1, const_args[1], arg_label(args[3]), 0); |
@@ -2398,6 +2403,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) | ||
2398 | 2403 | case INDEX_op_extract_i32: |
2399 | 2404 | case INDEX_op_extract_i64: |
2400 | 2405 | case INDEX_op_sextract_i32: |
2406 | + case INDEX_op_ctpop_i32: | |
2407 | + case INDEX_op_ctpop_i64: | |
2401 | 2408 | return &r_r; |
2402 | 2409 | |
2403 | 2410 | case INDEX_op_deposit_i32: |
@@ -2602,6 +2609,9 @@ static void tcg_target_init(TCGContext *s) | ||
2602 | 2609 | need to probe for it. */ |
2603 | 2610 | have_movbe = (c & bit_MOVBE) != 0; |
2604 | 2611 | #endif |
2612 | +#ifdef bit_POPCNT | |
2613 | + have_popcnt = (c & bit_POPCNT) != 0; | |
2614 | +#endif | |
2605 | 2615 | } |
2606 | 2616 | |
2607 | 2617 | if (max >= 7) { |