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); | ... | ... |