Commit dbc5594cb6294f34c257df11bef484e45493f85e

Authored by bellard
1 parent 4cbb86e1

finished simplifying string operations - correct TF flag handling for string ope…

…rations and ss loading - simplified basic block exit code generation


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@381 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 247 additions and 296 deletions
translate-i386.c
@@ -60,11 +60,15 @@ typedef struct DisasContext { @@ -60,11 +60,15 @@ typedef struct DisasContext {
60 int cpl; 60 int cpl;
61 int iopl; 61 int iopl;
62 int tf; /* TF cpu flag */ 62 int tf; /* TF cpu flag */
  63 + int jmp_opt; /* use direct block chaining for direct jumps */
63 int mem_index; /* select memory access functions */ 64 int mem_index; /* select memory access functions */
64 struct TranslationBlock *tb; 65 struct TranslationBlock *tb;
65 int popl_esp_hack; /* for correct popl with esp base handling */ 66 int popl_esp_hack; /* for correct popl with esp base handling */
66 } DisasContext; 67 } DisasContext;
67 68
  69 +static void gen_eob(DisasContext *s);
  70 +static void gen_jmp(DisasContext *s, unsigned int eip);
  71 +
68 /* i386 arith/logic operations */ 72 /* i386 arith/logic operations */
69 enum { 73 enum {
70 OP_ADDL, 74 OP_ADDL,
@@ -635,31 +639,6 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { @@ -635,31 +639,6 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = {
635 gen_op_stl_user_T0_A0, 639 gen_op_stl_user_T0_A0,
636 }; 640 };
637 641
638 -/* the _a32 and _a16 string operations use A0 as the base register. */  
639 -  
640 -#define STRINGOP_NB 9  
641 -  
642 -#define STRINGOP(x) \  
643 - gen_op_ ## x ## b_fast, \  
644 - gen_op_ ## x ## w_fast, \  
645 - gen_op_ ## x ## l_fast, \  
646 - gen_op_ ## x ## b_a32, \  
647 - gen_op_ ## x ## w_a32, \  
648 - gen_op_ ## x ## l_a32, \  
649 - gen_op_ ## x ## b_a16, \  
650 - gen_op_ ## x ## w_a16, \  
651 - gen_op_ ## x ## l_a16,  
652 -  
653 -static GenOpFunc *gen_op_scas[STRINGOP_NB * 3] = {  
654 - STRINGOP(repz_scas)  
655 - STRINGOP(repnz_scas)  
656 -};  
657 -  
658 -static GenOpFunc *gen_op_cmps[STRINGOP_NB * 3] = {  
659 - STRINGOP(repz_cmps)  
660 - STRINGOP(repnz_cmps)  
661 -};  
662 -  
663 static inline void gen_string_movl_A0_ESI(DisasContext *s) 642 static inline void gen_string_movl_A0_ESI(DisasContext *s)
664 { 643 {
665 int override; 644 int override;
@@ -712,12 +691,17 @@ static GenOpFunc2 *gen_op_jz_ecx[2] = { @@ -712,12 +691,17 @@ static GenOpFunc2 *gen_op_jz_ecx[2] = {
712 gen_op_jz_ecxl, 691 gen_op_jz_ecxl,
713 }; 692 };
714 693
  694 +static GenOpFunc1 *gen_op_jz_ecx_im[2] = {
  695 + gen_op_jz_ecxw_im,
  696 + gen_op_jz_ecxl_im,
  697 +};
  698 +
715 static GenOpFunc *gen_op_dec_ECX[2] = { 699 static GenOpFunc *gen_op_dec_ECX[2] = {
716 gen_op_decw_ECX, 700 gen_op_decw_ECX,
717 gen_op_decl_ECX, 701 gen_op_decl_ECX,
718 }; 702 };
719 703
720 -static GenOpFunc2 *gen_op_string_jnz_sub[2][3] = { 704 +static GenOpFunc1 *gen_op_string_jnz_sub[2][3] = {
721 { 705 {
722 gen_op_string_jnz_subb, 706 gen_op_string_jnz_subb,
723 gen_op_string_jnz_subw, 707 gen_op_string_jnz_subw,
@@ -730,6 +714,19 @@ static GenOpFunc2 *gen_op_string_jnz_sub[2][3] = { @@ -730,6 +714,19 @@ static GenOpFunc2 *gen_op_string_jnz_sub[2][3] = {
730 }, 714 },
731 }; 715 };
732 716
  717 +static GenOpFunc1 *gen_op_string_jnz_sub_im[2][3] = {
  718 + {
  719 + gen_op_string_jnz_subb_im,
  720 + gen_op_string_jnz_subw_im,
  721 + gen_op_string_jnz_subl_im,
  722 + },
  723 + {
  724 + gen_op_string_jz_subb_im,
  725 + gen_op_string_jz_subw_im,
  726 + gen_op_string_jz_subl_im,
  727 + },
  728 +};
  729 +
733 static GenOpFunc *gen_op_in_DX_T0[3] = { 730 static GenOpFunc *gen_op_in_DX_T0[3] = {
734 gen_op_inb_DX_T0, 731 gen_op_inb_DX_T0,
735 gen_op_inw_DX_T0, 732 gen_op_inw_DX_T0,
@@ -758,18 +755,23 @@ static inline void gen_movs(DisasContext *s, int ot) @@ -758,18 +755,23 @@ static inline void gen_movs(DisasContext *s, int ot)
758 } 755 }
759 } 756 }
760 757
761 -/* same method as Valgrind : we generate jumps to current or next  
762 - instruction */  
763 -static inline void gen_repz_movs(DisasContext *s, int ot,  
764 - unsigned int cur_eip, unsigned int next_eip) 758 +static inline void gen_update_cc_op(DisasContext *s)
765 { 759 {
766 - if (s->cc_op != CC_OP_DYNAMIC) 760 + if (s->cc_op != CC_OP_DYNAMIC) {
767 gen_op_set_cc_op(s->cc_op); 761 gen_op_set_cc_op(s->cc_op);
768 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
769 - gen_movs(s, ot);  
770 - gen_op_dec_ECX[s->aflag]();  
771 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
772 - s->is_jmp = 3; 762 + s->cc_op = CC_OP_DYNAMIC;
  763 + }
  764 +}
  765 +
  766 +static inline void gen_jz_ecx_string(DisasContext *s, unsigned int next_eip)
  767 +{
  768 + if (s->jmp_opt) {
  769 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  770 + } else {
  771 + /* XXX: does not work with gdbstub "ice" single step - not a
  772 + serious problem */
  773 + gen_op_jz_ecx_im[s->aflag](next_eip);
  774 + }
773 } 775 }
774 776
775 static inline void gen_stos(DisasContext *s, int ot) 777 static inline void gen_stos(DisasContext *s, int ot)
@@ -785,18 +787,6 @@ static inline void gen_stos(DisasContext *s, int ot) @@ -785,18 +787,6 @@ static inline void gen_stos(DisasContext *s, int ot)
785 } 787 }
786 } 788 }
787 789
788 -static inline void gen_repz_stos(DisasContext *s, int ot,  
789 - unsigned int cur_eip, unsigned int next_eip)  
790 -{  
791 - if (s->cc_op != CC_OP_DYNAMIC)  
792 - gen_op_set_cc_op(s->cc_op);  
793 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
794 - gen_stos(s, ot);  
795 - gen_op_dec_ECX[s->aflag]();  
796 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
797 - s->is_jmp = 3;  
798 -}  
799 -  
800 static inline void gen_lods(DisasContext *s, int ot) 790 static inline void gen_lods(DisasContext *s, int ot)
801 { 791 {
802 gen_string_movl_A0_ESI(s); 792 gen_string_movl_A0_ESI(s);
@@ -810,18 +800,6 @@ static inline void gen_lods(DisasContext *s, int ot) @@ -810,18 +800,6 @@ static inline void gen_lods(DisasContext *s, int ot)
810 } 800 }
811 } 801 }
812 802
813 -static inline void gen_repz_lods(DisasContext *s, int ot,  
814 - unsigned int cur_eip, unsigned int next_eip)  
815 -{  
816 - if (s->cc_op != CC_OP_DYNAMIC)  
817 - gen_op_set_cc_op(s->cc_op);  
818 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
819 - gen_lods(s, ot);  
820 - gen_op_dec_ECX[s->aflag]();  
821 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
822 - s->is_jmp = 3;  
823 -}  
824 -  
825 static inline void gen_scas(DisasContext *s, int ot) 803 static inline void gen_scas(DisasContext *s, int ot)
826 { 804 {
827 gen_op_mov_TN_reg[OT_LONG][0][R_EAX](); 805 gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
@@ -836,23 +814,6 @@ static inline void gen_scas(DisasContext *s, int ot) @@ -836,23 +814,6 @@ static inline void gen_scas(DisasContext *s, int ot)
836 } 814 }
837 } 815 }
838 816
839 -#if 0  
840 -static inline void gen_repz_scas(DisasContext *s, int ot,  
841 - unsigned int cur_eip, unsigned int next_eip,  
842 - int nz)  
843 -{  
844 - if (s->cc_op != CC_OP_DYNAMIC)  
845 - gen_op_set_cc_op(s->cc_op);  
846 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
847 - gen_scas(s, ot);  
848 - gen_op_set_cc_op(CC_OP_SUBB + ot);  
849 - gen_op_string_jnz_sub[nz][ot]((long)s->tb, next_eip);  
850 - gen_op_dec_ECX[s->aflag]();  
851 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
852 - s->is_jmp = 3;  
853 -}  
854 -#endif  
855 -  
856 static inline void gen_cmps(DisasContext *s, int ot) 817 static inline void gen_cmps(DisasContext *s, int ot)
857 { 818 {
858 gen_string_movl_A0_ESI(s); 819 gen_string_movl_A0_ESI(s);
@@ -883,18 +844,6 @@ static inline void gen_ins(DisasContext *s, int ot) @@ -883,18 +844,6 @@ static inline void gen_ins(DisasContext *s, int ot)
883 } 844 }
884 } 845 }
885 846
886 -static inline void gen_repz_ins(DisasContext *s, int ot,  
887 - unsigned int cur_eip, unsigned int next_eip)  
888 -{  
889 - if (s->cc_op != CC_OP_DYNAMIC)  
890 - gen_op_set_cc_op(s->cc_op);  
891 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
892 - gen_ins(s, ot);  
893 - gen_op_dec_ECX[s->aflag]();  
894 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
895 - s->is_jmp = 3;  
896 -}  
897 -  
898 static inline void gen_outs(DisasContext *s, int ot) 847 static inline void gen_outs(DisasContext *s, int ot)
899 { 848 {
900 gen_string_movl_A0_ESI(s); 849 gen_string_movl_A0_ESI(s);
@@ -908,59 +857,50 @@ static inline void gen_outs(DisasContext *s, int ot) @@ -908,59 +857,50 @@ static inline void gen_outs(DisasContext *s, int ot)
908 } 857 }
909 } 858 }
910 859
911 -static inline void gen_repz_outs(DisasContext *s, int ot,  
912 - unsigned int cur_eip, unsigned int next_eip)  
913 -{  
914 - if (s->cc_op != CC_OP_DYNAMIC)  
915 - gen_op_set_cc_op(s->cc_op);  
916 - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);  
917 - gen_outs(s, ot);  
918 - gen_op_dec_ECX[s->aflag]();  
919 - gen_op_jmp_tb_next((long)s->tb, cur_eip);  
920 - s->is_jmp = 3; 860 +/* same method as Valgrind : we generate jumps to current or next
  861 + instruction */
  862 +#define GEN_REPZ(op) \
  863 +static inline void gen_repz_ ## op(DisasContext *s, int ot, \
  864 + unsigned int cur_eip, unsigned int next_eip) \
  865 +{ \
  866 + gen_update_cc_op(s); \
  867 + gen_jz_ecx_string(s, next_eip); \
  868 + gen_ ## op(s, ot); \
  869 + gen_op_dec_ECX[s->aflag](); \
  870 + /* a loop would cause two single step exceptions if ECX = 1 \
  871 + before rep string_insn */ \
  872 + if (!s->jmp_opt) \
  873 + gen_op_jz_ecx_im[s->aflag](next_eip); \
  874 + gen_jmp(s, cur_eip); \
921 } 875 }
922 876
923 -static inline void gen_string_ds(DisasContext *s, int ot, GenOpFunc **func)  
924 -{  
925 - int index, override;  
926 -  
927 - override = s->override;  
928 - if (s->aflag) {  
929 - /* 32 bit address */  
930 - if (s->addseg && override < 0)  
931 - override = R_DS;  
932 - if (override >= 0) {  
933 - gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));  
934 - index = 3 + ot;  
935 - } else {  
936 - index = ot;  
937 - }  
938 - } else {  
939 - if (override < 0)  
940 - override = R_DS;  
941 - gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));  
942 - /* 16 address, always override */  
943 - index = 6 + ot;  
944 - }  
945 - func[index]();  
946 -}  
947 -  
948 -static inline void gen_string_es(DisasContext *s, int ot, GenOpFunc **func)  
949 -{  
950 - int index;  
951 -  
952 - if (s->aflag) {  
953 - if (s->addseg) {  
954 - index = 3 + ot;  
955 - } else {  
956 - index = ot;  
957 - }  
958 - } else {  
959 - index = 6 + ot;  
960 - }  
961 - func[index](); 877 +#define GEN_REPZ2(op) \
  878 +static inline void gen_repz_ ## op(DisasContext *s, int ot, \
  879 + unsigned int cur_eip, \
  880 + unsigned int next_eip, \
  881 + int nz) \
  882 +{ \
  883 + gen_update_cc_op(s); \
  884 + gen_jz_ecx_string(s, next_eip); \
  885 + gen_ ## op(s, ot); \
  886 + gen_op_dec_ECX[s->aflag](); \
  887 + gen_op_set_cc_op(CC_OP_SUBB + ot); \
  888 + if (!s->jmp_opt) \
  889 + gen_op_string_jnz_sub_im[nz][ot](next_eip); \
  890 + else \
  891 + gen_op_string_jnz_sub[nz][ot]((long)s->tb); \
  892 + if (!s->jmp_opt) \
  893 + gen_op_jz_ecx_im[s->aflag](next_eip); \
  894 + gen_jmp(s, cur_eip); \
962 } 895 }
963 896
  897 +GEN_REPZ(movs)
  898 +GEN_REPZ(stos)
  899 +GEN_REPZ(lods)
  900 +GEN_REPZ(ins)
  901 +GEN_REPZ(outs)
  902 +GEN_REPZ2(scas)
  903 +GEN_REPZ2(cmps)
