Commit 5797fa5d7ef49ce4beec9586af0cc9c63f7a4b3a

Authored by bellard
1 parent 8ef9a8ec

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
op-i386.c
@@ -80,62 +80,34 @@ static inline int lshift(int x, int n) @@ -80,62 +80,34 @@ static inline int lshift(int x, int n)
80 80
81 /* operations with flags */ 81 /* operations with flags */
82 82
83 -void OPPROTO op_addl_T0_T1_cc(void) 83 +/* update flags with T0 and T1 (add/sub case) */
  84 +void OPPROTO op_update2_cc(void)
84 { 85 {
85 - CC_SRC = T0;  
86 - T0 += T1; 86 + CC_SRC = T1;
87 CC_DST = T0; 87 CC_DST = T0;
88 } 88 }
89 89
90 -void OPPROTO op_orl_T0_T1_cc(void) 90 +/* update flags with T0 (logic operation case) */
  91 +void OPPROTO op_update1_cc(void)
91 { 92 {
92 - T0 |= T1;  
93 - CC_DST = T0;  
94 -}  
95 -  
96 -void OPPROTO op_andl_T0_T1_cc(void)  
97 -{  
98 - T0 &= T1;  
99 CC_DST = T0; 93 CC_DST = T0;
100 } 94 }
101 95
102 -void OPPROTO op_subl_T0_T1_cc(void) 96 +void OPPROTO op_update_neg_cc(void)
103 { 97 {
104 - CC_SRC = T0;  
105 - T0 -= T1;  
106 - CC_DST = T0;  
107 -}  
108 -  
109 -void OPPROTO op_xorl_T0_T1_cc(void)  
110 -{  
111 - T0 ^= T1; 98 + CC_SRC = -T0;
112 CC_DST = T0; 99 CC_DST = T0;
113 } 100 }
114 101
115 void OPPROTO op_cmpl_T0_T1_cc(void) 102 void OPPROTO op_cmpl_T0_T1_cc(void)
116 { 103 {
117 - CC_SRC = T0; 104 + CC_SRC = T1;
118 CC_DST = T0 - T1; 105 CC_DST = T0 - T1;
119 } 106 }
120 107
121 -void OPPROTO op_negl_T0_cc(void)  
122 -{  
123 - CC_SRC = 0;  
124 - T0 = -T0;  
125 - CC_DST = T0;  
126 -}  
127 -  
128 -void OPPROTO op_incl_T0_cc(void)  
129 -{  
130 - CC_SRC = cc_table[CC_OP].compute_c();  
131 - T0++;  
132 - CC_DST = T0;  
133 -}  
134 -  
135 -void OPPROTO op_decl_T0_cc(void) 108 +void OPPROTO op_update_inc_cc(void)
136 { 109 {
137 CC_SRC = cc_table[CC_OP].compute_c(); 110 CC_SRC = cc_table[CC_OP].compute_c();
138 - T0--;  
139 CC_DST = T0; 111 CC_DST = T0;
140 } 112 }
141 113
op_string.h
@@ -86,7 +86,7 @@ void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void) @@ -86,7 +86,7 @@ void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void)
86 v = glue(ldu, SUFFIX)(DI_ADDR); 86 v = glue(ldu, SUFFIX)(DI_ADDR);
87 inc = (DF << SHIFT); 87 inc = (DF << SHIFT);
88 INC_DI(); 88 INC_DI();
89 - CC_SRC = EAX; 89 + CC_SRC = v;
90 CC_DST = EAX - v; 90 CC_DST = EAX - v;
91 } 91 }
92 92
@@ -105,7 +105,7 @@ void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void) @@ -105,7 +105,7 @@ void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
105 if (v1 != v2) 105 if (v1 != v2)
106 break; 106 break;
107 } while (CX != 0); 107 } while (CX != 0);
108 - CC_SRC = v1; 108 + CC_SRC = v2;
109 CC_DST = v1 - v2; 109 CC_DST = v1 - v2;
110 CC_OP = CC_OP_SUBB + SHIFT; 110 CC_OP = CC_OP_SUBB + SHIFT;
111 } 111 }
@@ -127,7 +127,7 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void) @@ -127,7 +127,7 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void)
127 if (v1 == v2) 127 if (v1 == v2)
128 break; 128 break;
129 } while (CX != 0); 129 } while (CX != 0);
130 - CC_SRC = v1; 130 + CC_SRC = v2;
131 CC_DST = v1 - v2; 131 CC_DST = v1 - v2;
132 CC_OP = CC_OP_SUBB + SHIFT; 132 CC_OP = CC_OP_SUBB + SHIFT;
133 } 133 }
@@ -142,7 +142,7 @@ void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void) @@ -142,7 +142,7 @@ void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void)
142 inc = (DF << SHIFT); 142 inc = (DF << SHIFT);
143 INC_SI(); 143 INC_SI();
144 INC_DI(); 144 INC_DI();
145 - CC_SRC = v1; 145 + CC_SRC = v2;
146 CC_DST = v1 - v2; 146 CC_DST = v1 - v2;
147 } 147 }
148 148
@@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void) @@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
160 if (v1 != v2) 160 if (v1 != v2)
161 break; 161 break;
162 } while (CX != 0); 162 } while (CX != 0);
163 - CC_SRC = v1; 163 + CC_SRC = v2;
164 CC_DST = v1 - v2; 164 CC_DST = v1 - v2;
165 CC_OP = CC_OP_SUBB + SHIFT; 165 CC_OP = CC_OP_SUBB + SHIFT;
166 } 166 }
@@ -181,7 +181,7 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void) @@ -181,7 +181,7 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void)
181 if (v1 == v2) 181 if (v1 == v2)
182 break; 182 break;
183 } while (CX != 0); 183 } while (CX != 0);
184 - CC_SRC = v1; 184 + CC_SRC = v2;
185 CC_DST = v1 - v2; 185 CC_DST = v1 - v2;
186 CC_OP = CC_OP_SUBB + SHIFT; 186 CC_OP = CC_OP_SUBB + SHIFT;
187 } 187 }
ops_template.h
@@ -93,8 +93,8 @@ static int glue(compute_all_sub, SUFFIX)(void) @@ -93,8 +93,8 @@ static int glue(compute_all_sub, SUFFIX)(void)
93 { 93 {
94 int cf, pf, af, zf, sf, of; 94 int cf, pf, af, zf, sf, of;
95 int src1, src2; 95 int src1, src2;
96 - src1 = CC_SRC;  
97 - src2 = CC_SRC - CC_DST; 96 + src1 = CC_DST + CC_SRC;
  97 + src2 = CC_SRC;
98 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; 98 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
99 pf = parity_table[(uint8_t)CC_DST]; 99 pf = parity_table[(uint8_t)CC_DST];
100 af = (CC_DST ^ src1 ^ src2) & 0x10; 100 af = (CC_DST ^ src1 ^ src2) & 0x10;
@@ -107,8 +107,8 @@ static int glue(compute_all_sub, SUFFIX)(void) @@ -107,8 +107,8 @@ static int glue(compute_all_sub, SUFFIX)(void)
107 static int glue(compute_c_sub, SUFFIX)(void) 107 static int glue(compute_c_sub, SUFFIX)(void)
108 { 108 {
109 int src1, src2, cf; 109 int src1, src2, cf;
110 - src1 = CC_SRC;  
111 - src2 = CC_SRC - CC_DST; 110 + src1 = CC_DST + CC_SRC;
  111 + src2 = CC_SRC;
112 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; 112 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
113 return cf; 113 return cf;
114 } 114 }
@@ -117,8 +117,8 @@ static int glue(compute_all_sbb, SUFFIX)(void) @@ -117,8 +117,8 @@ static int glue(compute_all_sbb, SUFFIX)(void)
117 { 117 {
118 int cf, pf, af, zf, sf, of; 118 int cf, pf, af, zf, sf, of;
119 int src1, src2; 119 int src1, src2;
120 - src1 = CC_SRC;  
121 - src2 = CC_SRC - CC_DST - 1; 120 + src1 = CC_DST + CC_SRC + 1;
  121 + src2 = CC_SRC;
122 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; 122 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
123 pf = parity_table[(uint8_t)CC_DST]; 123 pf = parity_table[(uint8_t)CC_DST];
124 af = (CC_DST ^ src1 ^ src2) & 0x10; 124 af = (CC_DST ^ src1 ^ src2) & 0x10;
@@ -131,8 +131,8 @@ static int glue(compute_all_sbb, SUFFIX)(void) @@ -131,8 +131,8 @@ static int glue(compute_all_sbb, SUFFIX)(void)
131 static int glue(compute_c_sbb, SUFFIX)(void) 131 static int glue(compute_c_sbb, SUFFIX)(void)
132 { 132 {
133 int src1, src2, cf; 133 int src1, src2, cf;
134 - src1 = CC_SRC;  
135 - src2 = CC_SRC - CC_DST - 1; 134 + src1 = CC_DST + CC_SRC + 1;
  135 + src2 = CC_SRC;
136 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; 136 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
137 return cf; 137 return cf;
138 } 138 }
@@ -234,8 +234,8 @@ static int glue(compute_all_sar, SUFFIX)(void) @@ -234,8 +234,8 @@ static int glue(compute_all_sar, SUFFIX)(void)
234 void OPPROTO glue(op_jb_sub, SUFFIX)(void) 234 void OPPROTO glue(op_jb_sub, SUFFIX)(void)
235 { 235 {
236 int src1, src2; 236 int src1, src2;
237 - src1 = CC_SRC;  
238 - src2 = CC_SRC - CC_DST; 237 + src1 = CC_DST + CC_SRC;
  238 + src2 = CC_SRC;
239 239
240 if ((DATA_TYPE)src1 < (DATA_TYPE)src2) 240 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
241 JUMP_TB(PARAM1, 0, PARAM2); 241 JUMP_TB(PARAM1, 0, PARAM2);
@@ -256,8 +256,8 @@ void OPPROTO glue(op_jz_sub, SUFFIX)(void) @@ -256,8 +256,8 @@ void OPPROTO glue(op_jz_sub, SUFFIX)(void)
256 void OPPROTO glue(op_jbe_sub, SUFFIX)(void) 256 void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
257 { 257 {
258 int src1, src2; 258 int src1, src2;
259 - src1 = CC_SRC;  
260 - src2 = CC_SRC - CC_DST; 259 + src1 = CC_DST + CC_SRC;
  260 + src2 = CC_SRC;
261 261
262 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2) 262 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
263 JUMP_TB(PARAM1, 0, PARAM2); 263 JUMP_TB(PARAM1, 0, PARAM2);
@@ -278,8 +278,8 @@ void OPPROTO glue(op_js_sub, SUFFIX)(void) @@ -278,8 +278,8 @@ void OPPROTO glue(op_js_sub, SUFFIX)(void)
278 void OPPROTO glue(op_jl_sub, SUFFIX)(void) 278 void OPPROTO glue(op_jl_sub, SUFFIX)(void)
279 { 279 {
280 int src1, src2; 280 int src1, src2;
281 - src1 = CC_SRC;  
282 - src2 = CC_SRC - CC_DST; 281 + src1 = CC_DST + CC_SRC;
  282 + src2 = CC_SRC;
283 283
284 if ((DATA_STYPE)src1 < (DATA_STYPE)src2) 284 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
285 JUMP_TB(PARAM1, 0, PARAM2); 285 JUMP_TB(PARAM1, 0, PARAM2);
@@ -291,8 +291,8 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void) @@ -291,8 +291,8 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
291 void OPPROTO glue(op_jle_sub, SUFFIX)(void) 291 void OPPROTO glue(op_jle_sub, SUFFIX)(void)
292 { 292 {
293 int src1, src2; 293 int src1, src2;
294 - src1 = CC_SRC;  
295 - src2 = CC_SRC - CC_DST; 294 + src1 = CC_DST + CC_SRC;
  295 + src2 = CC_SRC;
296 296
297 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2) 297 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
298 JUMP_TB(PARAM1, 0, PARAM2); 298 JUMP_TB(PARAM1, 0, PARAM2);
@@ -361,8 +361,8 @@ void OPPROTO glue(op_jecxz, SUFFIX)(void) @@ -361,8 +361,8 @@ void OPPROTO glue(op_jecxz, SUFFIX)(void)
361 void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) 361 void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
362 { 362 {
363 int src1, src2; 363 int src1, src2;
364 - src1 = CC_SRC;  
365 - src2 = CC_SRC - CC_DST; 364 + src1 = CC_DST + CC_SRC;
  365 + src2 = CC_SRC;
366 366
367 T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2); 367 T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
368 } 368 }
@@ -375,8 +375,8 @@ void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void) @@ -375,8 +375,8 @@ void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
375 void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void) 375 void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
376 { 376 {
377 int src1, src2; 377 int src1, src2;
378 - src1 = CC_SRC;  
379 - src2 = CC_SRC - CC_DST; 378 + src1 = CC_DST + CC_SRC;
  379 + src2 = CC_SRC;
380 380
381 T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2); 381 T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
382 } 382 }
@@ -389,8 +389,8 @@ void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void) @@ -389,8 +389,8 @@ void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
389 void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) 389 void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
390 { 390 {
391 int src1, src2; 391 int src1, src2;
392 - src1 = CC_SRC;  
393 - src2 = CC_SRC - CC_DST; 392 + src1 = CC_DST + CC_SRC;
  393 + src2 = CC_SRC;
394 394
395 T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2); 395 T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
396 } 396 }
@@ -398,8 +398,8 @@ void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) @@ -398,8 +398,8 @@ void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
398 void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) 398 void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
399 { 399 {
400 int src1, src2; 400 int src1, src2;
401 - src1 = CC_SRC;  
402 - src2 = CC_SRC - CC_DST; 401 + src1 = CC_DST + CC_SRC;
  402 + src2 = CC_SRC;
403 403
404 T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); 404 T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
405 } 405 }
@@ -714,9 +714,7 @@ void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void) @@ -714,9 +714,7 @@ void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
714 { 714 {
715 int cf; 715 int cf;
716 cf = cc_table[CC_OP].compute_c(); 716 cf = cc_table[CC_OP].compute_c();
717 - CC_SRC = T0;  
718 T0 = T0 + T1 + cf; 717 T0 = T0 + T1 + cf;
719 - CC_DST = T0;  
720 CC_OP = CC_OP_ADDB + SHIFT + cf * 3; 718 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
721 } 719 }
722 720
@@ -724,15 +722,13 @@ void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void) @@ -724,15 +722,13 @@ void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
724 { 722 {
725 int cf; 723 int cf;
726 cf = cc_table[CC_OP].compute_c(); 724 cf = cc_table[CC_OP].compute_c();
727 - CC_SRC = T0;  
728 T0 = T0 - T1 - cf; 725 T0 = T0 - T1 - cf;
729 - CC_DST = T0;  
730 CC_OP = CC_OP_SUBB + SHIFT + cf * 3; 726 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
731 } 727 }
732 728
733 void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void) 729 void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
734 { 730 {
735 - CC_SRC = EAX; 731 + CC_SRC = T0;
736 CC_DST = EAX - T0; 732 CC_DST = EAX - T0;
737 if ((DATA_TYPE)CC_DST == 0) { 733 if ((DATA_TYPE)CC_DST == 0) {
738 T0 = T1; 734 T0 = T1;
translate-i386.c
@@ -365,14 +365,14 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = { @@ -365,14 +365,14 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = {
365 }; 365 };
366 366
367 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = { 367 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
368 - gen_op_addl_T0_T1_cc,  
369 - gen_op_orl_T0_T1_cc,  
370 NULL, 368 NULL,
  369 + gen_op_orl_T0_T1,
  370 + NULL,
  371 + NULL,
  372 + gen_op_andl_T0_T1,
  373 + NULL,
  374 + gen_op_xorl_T0_T1,
371 NULL, 375 NULL,
372 - gen_op_andl_T0_T1_cc,  
373 - gen_op_subl_T0_T1_cc,  
374 - gen_op_xorl_T0_T1_cc,  
375 - gen_op_cmpl_T0_T1_cc,  
376 }; 376 };
377 377
378 static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = { 378 static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
@@ -748,46 +748,83 @@ static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = { @@ -748,46 +748,83 @@ static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
748 gen_op_fdiv_STN_ST0, 748 gen_op_fdiv_STN_ST0,
749 }; 749 };
750 750
751 -static void gen_op(DisasContext *s1, int op, int ot, int d, int s) 751 +/* if d == OR_TMP0, it means memory operand (address in A0) */
  752 +static void gen_op(DisasContext *s1, int op, int ot, int d)
752 { 753 {
753 - if (d != OR_TMP0) 754 + GenOpFunc *gen_update_cc;
  755 +
  756 + if (d != OR_TMP0) {
754 gen_op_mov_TN_reg[ot][0][d](); 757 gen_op_mov_TN_reg[ot][0][d]();
755 - if (s != OR_TMP1)  
756 - gen_op_mov_TN_reg[ot][1][s]();  
757 - if (op == OP_ADCL || op == OP_SBBL) { 758 + } else {
  759 + gen_op_ld_T0_A0[ot]();
  760 + }
  761 + switch(op) {
  762 + case OP_ADCL:
  763 + case OP_SBBL:
758 if (s1->cc_op != CC_OP_DYNAMIC) 764 if (s1->cc_op != CC_OP_DYNAMIC)
759 gen_op_set_cc_op(s1->cc_op); 765 gen_op_set_cc_op(s1->cc_op);
760 gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); 766 gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
761 s1->cc_op = CC_OP_DYNAMIC; 767 s1->cc_op = CC_OP_DYNAMIC;
762 - } else { 768 + /* XXX: incorrect: CC_OP must also be modified AFTER memory access */
  769 + gen_update_cc = gen_op_update2_cc;
  770 + break;
  771 + case OP_ADDL:
  772 + gen_op_addl_T0_T1();
  773 + s1->cc_op = CC_OP_ADDB + ot;
  774 + gen_update_cc = gen_op_update2_cc;
  775 + break;
  776 + case OP_SUBL:
  777 + gen_op_subl_T0_T1();
  778 + s1->cc_op = CC_OP_SUBB + ot;
  779 + gen_update_cc = gen_op_update2_cc;
  780 + break;
  781 + default:
  782 + case OP_ANDL:
  783 + case OP_ORL:
  784 + case OP_XORL:
763 gen_op_arith_T0_T1_cc[op](); 785 gen_op_arith_T0_T1_cc[op]();
764 - s1->cc_op = cc_op_arithb[op] + ot; 786 + s1->cc_op = CC_OP_LOGICB + ot;
  787 + gen_update_cc = gen_op_update1_cc;
  788 + break;
  789 + case OP_CMPL:
  790 + gen_op_cmpl_T0_T1_cc();
  791 + s1->cc_op = CC_OP_SUBB + ot;
  792 + gen_update_cc = NULL;
  793 + break;
765 } 794 }
766 - if (d != OR_TMP0 && op != OP_CMPL)  
767 - gen_op_mov_reg_T0[ot][d]();  
768 -}  
769 -  
770 -static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)  
771 -{  
772 - gen_op_movl_T1_im(c);  
773 - gen_op(s1, op, ot, d, OR_TMP1); 795 + if (op != OP_CMPL) {
  796 + if (d != OR_TMP0)
  797 + gen_op_mov_reg_T0[ot][d]();
  798 + else
  799 + gen_op_st_T0_A0[ot]();
  800 + }
  801 + /* the flags update must happen after the memory write (precise
  802 + exception support) */
  803 + if (gen_update_cc)
  804 + gen_update_cc();
774 } 805 }
775 806
  807 +/* if d == OR_TMP0, it means memory operand (address in A0) */
776 static void gen_inc(DisasContext *s1, int ot, int d, int c) 808 static void gen_inc(DisasContext *s1, int ot, int d, int c)
777 { 809 {
778 if (d != OR_TMP0) 810 if (d != OR_TMP0)
779 gen_op_mov_TN_reg[ot][0][d](); 811 gen_op_mov_TN_reg[ot][0][d]();
  812 + else
  813 + gen_op_ld_T0_A0[ot]();
780 if (s1->cc_op != CC_OP_DYNAMIC) 814 if (s1->cc_op != CC_OP_DYNAMIC)
781 gen_op_set_cc_op(s1->cc_op); 815 gen_op_set_cc_op(s1->cc_op);
782 if (c > 0) { 816 if (c > 0) {
783 - gen_op_incl_T0_cc(); 817 + gen_op_incl_T0();
784 s1->cc_op = CC_OP_INCB + ot; 818 s1->cc_op = CC_OP_INCB + ot;
785 } else { 819 } else {
786 - gen_op_decl_T0_cc(); 820 + gen_op_decl_T0();
787 s1->cc_op = CC_OP_DECB + ot; 821 s1->cc_op = CC_OP_DECB + ot;
788 } 822 }
789 if (d != OR_TMP0) 823 if (d != OR_TMP0)
790 gen_op_mov_reg_T0[ot][d](); 824 gen_op_mov_reg_T0[ot][d]();
  825 + else
  826 + gen_op_st_T0_A0[ot]();
  827 + gen_op_update_inc_cc();
791 } 828 }
792 829
793 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) 830 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) @@ -1459,15 +1496,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1459 rm = modrm & 7; 1496 rm = modrm & 7;
1460 if (mod != 3) { 1497 if (mod != 3) {
1461 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1498 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1462 - gen_op_ld_T0_A0[ot]();  
1463 opreg = OR_TMP0; 1499 opreg = OR_TMP0;
1464 } else { 1500 } else {
1465 opreg = OR_EAX + rm; 1501 opreg = OR_EAX + rm;
1466 } 1502 }
1467 - gen_op(s, op, ot, opreg, reg);  
1468 - if (mod != 3 && op != 7) {  
1469 - gen_op_st_T0_A0[ot]();  
1470 - } 1503 + gen_op_mov_TN_reg[ot][1][reg]();
  1504 + gen_op(s, op, ot, opreg);
