On 10/14/23 03:01, Paolo Bonzini wrote:
+ [0x28] = X86_OP_ENTRY2(SUB, E,b, G,b), + [0x29] = X86_OP_ENTRY2(SUB, E,v, G,v), + [0x2A] = X86_OP_ENTRY2(SUB, G,b, E,b), + [0x2B] = X86_OP_ENTRY2(SUB, G,v, E,v), + [0x2C] = X86_OP_ENTRY2(SUB, 0,b, I,b), /* AL, Ib */ + [0x2D] = X86_OP_ENTRY2(SUB, 0,v, I,z), /* rAX, Iz */ + [0x2E] = {}, + [0x2F] = X86_OP_ENTRY0(DAS, chk(i64)), + + [0x38] = X86_OP_ENTRY2(SUB, E,b, G,b, nowb), + [0x39] = X86_OP_ENTRY2(SUB, E,v, G,v, nowb), + [0x3A] = X86_OP_ENTRY2(SUB, G,b, E,b, nowb), + [0x3B] = X86_OP_ENTRY2(SUB, G,v, E,v, nowb), + [0x3C] = X86_OP_ENTRY2(SUB, 0,b, I,b, nowb), /* AL, Ib */ + [0x3D] = X86_OP_ENTRY2(SUB, 0,v, I,z, nowb), /* rAX, Iz */ + [0x3E] = {}, + [0x3F] = X86_OP_ENTRY0(AAS, chk(i64)),
...
+ case X86_SPECIAL_NoWriteback: + decode.op[0].unit = X86_OP_SKIP; + break;
...
+static void gen_SUB(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) +{ + MemOp ot = decode->op[0].ot; + + if (s->prefix & PREFIX_LOCK) { + tcg_gen_neg_tl(s->T0, s->T1); + tcg_gen_atomic_fetch_add_tl(s->cc_srcT, s->A0, s->T0, + s->mem_index, ot | MO_LE); + tcg_gen_sub_tl(s->T0, s->cc_srcT, s->T1); + } else { + tcg_gen_mov_tl(s->cc_srcT, s->T0); + tcg_gen_sub_tl(s->T0, s->T0, s->T1); + } + prepare_update2_cc(decode, s, CC_OP_SUBB + ot); +}
Missing a check for CMP vs PREFIX_LOCK. I'm not sure where the best place to put that. Whether you use a chk bit or simply hard-code a check for (!lock || !skip). r~