964 904
965 static GenOpFunc *gen_op_in[3] = { 905 static GenOpFunc *gen_op_in[3] = {
966 gen_op_inb_T0_T1, 906 gen_op_inb_T0_T1,
@@ -1420,71 +1360,86 @@ static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip) @@ -1420,71 +1360,86 @@ static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
1420 1360
1421 inv = b & 1; 1361 inv = b & 1;
1422 jcc_op = (b >> 1) & 7; 1362 jcc_op = (b >> 1) & 7;
1423 - switch(s->cc_op) {  
1424 - /* we optimize the cmp/jcc case */  
1425 - case CC_OP_SUBB:  
1426 - case CC_OP_SUBW:  
1427 - case CC_OP_SUBL:  
1428 - func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];  
1429 - break;  
1430 -  
1431 - /* some jumps are easy to compute */  
1432 - case CC_OP_ADDB:  
1433 - case CC_OP_ADDW:  
1434 - case CC_OP_ADDL:  
1435 - case CC_OP_ADCB:  
1436 - case CC_OP_ADCW:  
1437 - case CC_OP_ADCL:  
1438 - case CC_OP_SBBB:  
1439 - case CC_OP_SBBW:  
1440 - case CC_OP_SBBL:  
1441 - case CC_OP_LOGICB:  
1442 - case CC_OP_LOGICW:  
1443 - case CC_OP_LOGICL:  
1444 - case CC_OP_INCB:  
1445 - case CC_OP_INCW:  
1446 - case CC_OP_INCL:  
1447 - case CC_OP_DECB:  
1448 - case CC_OP_DECW:  
1449 - case CC_OP_DECL:  
1450 - case CC_OP_SHLB:  
1451 - case CC_OP_SHLW:  
1452 - case CC_OP_SHLL:  
1453 - case CC_OP_SARB:  
1454 - case CC_OP_SARW:  
1455 - case CC_OP_SARL:  
1456 - switch(jcc_op) {  
1457 - case JCC_Z:  
1458 - func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op]; 1363 +
  1364 + if (s->jmp_opt) {
  1365 + switch(s->cc_op) {
  1366 + /* we optimize the cmp/jcc case */
  1367 + case CC_OP_SUBB:
  1368 + case CC_OP_SUBW:
  1369 + case CC_OP_SUBL:
  1370 + func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1459 break; 1371 break;
1460 - case JCC_S:  
1461 - func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op]; 1372 +
  1373 + /* some jumps are easy to compute */
  1374 + case CC_OP_ADDB:
  1375 + case CC_OP_ADDW:
  1376 + case CC_OP_ADDL:
  1377 + case CC_OP_ADCB:
  1378 + case CC_OP_ADCW:
  1379 + case CC_OP_ADCL:
  1380 + case CC_OP_SBBB:
  1381 + case CC_OP_SBBW:
  1382 + case CC_OP_SBBL:
  1383 + case CC_OP_LOGICB:
  1384 + case CC_OP_LOGICW:
  1385 + case CC_OP_LOGICL:
  1386 + case CC_OP_INCB:
  1387 + case CC_OP_INCW:
  1388 + case CC_OP_INCL:
  1389 + case CC_OP_DECB:
  1390 + case CC_OP_DECW:
  1391 + case CC_OP_DECL:
  1392 + case CC_OP_SHLB:
  1393 + case CC_OP_SHLW:
  1394 + case CC_OP_SHLL:
  1395 + case CC_OP_SARB:
  1396 + case CC_OP_SARW:
  1397 + case CC_OP_SARL:
  1398 + switch(jcc_op) {
  1399 + case JCC_Z:
  1400 + func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1401 + break;
  1402 + case JCC_S:
  1403 + func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1404 + break;
  1405 + default:
  1406 + func = NULL;
  1407 + break;
  1408 + }
1462 break; 1409 break;
1463 default: 1410 default:
1464 func = NULL; 1411 func = NULL;
1465 break; 1412 break;
1466 } 1413 }
1467 - break;  
1468 - default:  
1469 - func = NULL;  
1470 - break;  
1471 - }  
1472 1414
1473 - if (s->cc_op != CC_OP_DYNAMIC)  
1474 - gen_op_set_cc_op(s->cc_op); 1415 + if (s->cc_op != CC_OP_DYNAMIC)
  1416 + gen_op_set_cc_op(s->cc_op);
