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, | ... | ... |