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,55 +263,6 @@ void OPPROTO op_cmpxchg8b(void) | ||
263 | 263 | ||
264 | #endif | 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 | /* bcd */ | 266 | /* bcd */ |
316 | 267 | ||
317 | void OPPROTO op_aam(void) | 268 | void OPPROTO op_aam(void) |
@@ -460,13 +411,6 @@ void OPPROTO op_jnz_T0_label(void) | @@ -460,13 +411,6 @@ void OPPROTO op_jnz_T0_label(void) | ||
460 | FORCE_RET(); | 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 | /* slow set cases (compute x86 flags) */ | 414 | /* slow set cases (compute x86 flags) */ |
471 | void OPPROTO op_seto_T0_cc(void) | 415 | void OPPROTO op_seto_T0_cc(void) |
472 | { | 416 | { |
@@ -527,11 +471,6 @@ void OPPROTO op_xor_T0_1(void) | @@ -527,11 +471,6 @@ void OPPROTO op_xor_T0_1(void) | ||
527 | T0 ^= 1; | 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 | /* XXX: clear VIF/VIP in all ops ? */ | 474 | /* XXX: clear VIF/VIP in all ops ? */ |
536 | 475 | ||
537 | void OPPROTO op_movl_eflags_T0(void) | 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,40 +118,6 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void) | ||
118 | FORCE_RET(); | 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 | /* various optimized set cases */ | 121 | /* various optimized set cases */ |
156 | 122 | ||
157 | void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) | 123 | void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) |
@@ -200,13 +166,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) | @@ -200,13 +166,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) | ||
200 | T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); | 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 | #undef DATA_BITS | 169 | #undef DATA_BITS |
211 | #undef SHIFT_MASK | 170 | #undef SHIFT_MASK |
212 | #undef SHIFT1_MASK | 171 | #undef SHIFT1_MASK |
target-i386/translate.c
@@ -402,31 +402,57 @@ static inline void gen_op_jmp_T0(void) | @@ -402,31 +402,57 @@ static inline void gen_op_jmp_T0(void) | ||
402 | tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip)); | 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 | #ifdef TARGET_X86_64 | 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 | #endif | 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 | #ifdef TARGET_X86_64 | 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 | #endif | 453 | #endif |
454 | + } | ||
455 | +} | ||
430 | 456 | ||
431 | static inline void gen_op_set_cc_op(int32_t val) | 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,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 | static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = { | 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,20 +815,9 @@ static inline void gen_movs(DisasContext *s, int ot) | ||
760 | gen_op_ld_T0_A0(ot + s->mem_index); | 815 | gen_op_ld_T0_A0(ot + s->mem_index); |
761 | gen_string_movl_A0_EDI(s); | 816 | gen_string_movl_A0_EDI(s); |
762 | gen_op_st_T0_A0(ot + s->mem_index); | 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 | static inline void gen_update_cc_op(DisasContext *s) | 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,7 +866,7 @@ static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip) | ||
822 | 866 | ||
823 | l1 = gen_new_label(); | 867 | l1 = gen_new_label(); |
824 | l2 = gen_new_label(); | 868 | l2 = gen_new_label(); |
825 | - gen_op_jnz_ecx[s->aflag](l1); | 869 | + gen_op_jnz_ecx(s->aflag, l1); |
826 | gen_set_label(l2); | 870 | gen_set_label(l2); |
827 | gen_jmp_tb(s, next_eip, 1); | 871 | gen_jmp_tb(s, next_eip, 1); |
828 | gen_set_label(l1); | 872 | gen_set_label(l1); |
@@ -834,17 +878,8 @@ static inline void gen_stos(DisasContext *s, int ot) | @@ -834,17 +878,8 @@ static inline void gen_stos(DisasContext *s, int ot) | ||
834 | gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); | 878 | gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); |
835 | gen_string_movl_A0_EDI(s); | 879 | gen_string_movl_A0_EDI(s); |
836 | gen_op_st_T0_A0(ot + s->mem_index); | 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 | static inline void gen_lods(DisasContext *s, int ot) | 885 | static inline void gen_lods(DisasContext *s, int ot) |
@@ -852,17 +887,8 @@ static inline void gen_lods(DisasContext *s, int ot) | @@ -852,17 +887,8 @@ static inline void gen_lods(DisasContext *s, int ot) | ||
852 | gen_string_movl_A0_ESI(s); | 887 | gen_string_movl_A0_ESI(s); |
853 | gen_op_ld_T0_A0(ot + s->mem_index); | 888 | gen_op_ld_T0_A0(ot + s->mem_index); |
854 | gen_op_mov_reg_T0(ot, R_EAX); | 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 | static inline void gen_scas(DisasContext *s, int ot) | 894 | static inline void gen_scas(DisasContext *s, int ot) |
@@ -871,17 +897,8 @@ static inline void gen_scas(DisasContext *s, int ot) | @@ -871,17 +897,8 @@ static inline void gen_scas(DisasContext *s, int ot) | ||
871 | gen_string_movl_A0_EDI(s); | 897 | gen_string_movl_A0_EDI(s); |
872 | gen_op_ld_T1_A0(ot + s->mem_index); | 898 | gen_op_ld_T1_A0(ot + s->mem_index); |
873 | gen_op_cmpl_T0_T1_cc(); | 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 | static inline void gen_cmps(DisasContext *s, int ot) | 904 | static inline void gen_cmps(DisasContext *s, int ot) |
@@ -891,25 +908,16 @@ static inline void gen_cmps(DisasContext *s, int ot) | @@ -891,25 +908,16 @@ static inline void gen_cmps(DisasContext *s, int ot) | ||
891 | gen_string_movl_A0_EDI(s); | 908 | gen_string_movl_A0_EDI(s); |
892 | gen_op_ld_T1_A0(ot + s->mem_index); | 909 | gen_op_ld_T1_A0(ot + s->mem_index); |
893 | gen_op_cmpl_T0_T1_cc(); | 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 | static inline void gen_ins(DisasContext *s, int ot) | 916 | static inline void gen_ins(DisasContext *s, int ot) |
911 | { | 917 | { |
912 | gen_string_movl_A0_EDI(s); | 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 | gen_op_movl_T0_0(); | 921 | gen_op_movl_T0_0(); |
914 | gen_op_st_T0_A0(ot + s->mem_index); | 922 | gen_op_st_T0_A0(ot + s->mem_index); |
915 | gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); | 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,17 +925,8 @@ static inline void gen_ins(DisasContext *s, int ot) | ||
917 | tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); | 925 | tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); |
918 | tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32); | 926 | tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32); |
919 | gen_op_st_T0_A0(ot + s->mem_index); | 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 | static inline void gen_outs(DisasContext *s, int ot) | 932 | static inline void gen_outs(DisasContext *s, int ot) |
@@ -941,17 +940,8 @@ static inline void gen_outs(DisasContext *s, int ot) | @@ -941,17 +940,8 @@ static inline void gen_outs(DisasContext *s, int ot) | ||
941 | tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]); | 940 | tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]); |
942 | tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32); | 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 | /* same method as Valgrind : we generate jumps to current or next | 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,11 +954,11 @@ static inline void gen_repz_ ## op(DisasContext *s, int ot, \ | ||
964 | gen_update_cc_op(s); \ | 954 | gen_update_cc_op(s); \ |
965 | l2 = gen_jz_ecx_string(s, next_eip); \ | 955 | l2 = gen_jz_ecx_string(s, next_eip); \ |
966 | gen_ ## op(s, ot); \ | 956 | gen_ ## op(s, ot); \ |
967 | - gen_op_dec_ECX[s->aflag](); \ | 957 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); \ |
968 | /* a loop would cause two single step exceptions if ECX = 1 \ | 958 | /* a loop would cause two single step exceptions if ECX = 1 \ |
969 | before rep string_insn */ \ | 959 | before rep string_insn */ \ |
970 | if (!s->jmp_opt) \ | 960 | if (!s->jmp_opt) \ |
971 | - gen_op_jz_ecx[s->aflag](l2); \ | 961 | + gen_op_jz_ecx(s->aflag, l2); \ |
972 | gen_jmp(s, cur_eip); \ | 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,11 +972,11 @@ static inline void gen_repz_ ## op(DisasContext *s, int ot, \ | ||
982 | gen_update_cc_op(s); \ | 972 | gen_update_cc_op(s); \ |
983 | l2 = gen_jz_ecx_string(s, next_eip); \ | 973 | l2 = gen_jz_ecx_string(s, next_eip); \ |
984 | gen_ ## op(s, ot); \ | 974 | gen_ ## op(s, ot); \ |
985 | - gen_op_dec_ECX[s->aflag](); \ | 975 | + gen_op_add_reg_im(s->aflag, R_ECX, -1); \ |
986 | gen_op_set_cc_op(CC_OP_SUBB + ot); \ | 976 | gen_op_set_cc_op(CC_OP_SUBB + ot); \ |
987 | gen_op_string_jnz_sub[nz][ot](l2);\ | 977 | gen_op_string_jnz_sub[nz][ot](l2);\ |
988 | if (!s->jmp_opt) \ | 978 | if (!s->jmp_opt) \ |
989 | - gen_op_jz_ecx[s->aflag](l2); \ | 979 | + gen_op_jz_ecx(s->aflag, l2); \ |
990 | gen_jmp(s, cur_eip); \ | 980 | gen_jmp(s, cur_eip); \ |
991 | } | 981 | } |
992 | 982 | ||
@@ -1053,25 +1043,6 @@ static GenOpFunc1 *gen_jcc_sub[4][8] = { | @@ -1053,25 +1043,6 @@ static GenOpFunc1 *gen_jcc_sub[4][8] = { | ||
1053 | }, | 1043 | }, |
1054 | #endif | 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 | static GenOpFunc *gen_setcc_slow[8] = { | 1047 | static GenOpFunc *gen_setcc_slow[8] = { |
1077 | gen_op_seto_T0_cc, | 1048 | gen_op_seto_T0_cc, |
@@ -1316,40 +1287,6 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) | @@ -1316,40 +1287,6 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) | ||
1316 | tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); | 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 | /* XXX: add faster immediate case */ | 1290 | /* XXX: add faster immediate case */ |
1354 | static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, | 1291 | static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, |
1355 | int is_right, int is_arith) | 1292 | int is_right, int is_arith) |
@@ -2318,13 +2255,13 @@ static inline void gen_stack_update(DisasContext *s, int addend) | @@ -2318,13 +2255,13 @@ static inline void gen_stack_update(DisasContext *s, int addend) | ||
2318 | { | 2255 | { |
2319 | #ifdef TARGET_X86_64 | 2256 | #ifdef TARGET_X86_64 |
2320 | if (CODE64(s)) { | 2257 | if (CODE64(s)) { |
2321 | - gen_op_addq_ESP_im(addend); | 2258 | + gen_op_add_reg_im(2, R_ESP, addend); |
2322 | } else | 2259 | } else |
2323 | #endif | 2260 | #endif |
2324 | if (s->ss32) { | 2261 | if (s->ss32) { |
2325 | - gen_op_addl_ESP_im(addend); | 2262 | + gen_op_add_reg_im(1, R_ESP, addend); |
2326 | } else { | 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,13 +6003,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6066 | break; | 6003 | break; |
6067 | case 0xe0: /* loopnz */ | 6004 | case 0xe0: /* loopnz */ |
6068 | case 0xe1: /* loopz */ | 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 | case 0xe2: /* loop */ | 6006 | case 0xe2: /* loop */ |
6073 | case 0xe3: /* jecxz */ | 6007 | case 0xe3: /* jecxz */ |
6074 | { | 6008 | { |
6075 | - int l1, l2; | 6009 | + int l1, l2, l3; |
6076 | 6010 | ||
6077 | tval = (int8_t)insn_get(s, OT_BYTE); | 6011 | tval = (int8_t)insn_get(s, OT_BYTE); |
6078 | next_eip = s->pc - s->cs_base; | 6012 | next_eip = s->pc - s->cs_base; |
@@ -6082,18 +6016,39 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6082,18 +6016,39 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6082 | 6016 | ||
6083 | l1 = gen_new_label(); | 6017 | l1 = gen_new_label(); |
6084 | l2 = gen_new_label(); | 6018 | l2 = gen_new_label(); |
6019 | + l3 = gen_new_label(); | ||
6085 | b &= 3; | 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 | gen_jmp_im(next_eip); | 6049 | gen_jmp_im(next_eip); |
6096 | gen_op_jmp_label(l2); | 6050 | gen_op_jmp_label(l2); |
6051 | + | ||
6097 | gen_set_label(l1); | 6052 | gen_set_label(l1); |
6098 | gen_jmp_im(tval); | 6053 | gen_jmp_im(tval); |
6099 | gen_set_label(l2); | 6054 | gen_set_label(l2); |