1475 1417
1476 - if (!func) {  
1477 - gen_setcc_slow[jcc_op]();  
1478 - func = gen_op_jcc;  
1479 - } 1418 + if (!func) {
  1419 + gen_setcc_slow[jcc_op]();
  1420 + func = gen_op_jcc;
  1421 + }
1480 1422
1481 - tb = s->tb;  
1482 - if (!inv) {  
1483 - func((long)tb, val, next_eip); 1423 + tb = s->tb;
  1424 + if (!inv) {
  1425 + func((long)tb, val, next_eip);
  1426 + } else {
  1427 + func((long)tb, next_eip, val);
  1428 + }
  1429 + s->is_jmp = 3;
1484 } else { 1430 } else {
1485 - func((long)tb, next_eip, val); 1431 + if (s->cc_op != CC_OP_DYNAMIC) {
  1432 + gen_op_set_cc_op(s->cc_op);
  1433 + s->cc_op = CC_OP_DYNAMIC;
  1434 + }
  1435 + gen_setcc_slow[jcc_op]();
  1436 + if (!inv) {
  1437 + gen_op_jcc_im(val, next_eip);
  1438 + } else {
  1439 + gen_op_jcc_im(next_eip, val);
  1440 + }
  1441 + gen_eob(s);
1486 } 1442 }
1487 - s->is_jmp = 3;  
1488 } 1443 }
1489 1444
1490 static void gen_setcc(DisasContext *s, int b) 1445 static void gen_setcc(DisasContext *s, int b)
@@ -1557,7 +1512,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) @@ -1557,7 +1512,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
1557 stop as a special handling must be done to disable hardware 1512 stop as a special handling must be done to disable hardware
1558 interrupts for the next instruction */ 1513 interrupts for the next instruction */
1559 if (seg_reg == R_SS || (!s->addseg && seg_reg < R_FS)) 1514 if (seg_reg == R_SS || (!s->addseg && seg_reg < R_FS))
1560 - s->is_jmp = 2; 1515 + s->is_jmp = 3;
1561 } 1516 }
1562 1517
1563 /* generate a push. It depends on ss32, addseg and dflag */ 1518 /* generate a push. It depends on ss32, addseg and dflag */
@@ -1727,7 +1682,7 @@ static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip) @@ -1727,7 +1682,7 @@ static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip)
1727 gen_op_set_cc_op(s->cc_op); 1682 gen_op_set_cc_op(s->cc_op);
1728 gen_op_jmp_im(cur_eip); 1683 gen_op_jmp_im(cur_eip);
1729 gen_op_raise_exception(trapno); 1684 gen_op_raise_exception(trapno);
1730 - s->is_jmp = 1; 1685 + s->is_jmp = 3;
1731 } 1686 }
1732 1687
1733 /* an interrupt is different from an exception because of the 1688 /* an interrupt is different from an exception because of the
@@ -1739,7 +1694,7 @@ static void gen_interrupt(DisasContext *s, int intno, @@ -1739,7 +1694,7 @@ static void gen_interrupt(DisasContext *s, int intno,
1739 gen_op_set_cc_op(s->cc_op); 1694 gen_op_set_cc_op(s->cc_op);
1740 gen_op_jmp_im(cur_eip); 1695 gen_op_jmp_im(cur_eip);
1741 gen_op_raise_interrupt(intno, next_eip); 1696 gen_op_raise_interrupt(intno, next_eip);
1742 - s->is_jmp = 1; 1697 + s->is_jmp = 3;
1743 } 1698 }
1744 1699
1745 static void gen_debug(DisasContext *s, unsigned int cur_eip) 1700 static void gen_debug(DisasContext *s, unsigned int cur_eip)
@@ -1748,7 +1703,22 @@ static void gen_debug(DisasContext *s, unsigned int cur_eip) @@ -1748,7 +1703,22 @@ static void gen_debug(DisasContext *s, unsigned int cur_eip)
1748 gen_op_set_cc_op(s->cc_op); 1703 gen_op_set_cc_op(s->cc_op);
1749 gen_op_jmp_im(cur_eip); 1704 gen_op_jmp_im(cur_eip);
1750 gen_op_debug(); 1705 gen_op_debug();
1751 - s->is_jmp = 1; 1706 + s->is_jmp = 3;
  1707 +}
  1708 +
  1709 +/* generate a generic end of block. Trace exception is also generated
  1710 + if needed */
  1711 +static void gen_eob(DisasContext *s)
  1712 +{
  1713 + if (s->cc_op != CC_OP_DYNAMIC)
  1714 + gen_op_set_cc_op(s->cc_op);
  1715 + if (s->tf) {
  1716 + gen_op_raise_exception(EXCP01_SSTP);
  1717 + } else {
  1718 + gen_op_movl_T0_0();
  1719 + gen_op_exit_tb();
  1720 + }
  1721 + s->is_jmp = 3;
1752 } 1722 }
1753 1723
1754 /* generate a jump to eip. No segment change must happen before as a 1724 /* generate a jump to eip. No segment change must happen before as a
@@ -1757,16 +1727,20 @@ static void gen_jmp(DisasContext *s, unsigned int eip) @@ -1757,16 +1727,20 @@ static void gen_jmp(DisasContext *s, unsigned int eip)
1757 { 1727 {
1758 TranslationBlock *tb = s->tb; 1728 TranslationBlock *tb = s->tb;
1759 1729
1760 - if (s->cc_op != CC_OP_DYNAMIC)  
1761 - gen_op_set_cc_op(s->cc_op);  
1762 - gen_op_jmp_tb_next((long)tb, eip);  
1763 - s->is_jmp = 3; 1730 + if (s->jmp_opt) {
  1731 + if (s->cc_op != CC_OP_DYNAMIC)
  1732 + gen_op_set_cc_op(s->cc_op);
  1733 + gen_op_jmp((long)tb, eip);
  1734 + s->is_jmp = 3;
  1735 + } else {
  1736 + gen_op_jmp_im(eip);
  1737 + gen_eob(s);
  1738 + }
1764 } 1739 }
1765 1740
1766 -/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr  
1767 - is set to true if the instruction sets the PC (last instruction of  
1768 - a basic block) */  
1769 -long disas_insn(DisasContext *s, uint8_t *pc_start) 1741 +/* convert one instruction. s->is_jmp is set if the translation must
  1742 + be stopped. Return the next pc value */
  1743 +static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1770 { 1744 {
1771 int b, prefixes, aflag, dflag; 1745 int b, prefixes, aflag, dflag;
1772 int shift, ot; 1746 int shift, ot;
@@ -2106,9 +2080,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2106,9 +2080,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2106 next_eip = s->pc - s->cs_base; 2080 next_eip = s->pc - s->cs_base;
2107 gen_op_movl_T0_im(next_eip); 2081 gen_op_movl_T0_im(next_eip);
2108 gen_push_T0(s); 2082 gen_push_T0(s);
2109 - s->is_jmp = 1; 2083 + gen_eob(s);
2110 break; 2084 break;
2111 - case 3: /* lcall Ev */ 2085 + case 3: /*< lcall Ev */
2112 gen_op_ld_T1_A0[ot + s->mem_index](); 2086 gen_op_ld_T1_A0[ot + s->mem_index]();
2113 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 2087 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2114 gen_op_ld_T0_A0[OT_WORD + s->mem_index](); 2088 gen_op_ld_T0_A0[OT_WORD + s->mem_index]();
@@ -2121,13 +2095,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2121,13 +2095,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2121 } else { 2095 } else {
2122 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base); 2096 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
2123 } 2097 }
2124 - s->is_jmp = 1; 2098 + gen_eob(s);
2125 break; 2099 break;
2126 case 4: /* jmp Ev */ 2100 case 4: /* jmp Ev */
2127 if (s->dflag == 0) 2101 if (s->dflag == 0)
2128 gen_op_andl_T0_ffff(); 2102 gen_op_andl_T0_ffff();
2129 gen_op_jmp_T0(); 2103 gen_op_jmp_T0();
2130 - s->is_jmp = 1; 2104 + gen_eob(s);
2131 break; 2105 break;
2132 case 5: /* ljmp Ev */ 2106 case 5: /* ljmp Ev */
2133 gen_op_ld_T1_A0[ot + s->mem_index](); 2107 gen_op_ld_T1_A0[ot + s->mem_index]();
@@ -2144,7 +2118,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2144,7 +2118,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2144 gen_op_movl_T0_T1(); 2118 gen_op_movl_T0_T1();
2145 gen_op_jmp_T0(); 2119 gen_op_jmp_T0();
2146 } 2120 }
2147 - s->is_jmp = 1; 2121 + gen_eob(s);
2148 break; 2122 break;
2149 case 6: /* push Ev */ 2123 case 6: /* push Ev */
2150 gen_push_T0(s); 2124 gen_push_T0(s);
@@ -2366,6 +2340,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2366,6 +2340,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2366 if (reg == R_SS) { 2340 if (reg == R_SS) {
2367 /* if reg == SS, inhibit interrupts/trace */ 2341 /* if reg == SS, inhibit interrupts/trace */
2368 gen_op_set_inhibit_irq(); 2342 gen_op_set_inhibit_irq();
  2343 + s->tf = 0;
  2344 + }
  2345 + if (s->is_jmp) {
  2346 + gen_op_jmp_im(s->pc - s->cs_base);
  2347 + gen_eob(s);
2369 } 2348 }
2370 break; 2349 break;
2371 case 0x1a1: /* pop fs */ 2350 case 0x1a1: /* pop fs */
@@ -2373,6 +2352,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2373,6 +2352,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2373 gen_pop_T0(s); 2352 gen_pop_T0(s);
2374 gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base); 2353 gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
2375 gen_pop_update(s); 2354 gen_pop_update(s);
  2355 + if (s->is_jmp) {
  2356 + gen_op_jmp_im(s->pc - s->cs_base);
  2357 + gen_eob(s);
  2358 + }
