first step to fix precise eflags update in case of exception

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@293 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-06-30 10:11:50 +00:00
parent 8ef9a8ece3
commit 5797fa5d7e
4 changed files with 129 additions and 138 deletions

View File

@ -80,62 +80,34 @@ static inline int lshift(int x, int n)
/* operations with flags */ /* operations with flags */
void OPPROTO op_addl_T0_T1_cc(void) /* update flags with T0 and T1 (add/sub case) */
void OPPROTO op_update2_cc(void)
{ {
CC_SRC = T0; CC_SRC = T1;
T0 += T1;
CC_DST = T0; CC_DST = T0;
} }
void OPPROTO op_orl_T0_T1_cc(void) /* update flags with T0 (logic operation case) */
void OPPROTO op_update1_cc(void)
{ {
T0 |= T1;
CC_DST = T0; CC_DST = T0;
} }
void OPPROTO op_andl_T0_T1_cc(void) void OPPROTO op_update_neg_cc(void)
{ {
T0 &= T1; CC_SRC = -T0;
CC_DST = T0;
}
void OPPROTO op_subl_T0_T1_cc(void)
{
CC_SRC = T0;
T0 -= T1;
CC_DST = T0;
}
void OPPROTO op_xorl_T0_T1_cc(void)
{
T0 ^= T1;
CC_DST = T0; CC_DST = T0;
} }
void OPPROTO op_cmpl_T0_T1_cc(void) void OPPROTO op_cmpl_T0_T1_cc(void)
{ {
CC_SRC = T0; CC_SRC = T1;
CC_DST = T0 - T1; CC_DST = T0 - T1;
} }
void OPPROTO op_negl_T0_cc(void) void OPPROTO op_update_inc_cc(void)
{
CC_SRC = 0;
T0 = -T0;
CC_DST = T0;
}
void OPPROTO op_incl_T0_cc(void)
{ {
CC_SRC = cc_table[CC_OP].compute_c(); CC_SRC = cc_table[CC_OP].compute_c();
T0++;
CC_DST = T0;
}
void OPPROTO op_decl_T0_cc(void)
{
CC_SRC = cc_table[CC_OP].compute_c();
T0--;
CC_DST = T0; CC_DST = T0;
} }

View File

@ -86,7 +86,7 @@ void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void)
v = glue(ldu, SUFFIX)(DI_ADDR); v = glue(ldu, SUFFIX)(DI_ADDR);
inc = (DF << SHIFT); inc = (DF << SHIFT);
INC_DI(); INC_DI();
CC_SRC = EAX; CC_SRC = v;
CC_DST = EAX - v; CC_DST = EAX - v;
} }
@ -105,7 +105,7 @@ void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
if (v1 != v2) if (v1 != v2)
break; break;
} while (CX != 0); } while (CX != 0);
CC_SRC = v1; CC_SRC = v2;
CC_DST = v1 - v2; CC_DST = v1 - v2;
CC_OP = CC_OP_SUBB + SHIFT; CC_OP = CC_OP_SUBB + SHIFT;
} }
@ -127,7 +127,7 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void)
if (v1 == v2) if (v1 == v2)
break; break;
} while (CX != 0); } while (CX != 0);
CC_SRC = v1; CC_SRC = v2;
CC_DST = v1 - v2; CC_DST = v1 - v2;
CC_OP = CC_OP_SUBB + SHIFT; CC_OP = CC_OP_SUBB + SHIFT;
} }
@ -142,7 +142,7 @@ void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void)
inc = (DF << SHIFT); inc = (DF << SHIFT);
INC_SI(); INC_SI();
INC_DI(); INC_DI();
CC_SRC = v1; CC_SRC = v2;
CC_DST = v1 - v2; CC_DST = v1 - v2;
} }
@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
if (v1 != v2) if (v1 != v2)
break; break;
} while (CX != 0); } while (CX != 0);
CC_SRC = v1; CC_SRC = v2;
CC_DST = v1 - v2; CC_DST = v1 - v2;
CC_OP = CC_OP_SUBB + SHIFT; CC_OP = CC_OP_SUBB + SHIFT;
} }
@ -181,7 +181,7 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void)
if (v1 == v2) if (v1 == v2)
break; break;
} while (CX != 0); } while (CX != 0);
CC_SRC = v1; CC_SRC = v2;
CC_DST = v1 - v2; CC_DST = v1 - v2;
CC_OP = CC_OP_SUBB + SHIFT; CC_OP = CC_OP_SUBB + SHIFT;
} }