1471 break; 1505 break;
1472 case 1: /* OP Gv, Ev */ 1506 case 1: /* OP Gv, Ev */
1473 modrm = ldub(s->pc++); 1507 modrm = ldub(s->pc++);
@@ -1477,15 +1511,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1477,15 +1511,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1477 if (mod != 3) { 1511 if (mod != 3) {
1478 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1512 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1479 gen_op_ld_T1_A0[ot](); 1513 gen_op_ld_T1_A0[ot]();
1480 - opreg = OR_TMP1;  
1481 } else { 1514 } else {
1482 - opreg = OR_EAX + rm; 1515 + gen_op_mov_TN_reg[ot][1][rm]();
1483 } 1516 }
1484 - gen_op(s, op, ot, reg, opreg); 1517 + gen_op(s, op, ot, reg);
1485 break; 1518 break;
1486 case 2: /* OP A, Iv */ 1519 case 2: /* OP A, Iv */
1487 val = insn_get(s, ot); 1520 val = insn_get(s, ot);
1488 - gen_opi(s, op, ot, OR_EAX, val); 1521 + gen_op_movl_T1_im(val);
  1522 + gen_op(s, op, ot, OR_EAX);
1489 break; 1523 break;
1490 } 1524 }
1491 } 1525 }
@@ -1509,7 +1543,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1509,7 +1543,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1509 1543
1510 if (mod != 3) { 1544 if (mod != 3) {
1511 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1545 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1512 - gen_op_ld_T0_A0[ot]();  
1513 opreg = OR_TMP0; 1546 opreg = OR_TMP0;
1514 } else { 1547 } else {
1515 opreg = rm + OR_EAX; 1548 opreg = rm + OR_EAX;
@@ -1525,11 +1558,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1525,11 +1558,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1525 val = (int8_t)insn_get(s, OT_BYTE); 1558 val = (int8_t)insn_get(s, OT_BYTE);
1526 break; 1559 break;
1527 } 1560 }
1528 -  
1529 - gen_opi(s, op, ot, opreg, val);  
1530 - if (op != 7 && mod != 3) {  
1531 - gen_op_st_T0_A0[ot]();  
1532 - } 1561 + gen_op_movl_T1_im(val);
  1562 + gen_op(s, op, ot, opreg);