2376 break; 2359 break;
2377 2360
2378 /**************************/ 2361 /**************************/
@@ -2428,6 +2411,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2428,6 +2411,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2428 if (reg == R_SS) { 2411 if (reg == R_SS) {
2429 /* if reg == SS, inhibit interrupts/trace */ 2412 /* if reg == SS, inhibit interrupts/trace */
2430 gen_op_set_inhibit_irq(); 2413 gen_op_set_inhibit_irq();
  2414 + s->tf = 0;
  2415 + }
  2416 + if (s->is_jmp) {
  2417 + gen_op_jmp_im(s->pc - s->cs_base);
  2418 + gen_eob(s);
2431 } 2419 }
2432 break; 2420 break;
2433 case 0x8c: /* mov Gv, seg */ 2421 case 0x8c: /* mov Gv, seg */
@@ -2635,6 +2623,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2635,6 +2623,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2635 gen_movl_seg_T0(s, op, pc_start - s->cs_base); 2623 gen_movl_seg_T0(s, op, pc_start - s->cs_base);
2636 /* then put the data */ 2624 /* then put the data */
2637 gen_op_mov_reg_T1[ot][reg](); 2625 gen_op_mov_reg_T1[ot][reg]();
  2626 + if (s->is_jmp) {
  2627 + gen_op_jmp_im(s->pc - s->cs_base);
  2628 + gen_eob(s);
  2629 + }
