Revision 6e0d8677 target-i386/translate.c
b/target-i386/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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); |
Also available in: Unified diff