1533 } 1563 }
1534 break; 1564 break;
1535 1565
@@ -1577,12 +1607,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1577,12 +1607,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1577 } 1607 }
1578 break; 1608 break;
1579 case 3: /* neg */ 1609 case 3: /* neg */
1580 - gen_op_negl_T0_cc(); 1610 + gen_op_negl_T0();
1581 if (mod != 3) { 1611 if (mod != 3) {
1582 gen_op_st_T0_A0[ot](); 1612 gen_op_st_T0_A0[ot]();
1583 } else { 1613 } else {
1584 gen_op_mov_reg_T0[ot][rm](); 1614 gen_op_mov_reg_T0[ot][rm]();
1585 } 1615 }
  1616 + gen_op_update_neg_cc();
1586 s->cc_op = CC_OP_SUBB + ot; 1617 s->cc_op = CC_OP_SUBB + ot;
1587 break; 1618 break;
1588 case 4: /* mul */ 1619 case 4: /* mul */
@@ -1664,7 +1695,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1664,7 +1695,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1664 } 1695 }
1665 if (mod != 3) { 1696 if (mod != 3) {
1666 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1697 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1667 - if (op != 3 && op != 5) 1698 + if (op >= 2 && op != 3 && op != 5)
1668 gen_op_ld_T0_A0[ot](); 1699 gen_op_ld_T0_A0[ot]();
1669 } else { 1700 } else {
1670 gen_op_mov_TN_reg[ot][0][rm](); 1701 gen_op_mov_TN_reg[ot][0][rm]();
@@ -1672,18 +1703,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1672,18 +1703,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1672 1703
1673 switch(op) { 1704 switch(op) {
1674 case 0: /* inc Ev */ 1705 case 0: /* inc Ev */
1675 - gen_inc(s, ot, OR_TMP0, 1);  
1676 if (mod != 3) 1706 if (mod != 3)
1677 - gen_op_st_T0_A0[ot](); 1707 + opreg = OR_TMP0;
1678 else 1708 else
1679 - gen_op_mov_reg_T0[ot][rm](); 1709 + opreg = rm;
  1710 + gen_inc(s, ot, opreg, 1);
1680 break; 1711 break;
1681 case 1: /* dec Ev */ 1712 case 1: /* dec Ev */
1682 - gen_inc(s, ot, OR_TMP0, -1);  
1683 if (mod != 3) 1713 if (mod != 3)
1684 - gen_op_st_T0_A0[ot](); 1714 + opreg = OR_TMP0;
1685 else 1715 else
1686 - gen_op_mov_reg_T0[ot][rm](); 1716 + opreg = rm;
  1717 + gen_inc(s, ot, opreg, -1);
1687 break; 1718 break;
1688 case 2: /* call Ev */ 1719 case 2: /* call Ev */
1689 /* XXX: optimize if memory (no and is necessary) */ 1720 /* XXX: optimize if memory (no and is necessary) */
@@ -1822,17 +1853,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1822,17 +1853,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1822 rm = modrm & 7; 1853 rm = modrm & 7;
1823 gen_op_mov_TN_reg[ot][0][reg](); 1854 gen_op_mov_TN_reg[ot][0][reg]();
1824 gen_op_mov_TN_reg[ot][1][rm](); 1855 gen_op_mov_TN_reg[ot][1][rm]();
1825 - gen_op_addl_T0_T1_cc(); 1856 + gen_op_addl_T0_T1();
1826 gen_op_mov_reg_T0[ot][rm](); 1857 gen_op_mov_reg_T0[ot][rm]();
1827 gen_op_mov_reg_T1[ot][reg](); 1858 gen_op_mov_reg_T1[ot][reg]();
1828 } else { 1859 } else {
1829 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1860 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1830 gen_op_mov_TN_reg[ot][0][reg](); 1861 gen_op_mov_TN_reg[ot][0][reg]();
1831 gen_op_ld_T1_A0[ot](); 1862 gen_op_ld_T1_A0[ot]();
1832 - gen_op_addl_T0_T1_cc(); 1863 + gen_op_addl_T0_T1();
1833 gen_op_st_T0_A0[ot](); 1864 gen_op_st_T0_A0[ot]();
1834 gen_op_mov_reg_T1[ot][reg](); 1865 gen_op_mov_reg_T1[ot][reg]();
1835 } 1866 }
  1867 + gen_op_update2_cc();
1836 s->cc_op = CC_OP_ADDB + ot; 1868 s->cc_op = CC_OP_ADDB + ot;
1837 break; 1869 break;
1838 case 0x1b0: 1870 case 0x1b0:
@@ -3607,8 +3639,7 @@ static uint16_t opc_read_flags[NB_OPS] = { @@ -3607,8 +3639,7 @@ static uint16_t opc_read_flags[NB_OPS] = {
3607 [INDEX_op_sbbl_T0_T1_cc] = CC_C, 3639 [INDEX_op_sbbl_T0_T1_cc] = CC_C,
3608 3640
3609 /* subtle: due to the incl/decl implementation, C is used */ 3641 /* subtle: due to the incl/decl implementation, C is used */
3610 - [INDEX_op_incl_T0_cc] = CC_C,  
3611 - [INDEX_op_decl_T0_cc] = CC_C, 3642 + [INDEX_op_update_inc_cc] = CC_C,
3612 3643
3613 [INDEX_op_into] = CC_O, 3644 [INDEX_op_into] = CC_O,
3614 3645
@@ -3688,22 +3719,18 @@ static uint16_t opc_read_flags[NB_OPS] = { @@ -3688,22 +3719,18 @@ static uint16_t opc_read_flags[NB_OPS] = {
3688 3719
3689 /* flags written by an operation */ 3720 /* flags written by an operation */
3690 static uint16_t opc_write_flags[NB_OPS] = { 3721 static uint16_t opc_write_flags[NB_OPS] = {
3691 - [INDEX_op_addl_T0_T1_cc] = CC_OSZAPC,  
3692 - [INDEX_op_orl_T0_T1_cc] = CC_OSZAPC, 3722 + [INDEX_op_update2_cc] = CC_OSZAPC,
  3723 + [INDEX_op_update1_cc] = CC_OSZAPC,
3693 [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC, 3724 [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
3694 [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC, 3725 [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
3695 [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC, 3726 [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
3696 [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC, 3727 [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
3697 [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC, 3728 [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
3698 [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC, 3729 [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
3699 - [INDEX_op_andl_T0_T1_cc] = CC_OSZAPC,  
3700 - [INDEX_op_subl_T0_T1_cc] = CC_OSZAPC,  
3701 - [INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,  
3702 [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC, 3730 [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
3703 - [INDEX_op_negl_T0_cc] = CC_OSZAPC, 3731 + [INDEX_op_update_neg_cc] = CC_OSZAPC,
3704 /* subtle: due to the incl/decl implementation, C is used */ 3732 /* subtle: due to the incl/decl implementation, C is used */
3705 - [INDEX_op_incl_T0_cc] = CC_OSZAPC,  
3706 - [INDEX_op_decl_T0_cc] = CC_OSZAPC, 3733 + [INDEX_op_update_inc_cc] = CC_OSZAPC,
3707 [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, 3734 [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
3708 3735
3709 [INDEX_op_mulb_AL_T0] = CC_OSZAPC, 3736 [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
@@ -3812,14 +3839,10 @@ static uint16_t opc_write_flags[NB_OPS] = { @@ -3812,14 +3839,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
3812 3839
3813 /* simpler form of an operation if no flags need to be generated */ 3840 /* simpler form of an operation if no flags need to be generated */
3814 static uint16_t opc_simpler[NB_OPS] = { 3841 static uint16_t opc_simpler[NB_OPS] = {
3815 - [INDEX_op_addl_T0_T1_cc] = INDEX_op_addl_T0_T1,  
3816 - [INDEX_op_orl_T0_T1_cc] = INDEX_op_orl_T0_T1,  
3817 - [INDEX_op_andl_T0_T1_cc] = INDEX_op_andl_T0_T1,  
3818 - [INDEX_op_subl_T0_T1_cc] = INDEX_op_subl_T0_T1,  
3819 - [INDEX_op_xorl_T0_T1_cc] = INDEX_op_xorl_T0_T1,  
3820 - [INDEX_op_negl_T0_cc] = INDEX_op_negl_T0,  
3821 - [INDEX_op_incl_T0_cc] = INDEX_op_incl_T0,  
3822 - [INDEX_op_decl_T0_cc] = INDEX_op_decl_T0, 3842 + [INDEX_op_update2_cc] = INDEX_op_nop,
  3843 + [INDEX_op_update1_cc] = INDEX_op_nop,
  3844 + [INDEX_op_update_neg_cc] = INDEX_op_nop,
  3845 + [INDEX_op_update_inc_cc] = INDEX_op_nop,
3823 3846
3824 [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1, 3847 [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
3825 [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1, 3848 [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,