2638 break; 2630 break;
2639 2631
2640 /************************/ 2632 /************************/
@@ -3191,15 +3183,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3191,15 +3183,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3191 else 3183 else
3192 ot = dflag ? OT_LONG : OT_WORD; 3184 ot = dflag ? OT_LONG : OT_WORD;
3193 if (prefixes & PREFIX_REPNZ) { 3185 if (prefixes & PREFIX_REPNZ) {
3194 - if (s->cc_op != CC_OP_DYNAMIC)  
3195 - gen_op_set_cc_op(s->cc_op);  
3196 - gen_string_es(s, ot, gen_op_scas + STRINGOP_NB);  
3197 - s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 3186 + gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
3198 } else if (prefixes & PREFIX_REPZ) { 3187 } else if (prefixes & PREFIX_REPZ) {
3199 - if (s->cc_op != CC_OP_DYNAMIC)  
3200 - gen_op_set_cc_op(s->cc_op);  
3201 - gen_string_es(s, ot, gen_op_scas);  
3202 - s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 3188 + gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
3203 } else { 3189 } else {
3204 gen_scas(s, ot); 3190 gen_scas(s, ot);
3205 s->cc_op = CC_OP_SUBB + ot; 3191 s->cc_op = CC_OP_SUBB + ot;
@@ -3213,15 +3199,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3213,15 +3199,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3213 else 3199 else
3214 ot = dflag ? OT_LONG : OT_WORD; 3200 ot = dflag ? OT_LONG : OT_WORD;
3215 if (prefixes & PREFIX_REPNZ) { 3201 if (prefixes & PREFIX_REPNZ) {
3216 - if (s->cc_op != CC_OP_DYNAMIC)  
3217 - gen_op_set_cc_op(s->cc_op);  
3218 - gen_string_ds(s, ot, gen_op_cmps + STRINGOP_NB);  
3219 - s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 3202 + gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
3220 } else if (prefixes & PREFIX_REPZ) { 3203 } else if (prefixes & PREFIX_REPZ) {
3221 - if (s->cc_op != CC_OP_DYNAMIC)  
3222 - gen_op_set_cc_op(s->cc_op);  
3223 - gen_string_ds(s, ot, gen_op_cmps);  
3224 - s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 3204 + gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
3225 } else { 3205 } else {
3226 gen_cmps(s, ot); 3206 gen_cmps(s, ot);
3227 s->cc_op = CC_OP_SUBB + ot; 3207 s->cc_op = CC_OP_SUBB + ot;
@@ -3333,7 +3313,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3333,7 +3313,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3333 if (s->dflag == 0) 3313 if (s->dflag == 0)
3334 gen_op_andl_T0_ffff(); 3314 gen_op_andl_T0_ffff();
3335 gen_op_jmp_T0(); 3315 gen_op_jmp_T0();
3336 - s->is_jmp = 1; 3316 + gen_eob(s);
3337 break; 3317 break;
3338 case 0xc3: /* ret */ 3318 case 0xc3: /* ret */
3339 gen_pop_T0(s); 3319 gen_pop_T0(s);
@@ -3341,7 +3321,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3341,7 +3321,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3341 if (s->dflag == 0) 3321 if (s->dflag == 0)
3342 gen_op_andl_T0_ffff(); 3322 gen_op_andl_T0_ffff();
3343 gen_op_jmp_T0(); 3323 gen_op_jmp_T0();
3344 - s->is_jmp = 1; 3324 + gen_eob(s);
3345 break; 3325 break;
3346 case 0xca: /* lret im */ 3326 case 0xca: /* lret im */
3347 val = ldsw(s->pc); 3327 val = ldsw(s->pc);
@@ -3368,7 +3348,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3368,7 +3348,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3368 /* add stack offset */ 3348 /* add stack offset */
3369 gen_stack_update(s, val + (4 << s->dflag)); 3349 gen_stack_update(s, val + (4 << s->dflag));
3370 } 3350 }
3371 - s->is_jmp = 1; 3351 + gen_eob(s);
3372 break; 3352 break;
3373 case 0xcb: /* lret */ 3353 case 0xcb: /* lret */
3374 val = 0; 3354 val = 0;
@@ -3387,7 +3367,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3387,7 +3367,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3387 gen_op_iret_protected(s->dflag); 3367 gen_op_iret_protected(s->dflag);
3388 s->cc_op = CC_OP_EFLAGS; 3368 s->cc_op = CC_OP_EFLAGS;
3389 } 3369 }
3390 - s->is_jmp = 1; 3370 + gen_eob(s);
3391 break; 3371 break;
3392 case 0xe8: /* call im */ 3372 case 0xe8: /* call im */
3393 { 3373 {
@@ -3512,7 +3492,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3512,7 +3492,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3512 } 3492 }
3513 gen_pop_update(s); 3493 gen_pop_update(s);
3514 s->cc_op = CC_OP_EFLAGS; 3494 s->cc_op = CC_OP_EFLAGS;
3515 - s->is_jmp = 2; /* abort translation because TF flag may change */ 3495 + /* abort translation because TF flag may change */
  3496 + gen_op_jmp_im(s->pc - s->cs_base);
  3497 + gen_eob(s);
