From 8a62878523b8590ea61839ac0df563f2e716808a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 1 Mar 2018 18:34:07 -0500 Subject: [PATCH] target-i386: Use ctpop helper Backports commit 4885c3c49531995d67e54907d01d5aa1350faaaf from qemu --- qemu/target-i386/cc_helper.c | 3 +++ qemu/target-i386/cpu.h | 1 + qemu/target-i386/ops_sse.h | 26 -------------------------- qemu/target-i386/ops_sse_header.h | 1 - qemu/target-i386/translate.c | 12 ++++++++++-- 5 files changed, 14 insertions(+), 29 deletions(-) diff --git a/qemu/target-i386/cc_helper.c b/qemu/target-i386/cc_helper.c index a8a04a34..159dda46 100644 --- a/qemu/target-i386/cc_helper.c +++ b/qemu/target-i386/cc_helper.c @@ -105,6 +105,8 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, return src1; case CC_OP_CLR: return CC_Z | CC_P; + case CC_OP_POPCNT: + return src1 ? 0 : CC_Z; case CC_OP_MULB: return compute_all_mulb(dst, src1); @@ -232,6 +234,7 @@ target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1, case CC_OP_LOGICL: case CC_OP_LOGICQ: case CC_OP_CLR: + case CC_OP_POPCNT: return 0; case CC_OP_EFLAGS: diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index ee386611..661634aa 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -768,6 +768,7 @@ typedef enum { CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest. */ CC_OP_CLR, /* Z set, all other flags clear. */ + CC_OP_POPCNT, /* Z via CC_SRC, all other flags clear. */ CC_OP_NB, } CCOp; diff --git a/qemu/target-i386/ops_sse.h b/qemu/target-i386/ops_sse.h index 0be7e068..f4be0296 100644 --- a/qemu/target-i386/ops_sse.h +++ b/qemu/target-i386/ops_sse.h @@ -2157,32 +2157,6 @@ target_ulong helper_crc32(uint32_t crc1, target_ulong msg, uint32_t len) return crc; } -#define POPMASK(i) ((target_ulong) -1 / ((1LL << (1 << i)) + 1)) -#define POPCOUNT(n, i) ((n & POPMASK(i)) + ((n >> (1 << i)) & POPMASK(i))) -target_ulong helper_popcnt(CPUX86State *env, target_ulong n, uint32_t type) -{ - CC_SRC = n ? 0 : CC_Z; - - n = POPCOUNT(n, 0); - n = POPCOUNT(n, 1); - n = POPCOUNT(n, 2); - n = POPCOUNT(n, 3); - if (type == 1) { - return n & 0xff; - } - - n = POPCOUNT(n, 4); -#ifndef TARGET_X86_64 - return n; -#else - if (type == 2) { - return n & 0xff; - } - - return POPCOUNT(n, 5); -#endif -} - void glue(helper_pclmulqdq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, uint32_t ctrl) { diff --git a/qemu/target-i386/ops_sse_header.h b/qemu/target-i386/ops_sse_header.h index 64c5857c..094aafc5 100644 --- a/qemu/target-i386/ops_sse_header.h +++ b/qemu/target-i386/ops_sse_header.h @@ -333,7 +333,6 @@ DEF_HELPER_4(glue(pcmpestrm, SUFFIX), void, env, Reg, Reg, i32) DEF_HELPER_4(glue(pcmpistri, SUFFIX), void, env, Reg, Reg, i32) DEF_HELPER_4(glue(pcmpistrm, SUFFIX), void, env, Reg, Reg, i32) DEF_HELPER_3(crc32, tl, i32, tl, i32) -DEF_HELPER_3(popcnt, tl, env, tl, i32) #endif /* AES-NI op helpers */ diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index a7b966f2..b4c68cb0 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -249,6 +249,7 @@ static const uint8_t cc_op_live[CC_OP_NB] = { USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, // CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest. */ 0, // CC_OP_CLR, /* Z set, all other flags clear. */ + USES_CC_SRC, // CC_OP_POPCNT, /* Z via CC_SRC, all other flags clear. */ #else [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, [CC_OP_EFLAGS] = USES_CC_SRC, @@ -267,6 +268,7 @@ static const uint8_t cc_op_live[CC_OP_NB] = { [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2, [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, [CC_OP_CLR] = 0, + [CC_OP_POPCNT] = USES_CC_SRC, #endif }; @@ -915,6 +917,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) case CC_OP_LOGICB: case CC_OP_LOGICW: case CC_OP_LOGICL: case CC_OP_LOGICQ: case CC_OP_CLR: + case CC_OP_POPCNT: return ccprepare_make(TCG_COND_NEVER, 0, 0, 0, -1, false, false); case CC_OP_INCB: case CC_OP_INCW: case CC_OP_INCL: case CC_OP_INCQ: @@ -981,6 +984,7 @@ static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) case CC_OP_ADCOX: return ccprepare_make(TCG_COND_NE, cpu_cc_src, 0, 0, CC_S, false, false); case CC_OP_CLR: + case CC_OP_POPCNT: return ccprepare_make(TCG_COND_NEVER, 0, 0, 0, -1, false, false); default: { @@ -1003,6 +1007,7 @@ static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) case CC_OP_ADCOX: return ccprepare_make(TCG_COND_NE, cpu_cc_src2, 0, 0, -1, false, true); case CC_OP_CLR: + case CC_OP_POPCNT: return ccprepare_make(TCG_COND_NEVER, 0, 0, 0, -1, false, false); default: gen_compute_eflags(s); @@ -1027,6 +1032,7 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) case CC_OP_ADCOX: return ccprepare_make(TCG_COND_NE, cpu_cc_src, 0, 0, CC_Z, false, false); case CC_OP_CLR: + case CC_OP_POPCNT: return ccprepare_make(TCG_COND_ALWAYS, 0, 0, 0, -1, false, false); default: { @@ -8926,10 +8932,12 @@ case 0x101: } gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); - gen_helper_popcnt(tcg_ctx, cpu_T0, cpu_env, cpu_T0, tcg_const_i32(tcg_ctx, ot)); + gen_extu(tcg_ctx, ot, cpu_T0); + tcg_gen_mov_tl(tcg_ctx, cpu_cc_src, cpu_T0); + tcg_gen_ctpop_tl(tcg_ctx, cpu_T0, cpu_T0); gen_op_mov_reg_v(tcg_ctx, ot, reg, cpu_T0); - set_cc_op(s, CC_OP_EFLAGS); + set_cc_op(s, CC_OP_POPCNT); break; case 0x10e: case 0x10f: /* 3DNow! instructions, ignore prefixes */