mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 05:20:59 +00:00
target-i386: Use ctpop helper
Backports commit 4885c3c49531995d67e54907d01d5aa1350faaaf from qemu
This commit is contained in:
parent
d072ea48e7
commit
8a62878523
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue