Commit 6e0d8677cb443e7408c0b7a25a93c6596d7fa380
1 parent
cd31fefa
converted string OPs and LOOP insns to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4494 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
147 additions
and
294 deletions
target-i386/op.c
| ... | ... | @@ -263,55 +263,6 @@ void OPPROTO op_cmpxchg8b(void) |
| 263 | 263 | |
| 264 | 264 | #endif |
| 265 | 265 | |
| 266 | -/* string ops helpers */ | |
| 267 | - | |
| 268 | -void OPPROTO op_addl_ESI_T0(void) | |
| 269 | -{ | |
| 270 | - ESI = (uint32_t)(ESI + T0); | |
| 271 | -} | |
| 272 | - | |
| 273 | -void OPPROTO op_addw_ESI_T0(void) | |
| 274 | -{ | |
| 275 | - ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff); | |
| 276 | -} | |
| 277 | - | |
| 278 | -void OPPROTO op_addl_EDI_T0(void) | |
| 279 | -{ | |
| 280 | - EDI = (uint32_t)(EDI + T0); | |
| 281 | -} | |
| 282 | - | |
| 283 | -void OPPROTO op_addw_EDI_T0(void) | |
| 284 | -{ | |
| 285 | - EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff); | |
| 286 | -} | |
| 287 | - | |
| 288 | -void OPPROTO op_decl_ECX(void) | |
| 289 | -{ | |
| 290 | - ECX = (uint32_t)(ECX - 1); | |
| 291 | -} | |
| 292 | - | |
| 293 | -void OPPROTO op_decw_ECX(void) | |
| 294 | -{ | |
| 295 | - ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff); | |
| 296 | -} | |
| 297 | - | |
| 298 | -#ifdef TARGET_X86_64 | |
| 299 | -void OPPROTO op_addq_ESI_T0(void) | |
| 300 | -{ | |
| 301 | - ESI = (ESI + T0); | |
| 302 | -} | |
| 303 | - | |
| 304 | -void OPPROTO op_addq_EDI_T0(void) | |
| 305 | -{ | |
| 306 | - EDI = (EDI + T0); | |
| 307 | -} | |
| 308 | - | |
| 309 | -void OPPROTO op_decq_ECX(void) | |
| 310 | -{ | |
| 311 | - ECX--; | |
| 312 | -} | |
| 313 | -#endif | |
| 314 | - | |
| 315 | 266 | /* bcd */ |
| 316 | 267 | |
| 317 | 268 | void OPPROTO op_aam(void) |
| ... | ... | @@ -460,13 +411,6 @@ void OPPROTO op_jnz_T0_label(void) |
| 460 | 411 | FORCE_RET(); |
| 461 | 412 | } |
| 462 | 413 | |
| 463 | -void OPPROTO op_jz_T0_label(void) | |
| 464 | -{ | |
| 465 | - if (!T0) | |
| 466 | - GOTO_LABEL_PARAM(1); | |
| 467 | - FORCE_RET(); | |
| 468 | -} | |
| 469 | - | |
| 470 | 414 | /* slow set cases (compute x86 flags) */ |
| 471 | 415 | void OPPROTO op_seto_T0_cc(void) |
| 472 | 416 | { |
| ... | ... | @@ -527,11 +471,6 @@ void OPPROTO op_xor_T0_1(void) |
| 527 | 471 | T0 ^= 1; |
| 528 | 472 | } |
| 529 | 473 | |
| 530 | -void OPPROTO op_mov_T0_cc(void) | |
| 531 | -{ | |
| 532 | - T0 = cc_table[CC_OP].compute_all(); | |
| 533 | -} | |
| 534 | - | |
| 535 | 474 | /* XXX: clear VIF/VIP in all ops ? */ |
| 536 | 475 | |
| 537 | 476 | void OPPROTO op_movl_eflags_T0(void) | ... | ... |
target-i386/ops_template.h
| ... | ... | @@ -118,40 +118,6 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void) |
| 118 | 118 | FORCE_RET(); |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | -/* oldies */ | |
| 122 | - | |
| 123 | -#if DATA_BITS >= 16 | |
| 124 | - | |
| 125 | -void OPPROTO glue(op_loopnz, SUFFIX)(void) | |
| 126 | -{ | |
| 127 | - if ((DATA_TYPE)ECX != 0 && !(T0 & CC_Z)) | |
| 128 | - GOTO_LABEL_PARAM(1); | |
| 129 | - FORCE_RET(); | |
| 130 | -} | |
| 131 | - | |
| 132 | -void OPPROTO glue(op_loopz, SUFFIX)(void) | |
| 133 | -{ | |
| 134 | - if ((DATA_TYPE)ECX != 0 && (T0 & CC_Z)) | |
| 135 | - GOTO_LABEL_PARAM(1); | |
| 136 | - FORCE_RET(); | |
| 137 | -} | |
| 138 | - | |
| 139 | -void OPPROTO glue(op_jz_ecx, SUFFIX)(void) | |
| 140 | -{ | |
| 141 | - if ((DATA_TYPE)ECX == 0) | |
| 142 | - GOTO_LABEL_PARAM(1); | |
| 143 | - FORCE_RET(); | |
| 144 | -} | |
| 145 | - | |
| 146 | -void OPPROTO glue(op_jnz_ecx, SUFFIX)(void) | |
| 147 | -{ | |
| 148 | - if ((DATA_TYPE)ECX != 0) | |
| 149 | - GOTO_LABEL_PARAM(1); | |
| 150 | - FORCE_RET(); | |
| 151 | -} | |
| 152 | - | |
| 153 | -#endif | |
| 154 | - | |
| 155 | 121 | /* various optimized set cases */ |
| 156 | 122 | |
| 157 | 123 | void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) |
| ... | ... | @@ -200,13 +166,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) |
| 200 | 166 | T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); |
| 201 | 167 | } |
| 202 | 168 | |
| 203 | -/* string operations */ | |
| 204 | - | |
| 205 | -void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void) | |
| 206 | -{ | |
| 207 | - T0 = DF << SHIFT; | |
| 208 | -} | |
| 209 | - | |
| 210 | 169 | #undef DATA_BITS |
| 211 | 170 | #undef SHIFT_MASK |
| 212 | 171 | #undef SHIFT1_MASK | ... | ... |
target-i386/translate.c
| ... | ... | @@ -402,31 +402,57 @@ static inline void gen_op_jmp_T0(void) |
| 402 | 402 | tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip)); |
| 403 | 403 | } |
| 404 | 404 | |
| 405 | -static inline void gen_op_addw_ESP_im(int32_t val) | |
| 405 | +static inline void gen_op_add_reg_im(int size, int reg, int32_t val) | |
| 406 | 406 | { |
| 407 | - tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP])); | |
| 408 | - tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 409 | - tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]) + REG_W_OFFSET); | |
| 407 | + switch(size) { | |
| 408 | + case 0: | |
| 409 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 410 | + tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 411 | + tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET); | |
| 412 | + break; | |
| 413 | + case 1: | |
| 414 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 415 | + tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 416 | +#ifdef TARGET_X86_64 | |
| 417 | + tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff); | |
| 418 | +#endif | |
| 419 | + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 420 | + break; | |
| 421 | +#ifdef TARGET_X86_64 | |
| 422 | + case 2: | |
| 423 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 424 | + tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 425 | + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 426 | + break; | |
| 427 | +#endif | |
| 428 | + } | |
| 410 | 429 | } |
| 411 | 430 | |
| 412 | -static inline void gen_op_addl_ESP_im(int32_t val) | |
| 431 | +static inline void gen_op_add_reg_T0(int size, int reg) | |
| 413 | 432 | { |
| 414 | - tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP])); | |
| 415 | - tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 433 | + switch(size) { | |
| 434 | + case 0: | |
| 435 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 436 | + tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); | |
| 437 | + tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET); | |
| 438 | + break; | |
| 439 | + case 1: | |
| 440 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 441 | + tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); | |
| 416 | 442 | #ifdef TARGET_X86_64 |
| 417 | - tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff); | |
| 443 | + tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff); | |
| 418 | 444 | #endif |
| 419 | - tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP])); | |
| 420 | -} | |
| 421 | - | |
| 445 | + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 446 | + break; | |
| 422 | 447 | #ifdef TARGET_X86_64 |
| 423 | -static inline void gen_op_addq_ESP_im(int32_t val) | |
| 424 | -{ | |
| 425 | - tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP])); | |
| 426 | - tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); | |
| 427 | - tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP])); | |
| 428 | -} | |
| 448 | + case 2: | |
| 449 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 450 | + tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); | |
| 451 | + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg])); | |
| 452 | + break; | |
| 429 | 453 | #endif |
| 454 | + } | |
| 455 | +} | |
| 430 | 456 | |
| 431 | 457 | static inline void gen_op_set_cc_op(int32_t val) |
| 432 | 458 | { |
| ... | ... | @@ -663,30 +689,59 @@ static inline void gen_string_movl_A0_EDI(DisasContext *s) |
| 663 | 689 | } |
| 664 | 690 | } |
| 665 | 691 | |
| 666 | -static GenOpFunc *gen_op_movl_T0_Dshift[4] = { | |
| 667 | - gen_op_movl_T0_Dshiftb, | |
| 668 | - gen_op_movl_T0_Dshiftw, | |
| 669 | - gen_op_movl_T0_Dshiftl, | |
| 670 | - X86_64_ONLY(gen_op_movl_T0_Dshiftq), | |
| 692 | +static inline void gen_op_movl_T0_Dshift(int ot) | |
| 693 | +{ | |
| 694 | + tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df)); | |
| 695 | + tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot); | |
| 671 | 696 | }; |
| 672 | 697 | |
| 673 | -static GenOpFunc1 *gen_op_jnz_ecx[3] = { | |
| 674 | - gen_op_jnz_ecxw, | |
| 675 | - gen_op_jnz_ecxl, | |
| 676 | - X86_64_ONLY(gen_op_jnz_ecxq), | |
| 677 | -}; | |
| 698 | +static void gen_extu(int ot, TCGv reg) | |
| 699 | +{ | |
| 700 | + switch(ot) { | |
| 701 | + case OT_BYTE: | |
| 702 | + tcg_gen_ext8u_tl(reg, reg); | |
| 703 | + break; | |
| 704 | + case OT_WORD: | |
| 705 | + tcg_gen_ext16u_tl(reg, reg); | |
| 706 | + break; | |
| 707 | + case OT_LONG: | |
| 708 | + tcg_gen_ext32u_tl(reg, reg); | |
| 709 | + break; | |
| 710 | + default: | |
| 711 | + break; | |
| 712 | + } | |
| 713 | +} | |
| 678 | 714 | |
| 679 | -static GenOpFunc1 *gen_op_jz_ecx[3] = { | |
| 680 | - gen_op_jz_ecxw, | |
| 681 | - gen_op_jz_ecxl, | |
| 682 | - X86_64_ONLY(gen_op_jz_ecxq), | |
| 683 | -}; | |
| 715 | +static void gen_exts(int ot, TCGv reg) | |
| 716 | +{ | |
| 717 | + switch(ot) { | |
| 718 | + case OT_BYTE: | |
| 719 | + tcg_gen_ext8s_tl(reg, reg); | |
| 720 | + break; | |
| 721 | + case OT_WORD: | |
| 722 | + tcg_gen_ext16s_tl(reg, reg); | |
| 723 | + break; | |
| 724 | + case OT_LONG: | |
| 725 | + tcg_gen_ext32s_tl(reg, reg); | |
| 726 | + break; | |
| 727 | + default: | |
| 728 | + break; | |
| 729 | + } | |
| 730 | +} | |
| 684 | 731 | |
| 685 | -static GenOpFunc *gen_op_dec_ECX[3] = { | |
| 686 | - gen_op_decw_ECX, | |
| 687 | - gen_op_decl_ECX, | |
| 688 | - X86_64_ONLY(gen_op_decq_ECX), | |
| 689 | -}; | |
| 732 | +static inline void gen_op_jnz_ecx(int size, int label1) | |
| 733 | +{ | |
| 734 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX])); | |
| 735 | + gen_extu(size + 1, cpu_tmp0); | |
| 736 | + tcg_gen_brcond_tl(TCG_COND_NE, cpu_tmp0, tcg_const_tl(0), label1); | |
| 737 | +} | |
| 738 | + | |
| 739 | +static inline void gen_op_jz_ecx(int size, int label1) | |
| 740 | +{ | |
| 741 | + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX])); | |
| 742 | + gen_extu(size + 1, cpu_tmp0); | |
| 743 | + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), label1); | |
| 744 | +} | |
| 690 | 745 | |
| 691 | 746 | static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = { |
| 692 | 747 | { |
| ... | ... | @@ -760,20 +815,9 @@ static inline void gen_movs(DisasContext *s, int ot) |
| 760 | 815 | gen_op_ld_T0_A0(ot + s->mem_index); |
| 761 | 816 | gen_string_movl_A0_EDI(s); |
| 762 | 817 | gen_op_st_T0_A0(ot + s->mem_index); |
| 763 | - gen_op_movl_T0_Dshift[ot](); | |
| 764 | -#ifdef TARGET_X86_64 | |
| 765 | - if (s->aflag == 2) { | |
| 766 | - gen_op_addq_ESI_T0(); | |
| 767 | - gen_op_addq_EDI_T0(); | |
| 768 | - } else | |
| 769 | -#endif | |
| 770 | - if (s->aflag) { | |
| 771 | - gen_op_addl_ESI_T0(); | |
| 772 | - gen_op_addl_EDI_T0(); | |
| 773 | - } else { | |
| 774 | - gen_op_addw_ESI_T0(); | |
| 775 | - gen_op_addw_EDI_T0(); | |
| 776 | - } | |
| 818 | + gen_op_movl_T0_Dshift(ot); | |
| 819 | + gen_op_add_reg_T0(s->aflag, R_ESI); | |
| 820 | + gen_op_add_reg_T0(s->aflag, R_EDI); | |
| 777 | 821 | } |
| 778 | 822 | |
| 779 | 823 | static inline void gen_update_cc_op(DisasContext *s) |
| ... | ... | @@ -822,7 +866,7 @@ static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip) |
| 822 | 866 | |
| 823 | 867 | l1 = gen_new_label(); |
| 824 | 868 | l2 = gen_new_label(); |
| 825 | - gen_op_jnz_ecx[s->aflag](l1); | |
| 869 | + gen_op_jnz_ecx(s->aflag, l1); | |
| 826 | 870 | gen_set_label(l2); |
| 827 | 871 | gen_jmp_tb(s, next_eip, 1); |
| 828 | 872 | gen_set_label(l1); |
| ... | ... | @@ -834,17 +878,8 @@ static inline void gen_stos(DisasContext *s, int ot) |
| 834 | 878 | gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); |
| 835 | 879 | gen_string_movl_A0_EDI(s); |
| 836 | 880 | gen_op_st_T0_A0(ot + s->mem_index); |
| 837 | - gen_op_movl_T0_Dshift[ot](); | |
| 838 | -#ifdef TARGET_X86_64 | |
| 839 | - if (s->aflag == 2) { | |
| 840 | - gen_op_addq_EDI_T0(); | |
| 841 | - } else | |
| 842 | -#endif | |
| 843 | - if (s->aflag) { | |
| 844 | - gen_op_addl_EDI_T0(); | |
| 845 | - } else { | |
| 846 | - gen_op_addw_EDI_T0(); | |
| 847 | - } | |
| 881 | + gen_op_movl_T0_Dshift(ot); | |
| 882 | + gen_op_add_reg_T0(s->aflag, R_EDI); | |
| 848 | 883 | } |
| 849 | 884 | |
| 850 | 885 | static inline void gen_lods(DisasContext *s, int ot) |
| ... | ... | @@ -852,17 +887,8 @@ static inline void gen_lods(DisasContext *s, int ot) |
| 852 | 887 | gen_string_movl_A0_ESI(s); |
| 853 | 888 | gen_op_ld_T0_A0(ot + s->mem_index); |
| 854 | 889 | gen_op_mov_reg_T0(ot, R_EAX); |
| 855 | - gen_op_movl_T0_Dshift[ot](); | |
| 856 | -#ifdef TARGET_X86_64 | |
| 857 | - if (s->aflag == 2) { | |
| 858 | - gen_op_addq_ESI_T0(); | |
| 859 | - } else | |
| 860 | -#endif | |
| 861 | - if (s->aflag) { | |
| 862 | - gen_op_addl_ESI_T0(); | |
| 863 | - } else { | |
| 864 | - gen_op_addw_ESI_T0(); | |
| 865 | - } | |
| 890 | + gen_op_movl_T0_Dshift(ot); | |
| 891 | + gen_op_add_reg_T0(s->aflag, R_ESI); | |
| 866 | 892 | } |
| 867 | 893 | |
| 868 | 894 | static inline void gen_scas(DisasContext *s, int ot) |
| ... | ... | @@ -871,17 +897,8 @@ static inline void gen_scas(DisasContext *s, int ot) |
| 871 | 897 | gen_string_movl_A0_EDI(s); |
| 872 | 898 | gen_op_ld_T1_A0(ot + s->mem_index); |
| 873 | 899 | gen_op_cmpl_T0_T1_cc(); |
| 874 | - gen_op_movl_T0_Dshift[ot](); | |
| 875 | -#ifdef TARGET_X86_64 | |
| 876 | - if (s->aflag == 2) { | |
| 877 | - gen_op_addq_EDI_T0(); | |
| 878 | - } else | |
| 879 | -#endif | |
| 880 | - if (s->aflag) { | |
| 881 | - gen_op_addl_EDI_T0(); | |
| 882 | - } else { | |
| 883 | - gen_op_addw_EDI_T0(); | |
| 884 | - } | |
| 900 | + gen_op_movl_T0_Dshift(ot); | |
| 901 | + gen_op_add_reg_T0(s->aflag, R_EDI); | |
| 885 | 902 | } |
| 886 | 903 | |
| 887 | 904 | static inline void gen_cmps(DisasContext *s, int ot) |
| ... | ... | @@ -891,25 +908,16 @@ static inline void gen_cmps(DisasContext *s, int ot) |
| 891 | 908 | gen_string_movl_A0_EDI(s); |
| 892 | 909 | gen_op_ld_T1_A0(ot + s->mem_index); |
| 893 | 910 | gen_op_cmpl_T0_T1_cc(); |
| 894 | - gen_op_movl_T0_Dshift[ot](); | |
| 895 | -#ifdef TARGET_X86_64 | |
| 896 | - if (s->aflag == 2) { | |
| 897 | - gen_op_addq_ESI_T0(); | |
| 898 | - gen_op_addq_EDI_T0(); | |
| 899 | - } else | |
| 900 | -#endif | |
| 901 | - if (s->aflag) { | |
| 902 | - gen_op_addl_ESI_T0(); | |
| 903 | - gen_op_addl_EDI_T0(); | |
| 904 | - } else { | |
| 905 | - gen_op_addw_ESI_T0(); | |
| 906 | - gen_op_addw_EDI_T0(); | |
| 907 | - } | |
| 911 | + gen_op_movl_T0_Dshift(ot); | |
| 912 | + gen_op_add_reg_T0(s->aflag, R_ESI); | |
| 913 | + gen_op_add_reg_T0(s->aflag, R_EDI); | |
| 908 | 914 | } |
| 909 | 915 | |
| 910 | 916 | static inline void gen_ins(DisasContext *s, int ot) |
| 911 | 917 | { |
| 912 | 918 | gen_string_movl_A0_EDI(s); |
| 919 | + /* Note: we must do this dummy write first to be restartable in | |
| 920 | + case of page fault. */ | |
| 913 | 921 | gen_op_movl_T0_0(); |
| 914 | 922 | gen_op_st_T0_A0(ot + s->mem_index); |
| 915 | 923 | gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); |
| ... | ... | @@ -917,17 +925,8 @@ static inline void gen_ins(DisasContext *s, int ot) |
| 917 | 925 | tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); |
| 918 | 926 | tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32); |
| 919 | 927 | gen_op_st_T0_A0(ot + s->mem_index); |
| 920 | - gen_op_movl_T0_Dshift[ot](); | |
| 921 | -#ifdef TARGET_X86_64 | |
| 922 | - if (s->aflag == 2) { | |
| 923 | - gen_op_addq_EDI_T0(); | |
| 924 | - } else | |
| 925 | -#endif | |
| 926 | - if (s->aflag) { | |
| 927 | - gen_op_addl_EDI_T0(); | |
| 928 | - } else { | |
| 929 | - gen_op_addw_EDI_T0(); | |
| 930 | - } | |
| 928 | + gen_op_movl_T0_Dshift(ot); | |
| 929 | + gen_op_add_reg_T0(s->aflag, R_EDI); | |
| 931 | 930 | } |
| 932 | 931 | |
| 933 | 932 | static inline void gen_outs(DisasContext *s, int ot) |
| ... | ... | @@ -941,17 +940,8 @@ static inline void gen_outs(DisasContext *s, int ot) |
| 941 | 940 | tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]); |
| 942 | 941 | tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32); |
| 943 | 942 | |
| 944 | - gen_op_movl_T0_Dshift[ot](); | |
| 945 | -#ifdef TARGET_X86_64 | |
| 946 | - if (s->aflag == 2) { | |
| 947 | - gen_op_addq_ESI_T0(); | |
| 948 | - } else | |
| 949 | -#endif | |
| 950 | - if (s->aflag) { | |
| 951 | - gen_op_addl_ESI_T0(); | |
| 952 | - } else { | |
| 953 | - gen_op_addw_ESI_T0(); | |
| 954 | - } | |
| 943 | + gen_op_movl_T0_Dshift(ot); | |
| 944 | + gen_op_add_reg_T0(s->aflag, R_ESI); | |
| 955 | 945 | } |
| 956 | 946 | |
| 957 | 947 | /* same method as Valgrind : we generate jumps to current or next |
| ... | ... | @@ -964,11 +954,11 @@ static inline void gen_repz_ ## op(DisasContext *s, int ot, \ |
| 964 | 954 | gen_update_cc_op(s); \ |
| 965 | 955 | l2 = gen_jz_ecx_string(s, next_eip); \ |
| 966 | 956 | gen_ ## op(s, ot); \ |
| 967 | - gen_op_dec_ECX[s->aflag](); \ | |
| 957 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); \ | |
| 968 | 958 | /* a loop would cause two single step exceptions if ECX = 1 \ |
| 969 | 959 | before rep string_insn */ \ |
| 970 | 960 | if (!s->jmp_opt) \ |
| 971 | - gen_op_jz_ecx[s->aflag](l2); \ | |
| 961 | + gen_op_jz_ecx(s->aflag, l2); \ | |
| 972 | 962 | gen_jmp(s, cur_eip); \ |
| 973 | 963 | } |
| 974 | 964 | |
| ... | ... | @@ -982,11 +972,11 @@ static inline void gen_repz_ ## op(DisasContext *s, int ot, \ |
| 982 | 972 | gen_update_cc_op(s); \ |
| 983 | 973 | l2 = gen_jz_ecx_string(s, next_eip); \ |
| 984 | 974 | gen_ ## op(s, ot); \ |
| 985 | - gen_op_dec_ECX[s->aflag](); \ | |
| 975 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); \ | |
| 986 | 976 | gen_op_set_cc_op(CC_OP_SUBB + ot); \ |
| 987 | 977 | gen_op_string_jnz_sub[nz][ot](l2);\ |
| 988 | 978 | if (!s->jmp_opt) \ |
| 989 | - gen_op_jz_ecx[s->aflag](l2); \ | |
| 979 | + gen_op_jz_ecx(s->aflag, l2); \ | |
| 990 | 980 | gen_jmp(s, cur_eip); \ |
| 991 | 981 | } |
| 992 | 982 | |
| ... | ... | @@ -1053,25 +1043,6 @@ static GenOpFunc1 *gen_jcc_sub[4][8] = { |
| 1053 | 1043 | }, |
| 1054 | 1044 | #endif |
| 1055 | 1045 | }; |
| 1056 | -static GenOpFunc1 *gen_op_loop[3][4] = { | |
| 1057 | - [0] = { | |
| 1058 | - gen_op_loopnzw, | |
| 1059 | - gen_op_loopzw, | |
| 1060 | - gen_op_jnz_ecxw, | |
| 1061 | - }, | |
| 1062 | - [1] = { | |
| 1063 | - gen_op_loopnzl, | |
| 1064 | - gen_op_loopzl, | |
| 1065 | - gen_op_jnz_ecxl, | |
| 1066 | - }, | |
| 1067 | -#ifdef TARGET_X86_64 | |
| 1068 | - [2] = { | |
| 1069 | - gen_op_loopnzq, | |
| 1070 | - gen_op_loopzq, | |
| 1071 | - gen_op_jnz_ecxq, | |
| 1072 | - }, | |
| 1073 | -#endif | |
| 1074 | -}; | |
| 1075 | 1046 | |
| 1076 | 1047 | static GenOpFunc *gen_setcc_slow[8] = { |
| 1077 | 1048 | gen_op_seto_T0_cc, |
| ... | ... | @@ -1316,40 +1287,6 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) |
| 1316 | 1287 | tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); |
| 1317 | 1288 | } |
| 1318 | 1289 | |
| 1319 | -static void gen_extu(int ot, TCGv reg) | |
| 1320 | -{ | |
| 1321 | - switch(ot) { | |
| 1322 | - case OT_BYTE: | |
| 1323 | - tcg_gen_ext8u_tl(reg, reg); | |
| 1324 | - break; | |
| 1325 | - case OT_WORD: | |
| 1326 | - tcg_gen_ext16u_tl(reg, reg); | |
| 1327 | - break; | |
| 1328 | - case OT_LONG: | |
| 1329 | - tcg_gen_ext32u_tl(reg, reg); | |
| 1330 | - break; | |
| 1331 | - default: | |
| 1332 | - break; | |
| 1333 | - } | |
| 1334 | -} | |
| 1335 | - | |
| 1336 | -static void gen_exts(int ot, TCGv reg) | |
| 1337 | -{ | |
| 1338 | - switch(ot) { | |
| 1339 | - case OT_BYTE: | |
| 1340 | - tcg_gen_ext8s_tl(reg, reg); | |
| 1341 | - break; | |
| 1342 | - case OT_WORD: | |
| 1343 | - tcg_gen_ext16s_tl(reg, reg); | |
| 1344 | - break; | |
| 1345 | - case OT_LONG: | |
| 1346 | - tcg_gen_ext32s_tl(reg, reg); | |
| 1347 | - break; | |
| 1348 | - default: | |
| 1349 | - break; | |
| 1350 | - } | |
| 1351 | -} | |
| 1352 | - | |
| 1353 | 1290 | /* XXX: add faster immediate case */ |
| 1354 | 1291 | static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, |
| 1355 | 1292 | int is_right, int is_arith) |
| ... | ... | @@ -2318,13 +2255,13 @@ static inline void gen_stack_update(DisasContext *s, int addend) |
| 2318 | 2255 | { |
| 2319 | 2256 | #ifdef TARGET_X86_64 |
| 2320 | 2257 | if (CODE64(s)) { |
| 2321 | - gen_op_addq_ESP_im(addend); | |
| 2258 | + gen_op_add_reg_im(2, R_ESP, addend); | |
| 2322 | 2259 | } else |
| 2323 | 2260 | #endif |
| 2324 | 2261 | if (s->ss32) { |
| 2325 | - gen_op_addl_ESP_im(addend); | |
| 2262 | + gen_op_add_reg_im(1, R_ESP, addend); | |
| 2326 | 2263 | } else { |
| 2327 | - gen_op_addw_ESP_im(addend); | |
| 2264 | + gen_op_add_reg_im(0, R_ESP, addend); | |
| 2328 | 2265 | } |
| 2329 | 2266 | } |
| 2330 | 2267 | |
| ... | ... | @@ -6066,13 +6003,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6066 | 6003 | break; |
| 6067 | 6004 | case 0xe0: /* loopnz */ |
| 6068 | 6005 | case 0xe1: /* loopz */ |
| 6069 | - if (s->cc_op != CC_OP_DYNAMIC) | |
| 6070 | - gen_op_set_cc_op(s->cc_op); | |
| 6071 | - /* FALL THRU */ | |
| 6072 | 6006 | case 0xe2: /* loop */ |
| 6073 | 6007 | case 0xe3: /* jecxz */ |
| 6074 | 6008 | { |
| 6075 | - int l1, l2; | |
| 6009 | + int l1, l2, l3; | |
| 6076 | 6010 | |
| 6077 | 6011 | tval = (int8_t)insn_get(s, OT_BYTE); |
| 6078 | 6012 | next_eip = s->pc - s->cs_base; |
| ... | ... | @@ -6082,18 +6016,39 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6082 | 6016 | |
| 6083 | 6017 | l1 = gen_new_label(); |
| 6084 | 6018 | l2 = gen_new_label(); |
| 6019 | + l3 = gen_new_label(); | |
| 6085 | 6020 | b &= 3; |
| 6086 | - if (b == 3) { | |
| 6087 | - gen_op_jz_ecx[s->aflag](l1); | |
| 6088 | - } else { | |
| 6089 | - gen_op_dec_ECX[s->aflag](); | |
| 6090 | - if (b <= 1) | |
| 6091 | - gen_op_mov_T0_cc(); | |
| 6092 | - gen_op_loop[s->aflag][b](l1); | |
| 6021 | + switch(b) { | |
| 6022 | + case 0: /* loopnz */ | |
| 6023 | + case 1: /* loopz */ | |
| 6024 | + if (s->cc_op != CC_OP_DYNAMIC) | |
| 6025 | + gen_op_set_cc_op(s->cc_op); | |
| 6026 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); | |
| 6027 | + gen_op_jz_ecx(s->aflag, l3); | |
| 6028 | + gen_compute_eflags(cpu_tmp0); | |
| 6029 | + tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z); | |
| 6030 | + if (b == 0) { | |
| 6031 | + tcg_gen_brcond_tl(TCG_COND_EQ, | |
| 6032 | + cpu_tmp0, tcg_const_tl(0), l1); | |
| 6033 | + } else { | |
| 6034 | + tcg_gen_brcond_tl(TCG_COND_NE, | |
| 6035 | + cpu_tmp0, tcg_const_tl(0), l1); | |
| 6036 | + } | |
| 6037 | + break; | |
| 6038 | + case 2: /* loop */ | |
| 6039 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); | |
| 6040 | + gen_op_jnz_ecx(s->aflag, l1); | |
| 6041 | + break; | |
| 6042 | + default: | |
| 6043 | + case 3: /* jcxz */ | |
| 6044 | + gen_op_jz_ecx(s->aflag, l1); | |
| 6045 | + break; | |
| 6093 | 6046 | } |
| 6094 | 6047 | |
| 6048 | + gen_set_label(l3); | |
| 6095 | 6049 | gen_jmp_im(next_eip); |
| 6096 | 6050 | gen_op_jmp_label(l2); |
| 6051 | + | |
| 6097 | 6052 | gen_set_label(l1); |
| 6098 | 6053 | gen_jmp_im(tval); |
| 6099 | 6054 | gen_set_label(l2); | ... | ... |