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