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 | 80 | |
81 | 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 | 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 | 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 | 99 | CC_DST = T0; |
113 | 100 | } |
114 | 101 | |
115 | 102 | void OPPROTO op_cmpl_T0_T1_cc(void) |
116 | 103 | { |
117 | - CC_SRC = T0; | |
104 | + CC_SRC = T1; | |
118 | 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 | 110 | CC_SRC = cc_table[CC_OP].compute_c(); |
138 | - T0--; | |
139 | 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 | 86 | v = glue(ldu, SUFFIX)(DI_ADDR); |
87 | 87 | inc = (DF << SHIFT); |
88 | 88 | INC_DI(); |
89 | - CC_SRC = EAX; | |
89 | + CC_SRC = v; | |
90 | 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 | 105 | if (v1 != v2) |
106 | 106 | break; |
107 | 107 | } while (CX != 0); |
108 | - CC_SRC = v1; | |
108 | + CC_SRC = v2; | |
109 | 109 | CC_DST = v1 - v2; |
110 | 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 | 127 | if (v1 == v2) |
128 | 128 | break; |
129 | 129 | } while (CX != 0); |
130 | - CC_SRC = v1; | |
130 | + CC_SRC = v2; | |
131 | 131 | CC_DST = v1 - v2; |
132 | 132 | CC_OP = CC_OP_SUBB + SHIFT; |
133 | 133 | } |
... | ... | @@ -142,7 +142,7 @@ void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void) |
142 | 142 | inc = (DF << SHIFT); |
143 | 143 | INC_SI(); |
144 | 144 | INC_DI(); |
145 | - CC_SRC = v1; | |
145 | + CC_SRC = v2; | |
146 | 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 | 160 | if (v1 != v2) |
161 | 161 | break; |
162 | 162 | } while (CX != 0); |
163 | - CC_SRC = v1; | |
163 | + CC_SRC = v2; | |
164 | 164 | CC_DST = v1 - v2; |
165 | 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 | 181 | if (v1 == v2) |
182 | 182 | break; |
183 | 183 | } while (CX != 0); |
184 | - CC_SRC = v1; | |
184 | + CC_SRC = v2; | |
185 | 185 | CC_DST = v1 - v2; |
186 | 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 | 93 | { |
94 | 94 | int cf, pf, af, zf, sf, of; |
95 | 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 | 98 | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
99 | 99 | pf = parity_table[(uint8_t)CC_DST]; |
100 | 100 | af = (CC_DST ^ src1 ^ src2) & 0x10; |
... | ... | @@ -107,8 +107,8 @@ static int glue(compute_all_sub, SUFFIX)(void) |
107 | 107 | static int glue(compute_c_sub, SUFFIX)(void) |
108 | 108 | { |
109 | 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 | 112 | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
113 | 113 | return cf; |
114 | 114 | } |
... | ... | @@ -117,8 +117,8 @@ static int glue(compute_all_sbb, SUFFIX)(void) |
117 | 117 | { |
118 | 118 | int cf, pf, af, zf, sf, of; |
119 | 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 | 122 | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; |
123 | 123 | pf = parity_table[(uint8_t)CC_DST]; |
124 | 124 | af = (CC_DST ^ src1 ^ src2) & 0x10; |
... | ... | @@ -131,8 +131,8 @@ static int glue(compute_all_sbb, SUFFIX)(void) |
131 | 131 | static int glue(compute_c_sbb, SUFFIX)(void) |
132 | 132 | { |
133 | 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 | 136 | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; |
137 | 137 | return cf; |
138 | 138 | } |
... | ... | @@ -234,8 +234,8 @@ static int glue(compute_all_sar, SUFFIX)(void) |
234 | 234 | void OPPROTO glue(op_jb_sub, SUFFIX)(void) |
235 | 235 | { |
236 | 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 | 240 | if ((DATA_TYPE)src1 < (DATA_TYPE)src2) |
241 | 241 | JUMP_TB(PARAM1, 0, PARAM2); |
... | ... | @@ -256,8 +256,8 @@ void OPPROTO glue(op_jz_sub, SUFFIX)(void) |
256 | 256 | void OPPROTO glue(op_jbe_sub, SUFFIX)(void) |
257 | 257 | { |
258 | 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 | 262 | if ((DATA_TYPE)src1 <= (DATA_TYPE)src2) |
263 | 263 | JUMP_TB(PARAM1, 0, PARAM2); |
... | ... | @@ -278,8 +278,8 @@ void OPPROTO glue(op_js_sub, SUFFIX)(void) |
278 | 278 | void OPPROTO glue(op_jl_sub, SUFFIX)(void) |
279 | 279 | { |
280 | 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 | 284 | if ((DATA_STYPE)src1 < (DATA_STYPE)src2) |
285 | 285 | JUMP_TB(PARAM1, 0, PARAM2); |
... | ... | @@ -291,8 +291,8 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void) |
291 | 291 | void OPPROTO glue(op_jle_sub, SUFFIX)(void) |
292 | 292 | { |
293 | 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 | 297 | if ((DATA_STYPE)src1 <= (DATA_STYPE)src2) |
298 | 298 | JUMP_TB(PARAM1, 0, PARAM2); |
... | ... | @@ -361,8 +361,8 @@ void OPPROTO glue(op_jecxz, SUFFIX)(void) |
361 | 361 | void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) |
362 | 362 | { |
363 | 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 | 367 | T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2); |
368 | 368 | } |
... | ... | @@ -375,8 +375,8 @@ void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void) |
375 | 375 | void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void) |
376 | 376 | { |
377 | 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 | 381 | T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2); |
382 | 382 | } |
... | ... | @@ -389,8 +389,8 @@ void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void) |
389 | 389 | void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) |
390 | 390 | { |
391 | 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 | 395 | T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2); |
396 | 396 | } |
... | ... | @@ -398,8 +398,8 @@ void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) |
398 | 398 | void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) |
399 | 399 | { |
400 | 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 | 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 | 714 | { |
715 | 715 | int cf; |
716 | 716 | cf = cc_table[CC_OP].compute_c(); |
717 | - CC_SRC = T0; | |
718 | 717 | T0 = T0 + T1 + cf; |
719 | - CC_DST = T0; | |
720 | 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 | 722 | { |
725 | 723 | int cf; |
726 | 724 | cf = cc_table[CC_OP].compute_c(); |
727 | - CC_SRC = T0; | |
728 | 725 | T0 = T0 - T1 - cf; |
729 | - CC_DST = T0; | |
730 | 726 | CC_OP = CC_OP_SUBB + SHIFT + cf * 3; |
731 | 727 | } |
732 | 728 | |
733 | 729 | void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void) |
734 | 730 | { |
735 | - CC_SRC = EAX; | |
731 | + CC_SRC = T0; | |
736 | 732 | CC_DST = EAX - T0; |
737 | 733 | if ((DATA_TYPE)CC_DST == 0) { |
738 | 734 | T0 = T1; | ... | ... |
translate-i386.c
... | ... | @@ -365,14 +365,14 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = { |
365 | 365 | }; |
366 | 366 | |
367 | 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 | 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 | 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 | 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 | 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 | 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 | 764 | if (s1->cc_op != CC_OP_DYNAMIC) |
759 | 765 | gen_op_set_cc_op(s1->cc_op); |
760 | 766 | gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); |
761 | 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 | 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 | 808 | static void gen_inc(DisasContext *s1, int ot, int d, int c) |
777 | 809 | { |
778 | 810 | if (d != OR_TMP0) |
779 | 811 | gen_op_mov_TN_reg[ot][0][d](); |
812 | + else | |
813 | + gen_op_ld_T0_A0[ot](); | |
780 | 814 | if (s1->cc_op != CC_OP_DYNAMIC) |
781 | 815 | gen_op_set_cc_op(s1->cc_op); |
782 | 816 | if (c > 0) { |
783 | - gen_op_incl_T0_cc(); | |
817 | + gen_op_incl_T0(); | |
784 | 818 | s1->cc_op = CC_OP_INCB + ot; |
785 | 819 | } else { |
786 | - gen_op_decl_T0_cc(); | |
820 | + gen_op_decl_T0(); | |
787 | 821 | s1->cc_op = CC_OP_DECB + ot; |
788 | 822 | } |
789 | 823 | if (d != OR_TMP0) |
790 | 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 | 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 | 1496 | rm = modrm & 7; |
1460 | 1497 | if (mod != 3) { |
1461 | 1498 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
1462 | - gen_op_ld_T0_A0[ot](); | |
1463 | 1499 | opreg = OR_TMP0; |
1464 | 1500 | } else { |
1465 | 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 | 1505 | break; |
1472 | 1506 | case 1: /* OP Gv, Ev */ |
1473 | 1507 | modrm = ldub(s->pc++); |
... | ... | @@ -1477,15 +1511,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1477 | 1511 | if (mod != 3) { |
1478 | 1512 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
1479 | 1513 | gen_op_ld_T1_A0[ot](); |
1480 | - opreg = OR_TMP1; | |
1481 | 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 | 1518 | break; |
1486 | 1519 | case 2: /* OP A, Iv */ |
1487 | 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 | 1523 | break; |
1490 | 1524 | } |
1491 | 1525 | } |
... | ... | @@ -1509,7 +1543,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1509 | 1543 | |
1510 | 1544 | if (mod != 3) { |
1511 | 1545 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
1512 | - gen_op_ld_T0_A0[ot](); | |
1513 | 1546 | opreg = OR_TMP0; |
1514 | 1547 | } else { |
1515 | 1548 | opreg = rm + OR_EAX; |
... | ... | @@ -1525,11 +1558,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1525 | 1558 | val = (int8_t)insn_get(s, OT_BYTE); |
1526 | 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 | 1564 | break; |
1535 | 1565 | |
... | ... | @@ -1577,12 +1607,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1577 | 1607 | } |
1578 | 1608 | break; |
1579 | 1609 | case 3: /* neg */ |
1580 | - gen_op_negl_T0_cc(); | |
1610 | + gen_op_negl_T0(); | |
1581 | 1611 | if (mod != 3) { |
1582 | 1612 | gen_op_st_T0_A0[ot](); |
1583 | 1613 | } else { |
1584 | 1614 | gen_op_mov_reg_T0[ot][rm](); |
1585 | 1615 | } |
1616 | + gen_op_update_neg_cc(); | |
1586 | 1617 | s->cc_op = CC_OP_SUBB + ot; |
1587 | 1618 | break; |
1588 | 1619 | case 4: /* mul */ |
... | ... | @@ -1664,7 +1695,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1664 | 1695 | } |
1665 | 1696 | if (mod != 3) { |
1666 | 1697 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
1667 | - if (op != 3 && op != 5) | |
1698 | + if (op >= 2 && op != 3 && op != 5) | |
1668 | 1699 | gen_op_ld_T0_A0[ot](); |
1669 | 1700 | } else { |
1670 | 1701 | gen_op_mov_TN_reg[ot][0][rm](); |
... | ... | @@ -1672,18 +1703,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1672 | 1703 | |
1673 | 1704 | switch(op) { |
1674 | 1705 | case 0: /* inc Ev */ |
1675 | - gen_inc(s, ot, OR_TMP0, 1); | |
1676 | 1706 | if (mod != 3) |
1677 | - gen_op_st_T0_A0[ot](); | |
1707 | + opreg = OR_TMP0; | |
1678 | 1708 | else |
1679 | - gen_op_mov_reg_T0[ot][rm](); | |
1709 | + opreg = rm; | |
1710 | + gen_inc(s, ot, opreg, 1); | |
1680 | 1711 | break; |
1681 | 1712 | case 1: /* dec Ev */ |
1682 | - gen_inc(s, ot, OR_TMP0, -1); | |
1683 | 1713 | if (mod != 3) |
1684 | - gen_op_st_T0_A0[ot](); | |
1714 | + opreg = OR_TMP0; | |
1685 | 1715 | else |
1686 | - gen_op_mov_reg_T0[ot][rm](); | |
1716 | + opreg = rm; | |
1717 | + gen_inc(s, ot, opreg, -1); | |
1687 | 1718 | break; |
1688 | 1719 | case 2: /* call Ev */ |
1689 | 1720 | /* XXX: optimize if memory (no and is necessary) */ |
... | ... | @@ -1822,17 +1853,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
1822 | 1853 | rm = modrm & 7; |
1823 | 1854 | gen_op_mov_TN_reg[ot][0][reg](); |
1824 | 1855 | gen_op_mov_TN_reg[ot][1][rm](); |
1825 | - gen_op_addl_T0_T1_cc(); | |
1856 | + gen_op_addl_T0_T1(); | |
1826 | 1857 | gen_op_mov_reg_T0[ot][rm](); |
1827 | 1858 | gen_op_mov_reg_T1[ot][reg](); |
1828 | 1859 | } else { |
1829 | 1860 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
1830 | 1861 | gen_op_mov_TN_reg[ot][0][reg](); |
1831 | 1862 | gen_op_ld_T1_A0[ot](); |
1832 | - gen_op_addl_T0_T1_cc(); | |
1863 | + gen_op_addl_T0_T1(); | |
1833 | 1864 | gen_op_st_T0_A0[ot](); |
1834 | 1865 | gen_op_mov_reg_T1[ot][reg](); |
1835 | 1866 | } |
1867 | + gen_op_update2_cc(); | |
1836 | 1868 | s->cc_op = CC_OP_ADDB + ot; |
1837 | 1869 | break; |
1838 | 1870 | case 0x1b0: |
... | ... | @@ -3607,8 +3639,7 @@ static uint16_t opc_read_flags[NB_OPS] = { |
3607 | 3639 | [INDEX_op_sbbl_T0_T1_cc] = CC_C, |
3608 | 3640 | |
3609 | 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 | 3644 | [INDEX_op_into] = CC_O, |
3614 | 3645 | |
... | ... | @@ -3688,22 +3719,18 @@ static uint16_t opc_read_flags[NB_OPS] = { |
3688 | 3719 | |
3689 | 3720 | /* flags written by an operation */ |
3690 | 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 | 3724 | [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC, |
3694 | 3725 | [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC, |
3695 | 3726 | [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC, |
3696 | 3727 | [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC, |
3697 | 3728 | [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC, |
3698 | 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 | 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 | 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 | 3734 | [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, |
3708 | 3735 | |
3709 | 3736 | [INDEX_op_mulb_AL_T0] = CC_OSZAPC, |
... | ... | @@ -3812,14 +3839,10 @@ static uint16_t opc_write_flags[NB_OPS] = { |
3812 | 3839 | |
3813 | 3840 | /* simpler form of an operation if no flags need to be generated */ |
3814 | 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 | 3847 | [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1, |
3825 | 3848 | [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1, | ... | ... |