3516 } 3498 }
3517 break; 3499 break;
3518 case 0x9e: /* sahf */ 3500 case 0x9e: /* sahf */
@@ -3713,19 +3695,19 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3713,19 +3695,19 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3713 case 0xfb: /* sti */ 3695 case 0xfb: /* sti */
3714 if (!s->vm86) { 3696 if (!s->vm86) {
3715 if (s->cpl <= s->iopl) { 3697 if (s->cpl <= s->iopl) {
  3698 + gen_sti:
3716 gen_op_sti(); 3699 gen_op_sti();
3717 /* interruptions are enabled only the first insn after sti */ 3700 /* interruptions are enabled only the first insn after sti */
3718 gen_op_set_inhibit_irq(); 3701 gen_op_set_inhibit_irq();
3719 - s->is_jmp = 2; /* give a chance to handle pending irqs */ 3702 + /* give a chance to handle pending irqs */
  3703 + gen_op_jmp_im(s->pc - s->cs_base);
  3704 + gen_eob(s);
3720 } else { 3705 } else {
3721 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 3706 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3722 } 3707 }
3723 } else { 3708 } else {
3724 if (s->iopl == 3) { 3709 if (s->iopl == 3) {
3725 - gen_op_sti();  
3726 - /* interruptions are enabled only the first insn after sti */  
3727 - gen_op_set_inhibit_irq();  
3728 - s->is_jmp = 2; /* give a chance to handle pending irqs */ 3710 + goto gen_sti;
3729 } else { 3711 } else {
3730 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 3712 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3731 } 3713 }
@@ -3769,7 +3751,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3769,7 +3751,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3769 if (s->dflag == 0) 3751 if (s->dflag == 0)
3770 val &= 0xffff; 3752 val &= 0xffff;
3771 gen_op_loop[s->aflag][b & 3](val, next_eip); 3753 gen_op_loop[s->aflag][b & 3](val, next_eip);
3772 - s->is_jmp = 1; 3754 + gen_eob(s);
3773 break; 3755 break;
3774 case 0x130: /* wrmsr */ 3756 case 0x130: /* wrmsr */
3775 case 0x132: /* rdmsr */ 3757 case 0x132: /* rdmsr */
@@ -3796,7 +3778,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3796,7 +3778,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3796 gen_op_set_cc_op(s->cc_op); 3778 gen_op_set_cc_op(s->cc_op);
3797 gen_op_jmp_im(s->pc - s->cs_base); 3779 gen_op_jmp_im(s->pc - s->cs_base);
3798 gen_op_hlt(); 3780 gen_op_hlt();
3799 - s->is_jmp = 1; 3781 + s->is_jmp = 3;
3800 } 3782 }
3801 break; 3783 break;
3802 case 0x100: 3784 case 0x100:
@@ -3968,7 +3950,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3968,7 +3950,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3968 if (b & 2) { 3950 if (b & 2) {
3969 gen_op_mov_TN_reg[OT_LONG][0][rm](); 3951 gen_op_mov_TN_reg[OT_LONG][0][rm]();
3970 gen_op_movl_crN_T0(reg); 3952 gen_op_movl_crN_T0(reg);
3971 - s->is_jmp = 2; 3953 + gen_op_jmp_im(s->pc - s->cs_base);
  3954 + gen_eob(s);
3972 } else { 3955 } else {
3973 gen_op_movl_T0_env(offsetof(CPUX86State,cr[reg])); 3956 gen_op_movl_T0_env(offsetof(CPUX86State,cr[reg]));
3974 gen_op_mov_reg_T0[OT_LONG][rm](); 3957 gen_op_mov_reg_T0[OT_LONG][rm]();
@@ -3995,7 +3978,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3995,7 +3978,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3995 if (b & 2) { 3978 if (b & 2) {
3996 gen_op_mov_TN_reg[OT_LONG][0][rm](); 3979 gen_op_mov_TN_reg[OT_LONG][0][rm]();
3997 gen_op_movl_drN_T0(reg); 3980 gen_op_movl_drN_T0(reg);
3998 - s->is_jmp = 2; 3981 + gen_op_jmp_im(s->pc - s->cs_base);
  3982 + gen_eob(s);
3999 } else { 3983 } else {
4000 gen_op_movl_T0_env(offsetof(CPUX86State,dr[reg])); 3984 gen_op_movl_T0_env(offsetof(CPUX86State,dr[reg]));
4001 gen_op_mov_reg_T0[OT_LONG][rm](); 3985 gen_op_mov_reg_T0[OT_LONG][rm]();
@@ -4015,10 +3999,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -4015,10 +3999,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
4015 /* lock generation */ 3999 /* lock generation */
4016 if (s->prefix & PREFIX_LOCK) 4000 if (s->prefix & PREFIX_LOCK)
4017 gen_op_unlock(); 4001 gen_op_unlock();
4018 - return (long)s->pc; 4002 + return s->pc;
4019 illegal_op: 4003 illegal_op:
4020 /* XXX: ensure that no lock was generated */ 4004 /* XXX: ensure that no lock was generated */
4021 - return -1; 4005 + gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
  4006 + return s->pc;
4022 } 4007 }
4023 4008
4024 #define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C) 4009 #define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
@@ -4265,23 +4250,6 @@ static uint16_t opc_write_flags[NB_OPS] = { @@ -4265,23 +4250,6 @@ static uint16_t opc_write_flags[NB_OPS] = {
4265 [INDEX_op_bsrw_T0_cc] = CC_OSZAPC, 4250 [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
4266 [INDEX_op_bsrl_T0_cc] = CC_OSZAPC, 4251 [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
4267 4252
4268 -#undef STRINGOP  
4269 -#define STRINGOP(x) \  
4270 - [INDEX_op_ ## x ## b_fast] = CC_OSZAPC, \  
4271 - [INDEX_op_ ## x ## w_fast] = CC_OSZAPC, \  
4272 - [INDEX_op_ ## x ## l_fast] = CC_OSZAPC, \  
4273 - [INDEX_op_ ## x ## b_a32] = CC_OSZAPC, \  
4274 - [INDEX_op_ ## x ## w_a32] = CC_OSZAPC, \  
4275 - [INDEX_op_ ## x ## l_a32] = CC_OSZAPC, \  
4276 - [INDEX_op_ ## x ## b_a16] = CC_OSZAPC, \  
4277 - [INDEX_op_ ## x ## w_a16] = CC_OSZAPC, \  
4278 - [INDEX_op_ ## x ## l_a16] = CC_OSZAPC,  
4279 -  
4280 - STRINGOP(repz_scas)  
4281 - STRINGOP(repnz_scas)  
4282 - STRINGOP(repz_cmps)  
4283 - STRINGOP(repnz_cmps)  
4284 -  
4285 [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC, 4253 [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
4286 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC, 4254 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
4287 [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC, 4255 [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
@@ -4383,7 +4351,6 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4383,7 +4351,6 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4383 uint8_t *pc_ptr; 4351 uint8_t *pc_ptr;
4384 uint16_t *gen_opc_end; 4352 uint16_t *gen_opc_end;
4385 int flags, j, lj; 4353 int flags, j, lj;
4386 - long ret;  
4387 uint8_t *pc_start; 4354 uint8_t *pc_start;
4388 uint8_t *cs_base; 4355 uint8_t *cs_base;
4389 4356
@@ -4413,7 +4380,11 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4413,7 +4380,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4413 else 4380 else
4414 dc->mem_index = 3; 4381 dc->mem_index = 3;
4415 } 4382 }
4416 - 4383 + dc->jmp_opt = !(dc->tf || env->singlestep_enabled
  4384 +#ifndef CONFIG_SOFT_MMU
  4385 + || (flags & HF_SOFTMMU_MASK)
  4386 +#endif
  4387 + );
4417 gen_opc_ptr = gen_opc_buf; 4388 gen_opc_ptr = gen_opc_buf;
4418 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; 4389 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4419 gen_opparam_ptr = gen_opparam_buf; 4390 gen_opparam_ptr = gen_opparam_buf;
@@ -4428,12 +4399,12 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4428,12 +4399,12 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4428 if (flags & HF_INHIBIT_IRQ_MASK) { 4399 if (flags & HF_INHIBIT_IRQ_MASK) {
4429 gen_op_reset_inhibit_irq(); 4400 gen_op_reset_inhibit_irq();
4430 } 4401 }
4431 - do { 4402 + for(;;) {
4432 if (env->nb_breakpoints > 0) { 4403 if (env->nb_breakpoints > 0) {
4433 for(j = 0; j < env->nb_breakpoints; j++) { 4404 for(j = 0; j < env->nb_breakpoints; j++) {
4434 if (env->breakpoints[j] == (unsigned long)pc_ptr) { 4405 if (env->breakpoints[j] == (unsigned long)pc_ptr) {
4435 gen_debug(dc, pc_ptr - dc->cs_base); 4406 gen_debug(dc, pc_ptr - dc->cs_base);
4436 - goto the_end; 4407 + break;
4437 } 4408 }
4438 } 4409 }
4439 } 4410 }
@@ -4448,44 +4419,24 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4448,44 +4419,24 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4448 gen_opc_cc_op[lj] = dc->cc_op; 4419 gen_opc_cc_op[lj] = dc->cc_op;
4449 gen_opc_instr_start[lj] = 1; 4420 gen_opc_instr_start[lj] = 1;
4450 } 4421 }
4451 - ret = disas_insn(dc, pc_ptr);  
4452 - if (ret == -1) {  
4453 - /* we trigger an illegal instruction operation only if it  
4454 - is the first instruction. Otherwise, we simply stop  
4455 - generating the code just before it */  
4456 - if (pc_ptr == pc_start)  
4457 - return -1;  
4458 - else  
4459 - break;  
4460 - }  
4461 - pc_ptr = (void *)ret; 4422 + pc_ptr = disas_insn(dc, pc_ptr);
  4423 + /* stop translation if indicated */
  4424 + if (dc->is_jmp)
  4425 + break;
4462 /* if single step mode, we generate only one instruction and 4426 /* if single step mode, we generate only one instruction and
4463 generate an exception */ 4427 generate an exception */
4464 - if (dc->tf) 4428 + if (dc->tf) {
  4429 + gen_op_jmp_im(pc_ptr - dc->cs_base);
  4430 + gen_eob(dc);
  4431 + break;
  4432 + }
  4433 + /* if too long translation, stop generation too */
  4434 + if (gen_opc_ptr >= gen_opc_end ||
  4435 + (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
  4436 + gen_op_jmp_im(pc_ptr - dc->cs_base);
  4437 + gen_eob(dc);
4465 break; 4438 break;
4466 - } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&  
4467 - (pc_ptr - pc_start) < (TARGET_PAGE_SIZE - 32));  
4468 - if (!dc->tf && dc->is_jmp == DISAS_NEXT) {  
4469 - gen_jmp(dc, ret - (unsigned long)dc->cs_base);  
4470 - }  
4471 -  
4472 - /* we must store the eflags state if it is not already done */  
4473 - if (dc->is_jmp != DISAS_TB_JUMP) {  
4474 - if (dc->cc_op != CC_OP_DYNAMIC)  
4475 - gen_op_set_cc_op(dc->cc_op);  
4476 - if (dc->is_jmp != DISAS_JUMP) {  
4477 - /* we add an additionnal jmp to update the simulated PC */  
4478 - gen_op_jmp_im(ret - (unsigned long)dc->cs_base);  
4479 } 4439 }
4480 - }  
4481 - if (dc->tf) {  
4482 - gen_op_raise_exception(EXCP01_SSTP);  
4483 - }  
4484 - the_end:  
4485 - if (dc->is_jmp != DISAS_TB_JUMP) {  
4486 - /* indicate that the hash table must be used to find the next TB */  
4487 - gen_op_movl_T0_0();  
4488 - gen_op_exit_tb();  
4489 } 4440 }
4490 *gen_opc_ptr = INDEX_op_end; 4441 *gen_opc_ptr = INDEX_op_end;
4491 /* we don't forget to fill the last values */ 4442 /* we don't forget to fill the last values */