BSF and BSR currently pass their source as operand 0 and the old destination as operand 2. This nonstandard order was needed so that the source could use zextT0.
Per-operand extensions now let operand 2 use zextT1, so that BSF and BSR can use the normal X86_OP_ENTRY2. Reviewed-by: Richard Henderson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> --- target/i386/tcg/decode-new.c.inc | 18 ++++++++---------- target/i386/tcg/emit.c.inc | 12 +++++------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 07a627af5cf..3acac68977d 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -674,12 +674,11 @@ static void decode_0FB8(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui static void decode_0FBC(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) { - /* For BSF, pass 2op as the third operand so that we can use zextT0 */ static const X86OpEntry opcodes_0FBC[4] = { - X86_OP_ENTRY3(BSF, G,v, E,v, 2op,v, zextT0), - X86_OP_ENTRY3(BSF, G,v, E,v, 2op,v, zextT0), /* 0x66 */ - X86_OP_ENTRYwr(TZCNT, G,v, E,v, zextT0), /* 0xf3 */ - X86_OP_ENTRY3(BSF, G,v, E,v, 2op,v, zextT0), /* 0xf2 */ + X86_OP_ENTRY2(BSF, G,v, E,v, zextT1), + X86_OP_ENTRY2(BSF, G,v, E,v, zextT1), /* 0x66 */ + X86_OP_ENTRYwr(TZCNT, G,v, E,v, zextT0), /* 0xf3 */ + X86_OP_ENTRY2(BSF, G,v, E,v, zextT1), /* 0xf2 */ }; if (!(s->cpuid_ext3_features & CPUID_EXT3_ABM)) { *entry = opcodes_0FBC[0]; @@ -690,12 +689,11 @@ static void decode_0FBC(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui static void decode_0FBD(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) { - /* For BSR, pass 2op as the third operand so that we can use zextT0 */ static const X86OpEntry opcodes_0FBD[4] = { - X86_OP_ENTRY3(BSR, G,v, E,v, 2op,v, zextT0), - X86_OP_ENTRY3(BSR, G,v, E,v, 2op,v, zextT0), /* 0x66 */ - X86_OP_ENTRYwr(LZCNT, G,v, E,v, zextT0), /* 0xf3 */ - X86_OP_ENTRY3(BSR, G,v, E,v, 2op,v, zextT0), /* 0xf2 */ + X86_OP_ENTRY2(BSR, G,v, E,v, zextT1), + X86_OP_ENTRY2(BSR, G,v, E,v, zextT1), /* 0x66 */ + X86_OP_ENTRYwr(LZCNT, G,v, E,v, zextT0), /* 0xf3 */ + X86_OP_ENTRY2(BSR, G,v, E,v, zextT1), /* 0xf2 */ }; if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { *entry = opcodes_0FBD[0]; diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 54dc23ca624..abf40123035 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -1396,7 +1396,6 @@ static void gen_BOUND(DisasContext *s, X86DecodedInsn *decode) } } -/* Non-standard convention - on entry T0 is zero-extended input, T1 is the output. */ static void gen_BSF(DisasContext *s, X86DecodedInsn *decode) { MemOp ot = decode->op[0].ot; @@ -1404,7 +1403,7 @@ static void gen_BSF(DisasContext *s, X86DecodedInsn *decode) /* Only the Z bit is defined and it is related to the input. */ decode->cc_dst = tcg_temp_new(); decode->cc_op = CC_OP_LOGICB + ot; - tcg_gen_mov_tl(decode->cc_dst, s->T0); + tcg_gen_mov_tl(decode->cc_dst, s->T1); /* * The manual says that the output is undefined when the @@ -1412,10 +1411,9 @@ static void gen_BSF(DisasContext *s, X86DecodedInsn *decode) * real programs appear to depend on that. Accomplish this * by passing the output as the value to return upon zero. */ - tcg_gen_ctz_tl(s->T0, s->T0, s->T1); + tcg_gen_ctz_tl(s->T0, s->T1, s->T0); } -/* Non-standard convention - on entry T0 is zero-extended input, T1 is the output. */ static void gen_BSR(DisasContext *s, X86DecodedInsn *decode) { MemOp ot = decode->op[0].ot; @@ -1423,7 +1421,7 @@ static void gen_BSR(DisasContext *s, X86DecodedInsn *decode) /* Only the Z bit is defined and it is related to the input. */ decode->cc_dst = tcg_temp_new(); decode->cc_op = CC_OP_LOGICB + ot; - tcg_gen_mov_tl(decode->cc_dst, s->T0); + tcg_gen_mov_tl(decode->cc_dst, s->T1); /* * The manual says that the output is undefined when the @@ -1432,8 +1430,8 @@ static void gen_BSR(DisasContext *s, X86DecodedInsn *decode) * by passing the output as the value to return upon zero. * Plus, return the bit index of the first 1 bit. */ - tcg_gen_xori_tl(s->T1, s->T1, TARGET_LONG_BITS - 1); - tcg_gen_clz_tl(s->T0, s->T0, s->T1); + tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); + tcg_gen_clz_tl(s->T0, s->T1, s->T0); tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); } -- 2.55.0
