Commit 6e0d8677cb443e7408c0b7a25a93c6596d7fa380

Authored by bellard
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
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);
... ...