Commit 5797fa5d7ef49ce4beec9586af0cc9c63f7a4b3a
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
Showing
4 changed files
with
129 additions
and
138 deletions
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, ®_addr, &offset_addr); | 1498 | gen_lea_modrm(s, modrm, ®_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, ®_addr, &offset_addr); | 1512 | gen_lea_modrm(s, modrm, ®_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, ®_addr, &offset_addr); | 1545 | gen_lea_modrm(s, modrm, ®_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, ®_addr, &offset_addr); | 1697 | gen_lea_modrm(s, modrm, ®_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, ®_addr, &offset_addr); | 1860 | gen_lea_modrm(s, modrm, ®_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, |