View File

@ -93,8 +93,8 @@ static int glue(compute_all_sub, SUFFIX)(void)
{ {
int cf, pf, af, zf, sf, of; int cf, pf, af, zf, sf, of;
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
pf = parity_table[(uint8_t)CC_DST]; pf = parity_table[(uint8_t)CC_DST];
af = (CC_DST ^ src1 ^ src2) & 0x10; af = (CC_DST ^ src1 ^ src2) & 0x10;
@ -107,8 +107,8 @@ static int glue(compute_all_sub, SUFFIX)(void)
static int glue(compute_c_sub, SUFFIX)(void) static int glue(compute_c_sub, SUFFIX)(void)
{ {
int src1, src2, cf; int src1, src2, cf;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
return cf; return cf;
} }
@ -117,8 +117,8 @@ static int glue(compute_all_sbb, SUFFIX)(void)
{ {
int cf, pf, af, zf, sf, of; int cf, pf, af, zf, sf, of;
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC + 1;
src2 = CC_SRC - CC_DST - 1; src2 = CC_SRC;
cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
pf = parity_table[(uint8_t)CC_DST]; pf = parity_table[(uint8_t)CC_DST];
af = (CC_DST ^ src1 ^ src2) & 0x10; af = (CC_DST ^ src1 ^ src2) & 0x10;
@ -131,8 +131,8 @@ static int glue(compute_all_sbb, SUFFIX)(void)
static int glue(compute_c_sbb, SUFFIX)(void) static int glue(compute_c_sbb, SUFFIX)(void)
{ {
int src1, src2, cf; int src1, src2, cf;
src1 = CC_SRC; src1 = CC_DST + CC_SRC + 1;
src2 = CC_SRC - CC_DST - 1; src2 = CC_SRC;
cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
return cf; return cf;
} }
@ -234,8 +234,8 @@ static int glue(compute_all_sar, SUFFIX)(void)
void OPPROTO glue(op_jb_sub, SUFFIX)(void) void OPPROTO glue(op_jb_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
if ((DATA_TYPE)src1 < (DATA_TYPE)src2) if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
JUMP_TB(PARAM1, 0, PARAM2); JUMP_TB(PARAM1, 0, PARAM2);
@ -256,8 +256,8 @@ void OPPROTO glue(op_jz_sub, SUFFIX)(void)
void OPPROTO glue(op_jbe_sub, SUFFIX)(void) void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
if ((DATA_TYPE)src1 <= (DATA_TYPE)src2) if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
JUMP_TB(PARAM1, 0, PARAM2); JUMP_TB(PARAM1, 0, PARAM2);
@ -278,8 +278,8 @@ void OPPROTO glue(op_js_sub, SUFFIX)(void)
void OPPROTO glue(op_jl_sub, SUFFIX)(void) void OPPROTO glue(op_jl_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
if ((DATA_STYPE)src1 < (DATA_STYPE)src2) if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
JUMP_TB(PARAM1, 0, PARAM2); JUMP_TB(PARAM1, 0, PARAM2);
@ -291,8 +291,8 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
void OPPROTO glue(op_jle_sub, SUFFIX)(void) void OPPROTO glue(op_jle_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
if ((DATA_STYPE)src1 <= (DATA_STYPE)src2) if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
JUMP_TB(PARAM1, 0, PARAM2); JUMP_TB(PARAM1, 0, PARAM2);
@ -361,8 +361,8 @@ void OPPROTO glue(op_jecxz, SUFFIX)(void)
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2); T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
} }
@ -375,8 +375,8 @@ void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void) void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2); T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
} }
@ -389,8 +389,8 @@ void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2); T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
} }
@ -398,8 +398,8 @@ void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
{ {
int src1, src2; int src1, src2;
src1 = CC_SRC; src1 = CC_DST + CC_SRC;
src2 = CC_SRC - CC_DST; src2 = CC_SRC;
T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
} }
@ -714,9 +714,7 @@ void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
{ {
int cf; int cf;
cf = cc_table[CC_OP].compute_c(); cf = cc_table[CC_OP].compute_c();
CC_SRC = T0;
T0 = T0 + T1 + cf; T0 = T0 + T1 + cf;
CC_DST = T0;
CC_OP = CC_OP_ADDB + SHIFT + cf * 3; CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
} }
@ -724,15 +722,13 @@ void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
{ {
int cf; int cf;
cf = cc_table[CC_OP].compute_c(); cf = cc_table[CC_OP].compute_c();
CC_SRC = T0;
T0 = T0 - T1 - cf; T0 = T0 - T1 - cf;
CC_DST = T0;
CC_OP = CC_OP_SUBB + SHIFT + cf * 3; CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
} }
void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void) void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
{ {
CC_SRC = EAX; CC_SRC = T0;
CC_DST = EAX - T0; CC_DST = EAX - T0;
if ((DATA_TYPE)CC_DST == 0) { if ((DATA_TYPE)CC_DST == 0) {
T0 = T1; T0 = T1;

View File

@ -365,14 +365,14 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = {
}; };
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = { static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
gen_op_addl_T0_T1_cc, NULL,
gen_op_orl_T0_T1_cc, gen_op_orl_T0_T1,
NULL, NULL,
NULL, NULL,
gen_op_andl_T0_T1_cc, gen_op_andl_T0_T1,
gen_op_subl_T0_T1_cc, NULL,
gen_op_xorl_T0_T1_cc, gen_op_xorl_T0_T1,
gen_op_cmpl_T0_T1_cc, NULL,
}; };
static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = { static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
@ -748,46 +748,83 @@ static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
gen_op_fdiv_STN_ST0, gen_op_fdiv_STN_ST0,
}; };
static void gen_op(DisasContext *s1, int op, int ot, int d, int s) /* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, int ot, int d)
{ {
if (d != OR_TMP0) GenOpFunc *gen_update_cc;
if (d != OR_TMP0) {
gen_op_mov_TN_reg[ot][0][d](); gen_op_mov_TN_reg[ot][0][d]();
if (s != OR_TMP1) } else {
gen_op_mov_TN_reg[ot][1][s](); gen_op_ld_T0_A0[ot]();
if (op == OP_ADCL || op == OP_SBBL) { }
switch(op) {
case OP_ADCL:
case OP_SBBL:
if (s1->cc_op != CC_OP_DYNAMIC) if (s1->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s1->cc_op); gen_op_set_cc_op(s1->cc_op);
gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
s1->cc_op = CC_OP_DYNAMIC; s1->cc_op = CC_OP_DYNAMIC;
} else { /* XXX: incorrect: CC_OP must also be modified AFTER memory access */
gen_update_cc = gen_op_update2_cc;
break;
case OP_ADDL:
gen_op_addl_T0_T1();
s1->cc_op = CC_OP_ADDB + ot;
gen_update_cc = gen_op_update2_cc;
break;
case OP_SUBL:
gen_op_subl_T0_T1();
s1->cc_op = CC_OP_SUBB + ot;
gen_update_cc = gen_op_update2_cc;
break;
default:
case OP_ANDL:
case OP_ORL:
case OP_XORL:
gen_op_arith_T0_T1_cc[op](); gen_op_arith_T0_T1_cc[op]();
s1->cc_op = cc_op_arithb[op] + ot; s1->cc_op = CC_OP_LOGICB + ot;
gen_update_cc = gen_op_update1_cc;
break;
case OP_CMPL:
gen_op_cmpl_T0_T1_cc();
s1->cc_op = CC_OP_SUBB + ot;
gen_update_cc = NULL;
break;
} }
if (d != OR_TMP0 && op != OP_CMPL) if (op != OP_CMPL) {
gen_op_mov_reg_T0[ot][d](); if (d != OR_TMP0)
} gen_op_mov_reg_T0[ot][d]();
else
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c) gen_op_st_T0_A0[ot]();
{ }
gen_op_movl_T1_im(c); /* the flags update must happen after the memory write (precise
gen_op(s1, op, ot, d, OR_TMP1); exception support) */
if (gen_update_cc)
gen_update_cc();
} }
/* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_inc(DisasContext *s1, int ot, int d, int c) static void gen_inc(DisasContext *s1, int ot, int d, int c)
{ {
if (d != OR_TMP0) if (d != OR_TMP0)
gen_op_mov_TN_reg[ot][0][d](); gen_op_mov_TN_reg[ot][0][d]();
else
gen_op_ld_T0_A0[ot]();
if (s1->cc_op != CC_OP_DYNAMIC) if (s1->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s1->cc_op); gen_op_set_cc_op(s1->cc_op);
if (c > 0) { if (c > 0) {
gen_op_incl_T0_cc(); gen_op_incl_T0();
s1->cc_op = CC_OP_INCB + ot; s1->cc_op = CC_OP_INCB + ot;
} else { } else {
gen_op_decl_T0_cc(); gen_op_decl_T0();
s1->cc_op = CC_OP_DECB + ot; s1->cc_op = CC_OP_DECB + ot;
} }
if (d != OR_TMP0) if (d != OR_TMP0)
gen_op_mov_reg_T0[ot][d](); gen_op_mov_reg_T0[ot][d]();
else
gen_op_st_T0_A0[ot]();
gen_op_update_inc_cc();
} }
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
@ -1459,15 +1496,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
rm = modrm & 7; rm = modrm & 7;
if (mod != 3) { if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_ld_T0_A0[ot]();
opreg = OR_TMP0; opreg = OR_TMP0;
} else { } else {
opreg = OR_EAX + rm; opreg = OR_EAX + rm;
} }
gen_op(s, op, ot, opreg, reg); gen_op_mov_TN_reg[ot][1][reg]();
if (mod != 3 && op != 7) { gen_op(s, op, ot, opreg);
gen_op_st_T0_A0[ot]();
}
break; break;
case 1: /* OP Gv, Ev */ case 1: /* OP Gv, Ev */
modrm = ldub(s->pc++); modrm = ldub(s->pc++);
@ -1477,15 +1511,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
if (mod != 3) { if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_ld_T1_A0[ot](); gen_op_ld_T1_A0[ot]();
opreg = OR_TMP1;
} else { } else {
opreg = OR_EAX + rm; gen_op_mov_TN_reg[ot][1][rm]();
} }
gen_op(s, op, ot, reg, opreg); gen_op(s, op, ot, reg);
break; break;
case 2: /* OP A, Iv */ case 2: /* OP A, Iv */
val = insn_get(s, ot); val = insn_get(s, ot);
gen_opi(s, op, ot, OR_EAX, val); gen_op_movl_T1_im(val);
gen_op(s, op, ot, OR_EAX);
break; break;
} }
} }
@ -1509,7 +1543,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
if (mod != 3) { if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_ld_T0_A0[ot]();
opreg = OR_TMP0; opreg = OR_TMP0;
} else { } else {
opreg = rm + OR_EAX; opreg = rm + OR_EAX;
@ -1525,11 +1558,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
val = (int8_t)insn_get(s, OT_BYTE); val = (int8_t)insn_get(s, OT_BYTE);
break; break;
} }
gen_op_movl_T1_im(val);
gen_opi(s, op, ot, opreg, val); gen_op(s, op, ot, opreg);
if (op != 7 && mod != 3) {
gen_op_st_T0_A0[ot]();
}
} }
break; break;
@ -1577,12 +1607,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
} }
break; break;
case 3: /* neg */ case 3: /* neg */
gen_op_negl_T0_cc(); gen_op_negl_T0();
if (mod != 3) { if (mod != 3) {
gen_op_st_T0_A0[ot](); gen_op_st_T0_A0[ot]();
} else { } else {
gen_op_mov_reg_T0[ot][rm](); gen_op_mov_reg_T0[ot][rm]();
} }
gen_op_update_neg_cc();
s->cc_op = CC_OP_SUBB + ot; s->cc_op = CC_OP_SUBB + ot;
break; break;
case 4: /* mul */ case 4: /* mul */
@ -1664,7 +1695,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
} }
if (mod != 3) { if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
if (op != 3 && op != 5) if (op >= 2 && op != 3 && op != 5)
gen_op_ld_T0_A0[ot](); gen_op_ld_T0_A0[ot]();
} else { } else {
gen_op_mov_TN_reg[ot][0][rm](); gen_op_mov_TN_reg[ot][0][rm]();
@ -1672,18 +1703,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
switch(op) { switch(op) {
case 0: /* inc Ev */ case 0: /* inc Ev */
gen_inc(s, ot, OR_TMP0, 1);
if (mod != 3) if (mod != 3)
gen_op_st_T0_A0[ot](); opreg = OR_TMP0;
else else
gen_op_mov_reg_T0[ot][rm](); opreg = rm;
gen_inc(s, ot, opreg, 1);
break; break;
case 1: /* dec Ev */ case 1: /* dec Ev */
gen_inc(s, ot, OR_TMP0, -1);
if (mod != 3) if (mod != 3)
gen_op_st_T0_A0[ot](); opreg = OR_TMP0;
else else
gen_op_mov_reg_T0[ot][rm](); opreg = rm;
gen_inc(s, ot, opreg, -1);
break; break;
case 2: /* call Ev */ case 2: /* call Ev */
/* XXX: optimize if memory (no and is necessary) */ /* XXX: optimize if memory (no and is necessary) */
@ -1822,17 +1853,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
rm = modrm & 7; rm = modrm & 7;
gen_op_mov_TN_reg[ot][0][reg](); gen_op_mov_TN_reg[ot][0][reg]();
gen_op_mov_TN_reg[ot][1][rm](); gen_op_mov_TN_reg[ot][1][rm]();
gen_op_addl_T0_T1_cc(); gen_op_addl_T0_T1();
gen_op_mov_reg_T0[ot][rm](); gen_op_mov_reg_T0[ot][rm]();
gen_op_mov_reg_T1[ot][reg](); gen_op_mov_reg_T1[ot][reg]();
} else { } else {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_mov_TN_reg[ot][0][reg](); gen_op_mov_TN_reg[ot][0][reg]();
gen_op_ld_T1_A0[ot](); gen_op_ld_T1_A0[ot]();
gen_op_addl_T0_T1_cc(); gen_op_addl_T0_T1();
gen_op_st_T0_A0[ot](); gen_op_st_T0_A0[ot]();
gen_op_mov_reg_T1[ot][reg](); gen_op_mov_reg_T1[ot][reg]();
} }
gen_op_update2_cc();
s->cc_op = CC_OP_ADDB + ot; s->cc_op = CC_OP_ADDB + ot;
break; break;
case 0x1b0: case 0x1b0:
@ -3607,8 +3639,7 @@ static uint16_t opc_read_flags[NB_OPS] = {
[INDEX_op_sbbl_T0_T1_cc] = CC_C, [INDEX_op_sbbl_T0_T1_cc] = CC_C,
/* subtle: due to the incl/decl implementation, C is used */ /* subtle: due to the incl/decl implementation, C is used */
[INDEX_op_incl_T0_cc] = CC_C, [INDEX_op_update_inc_cc] = CC_C,
[INDEX_op_decl_T0_cc] = CC_C,
[INDEX_op_into] = CC_O, [INDEX_op_into] = CC_O,
@ -3688,22 +3719,18 @@ static uint16_t opc_read_flags[NB_OPS] = {
/* flags written by an operation */ /* flags written by an operation */
static uint16_t opc_write_flags[NB_OPS] = { static uint16_t opc_write_flags[NB_OPS] = {
[INDEX_op_addl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_update2_cc] = CC_OSZAPC,
[INDEX_op_orl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_update1_cc] = CC_OSZAPC,
[INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC, [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC, [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC, [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC, [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_andl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_subl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_negl_T0_cc] = CC_OSZAPC, [INDEX_op_update_neg_cc] = CC_OSZAPC,
/* subtle: due to the incl/decl implementation, C is used */ /* subtle: due to the incl/decl implementation, C is used */
[INDEX_op_incl_T0_cc] = CC_OSZAPC, [INDEX_op_update_inc_cc] = CC_OSZAPC,
[INDEX_op_decl_T0_cc] = CC_OSZAPC,
[INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_mulb_AL_T0] = CC_OSZAPC, [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
@ -3812,14 +3839,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
/* simpler form of an operation if no flags need to be generated */ /* simpler form of an operation if no flags need to be generated */
static uint16_t opc_simpler[NB_OPS] = { static uint16_t opc_simpler[NB_OPS] = {
[INDEX_op_addl_T0_T1_cc] = INDEX_op_addl_T0_T1, [INDEX_op_update2_cc] = INDEX_op_nop,
[INDEX_op_orl_T0_T1_cc] = INDEX_op_orl_T0_T1, [INDEX_op_update1_cc] = INDEX_op_nop,
[INDEX_op_andl_T0_T1_cc] = INDEX_op_andl_T0_T1, [INDEX_op_update_neg_cc] = INDEX_op_nop,
[INDEX_op_subl_T0_T1_cc] = INDEX_op_subl_T0_T1, [INDEX_op_update_inc_cc] = INDEX_op_nop,
[INDEX_op_xorl_T0_T1_cc] = INDEX_op_xorl_T0_T1,
[INDEX_op_negl_T0_cc] = INDEX_op_negl_T0,
[INDEX_op_incl_T0_cc] = INDEX_op_incl_T0,
[INDEX_op_decl_T0_cc] = INDEX_op_decl_T0,
[INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1, [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
[INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1, [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,