Revision 2c1794c4 translate-i386.c

b/translate-i386.c
1832 1832
            s->is_jmp = 1;
1833 1833
            break;
1834 1834
        case 3: /* lcall Ev */
1835
            /* push return segment + offset */
1836
            gen_op_movl_T0_seg(R_CS);
1837
            gen_push_T0(s);
1838
            next_eip = s->pc - s->cs_base;
1839
            gen_op_movl_T0_im(next_eip);
1840
            gen_push_T0(s);
1841

  
1842 1835
            gen_op_ld_T1_A0[ot]();
1843 1836
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1844 1837
            gen_op_lduw_T0_A0();
1845
            gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);
1846
            gen_op_movl_T0_T1();
1847
            gen_op_jmp_T0();
1838
        do_lcall:
1839
            if (s->pe && !s->vm86) {
1840
                if (s->cc_op != CC_OP_DYNAMIC)
1841
                    gen_op_set_cc_op(s->cc_op);
1842
                gen_op_jmp_im(pc_start - s->cs_base);
1843
                gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base);
1844
            } else {
1845
                gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
1846
            }
1848 1847
            s->is_jmp = 1;
1849 1848
            break;
1850 1849
        case 4: /* jmp Ev */
......
1857 1856
            gen_op_ld_T1_A0[ot]();
1858 1857
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1859 1858
            gen_op_lduw_T0_A0();
1859
        do_ljmp:
1860 1860
            if (s->pe && !s->vm86) {
1861
                /* we compute EIP to handle the exception case */
1861
                if (s->cc_op != CC_OP_DYNAMIC)
1862
                    gen_op_set_cc_op(s->cc_op);
1862 1863
                gen_op_jmp_im(pc_start - s->cs_base);
1863
                gen_op_ljmp_T0_T1();
1864
                gen_op_ljmp_protected_T0_T1();
1864 1865
            } else {
1865 1866
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
1866 1867
                gen_op_movl_T0_T1();
......
2867 2868
        else
2868 2869
            ot = dflag ? OT_LONG : OT_WORD;
2869 2870

  
2870
        if (prefixes & PREFIX_REPZ) {
2871
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2871 2872
            gen_string_ds(s, ot, gen_op_movs + 9);
2872 2873
        } else {
2873 2874
            gen_string_ds(s, ot, gen_op_movs);
......
2881 2882
        else
2882 2883
            ot = dflag ? OT_LONG : OT_WORD;
2883 2884

  
2884
        if (prefixes & PREFIX_REPZ) {
2885
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2885 2886
            gen_string_es(s, ot, gen_op_stos + 9);
2886 2887
        } else {
2887 2888
            gen_string_es(s, ot, gen_op_stos);
......
2893 2894
            ot = OT_BYTE;
2894 2895
        else
2895 2896
            ot = dflag ? OT_LONG : OT_WORD;
2896
        if (prefixes & PREFIX_REPZ) {
2897
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2897 2898
            gen_string_ds(s, ot, gen_op_lods + 9);
2898 2899
        } else {
2899 2900
            gen_string_ds(s, ot, gen_op_lods);
......
2952 2953
                ot = OT_BYTE;
2953 2954
            else
2954 2955
                ot = dflag ? OT_LONG : OT_WORD;
2955
            if (prefixes & PREFIX_REPZ) {
2956
            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2956 2957
                gen_string_es(s, ot, gen_op_ins + 9);
2957 2958
            } else {
2958 2959
                gen_string_es(s, ot, gen_op_ins);
......
2969 2970
                ot = OT_BYTE;
2970 2971
            else
2971 2972
                ot = dflag ? OT_LONG : OT_WORD;
2972
            if (prefixes & PREFIX_REPZ) {
2973
            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2973 2974
                gen_string_ds(s, ot, gen_op_outs + 9);
2974 2975
            } else {
2975 2976
                gen_string_ds(s, ot, gen_op_outs);
......
3062 3063
        val = ldsw(s->pc);
3063 3064
        s->pc += 2;
3064 3065
    do_lret:
3065
        gen_stack_A0(s);
3066
        /* pop offset */
3067
        gen_op_ld_T0_A0[1 + s->dflag]();
3068
        if (s->dflag == 0)
3069
            gen_op_andl_T0_ffff();
3070
        /* NOTE: keeping EIP updated is not a problem in case of
3071
           exception */
3072
        gen_op_jmp_T0();
3073
        /* pop selector */
3074
        gen_op_addl_A0_im(2 << s->dflag);
3075
        gen_op_ld_T0_A0[1 + s->dflag]();
3076
        gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);
3077
        /* add stack offset */
3078
        gen_stack_update(s, val + (4 << s->dflag));
3066
        if (s->pe && !s->vm86) {
3067
            if (s->cc_op != CC_OP_DYNAMIC)
3068
                gen_op_set_cc_op(s->cc_op);
3069
            gen_op_jmp_im(pc_start - s->cs_base);
3070
            gen_op_lret_protected(s->dflag, val);
3071
        } else {
3072
            gen_stack_A0(s);
3073
            /* pop offset */
3074
            gen_op_ld_T0_A0[1 + s->dflag]();
3075
            if (s->dflag == 0)
3076
                gen_op_andl_T0_ffff();
3077
            /* NOTE: keeping EIP updated is not a problem in case of
3078
               exception */
3079
            gen_op_jmp_T0();
3080
            /* pop selector */
3081
            gen_op_addl_A0_im(2 << s->dflag);
3082
            gen_op_ld_T0_A0[1 + s->dflag]();
3083
            gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3084
            /* add stack offset */
3085
            gen_stack_update(s, val + (4 << s->dflag));
3086
        }
3079 3087
        s->is_jmp = 1;
3080 3088
        break;
3081 3089
    case 0xcb: /* lret */
......
3114 3122
    case 0x9a: /* lcall im */
3115 3123
        {
3116 3124
            unsigned int selector, offset;
3117
            /* XXX: not restartable */
3118 3125

  
3119 3126
            ot = dflag ? OT_LONG : OT_WORD;
3120 3127
            offset = insn_get(s, ot);
3121 3128
            selector = insn_get(s, OT_WORD);
3122 3129
            
3123
            /* push return segment + offset */
3124
            gen_op_movl_T0_seg(R_CS);
3125
            gen_push_T0(s);
3126
            next_eip = s->pc - s->cs_base;
3127
            gen_op_movl_T0_im(next_eip);
3128
            gen_push_T0(s);
3129

  
3130
            /* change cs and pc */
3131 3130
            gen_op_movl_T0_im(selector);
3132
            gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);
3133
            gen_op_jmp_im((unsigned long)offset);
3134
            s->is_jmp = 1;
3131
            gen_op_movl_T1_im(offset);
3135 3132
        }
3136
        break;
3133
        goto do_lcall;
3137 3134
    case 0xe9: /* jmp */
3138 3135
        ot = dflag ? OT_LONG : OT_WORD;
3139 3136
        val = insn_get(s, ot);
......
3150 3147
            offset = insn_get(s, ot);
3151 3148
            selector = insn_get(s, OT_WORD);
3152 3149
            
3153
            /* change cs and pc */
3154 3150
            gen_op_movl_T0_im(selector);
3155
            if (s->pe && !s->vm86) {
3156
                /* we compute EIP to handle the exception case */
3157
                gen_op_jmp_im(pc_start - s->cs_base);
3158
                gen_op_movl_T1_im(offset);
3159
                gen_op_ljmp_T0_T1();
3160
            } else {
3161
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3162
                gen_op_jmp_im((unsigned long)offset);
3163
            }
3164
            s->is_jmp = 1;
3151
            gen_op_movl_T1_im(offset);
3165 3152
        }
3166
        break;
3153
        goto do_ljmp;
3167 3154
    case 0xeb: /* jmp Jb */
3168 3155
        val = (int8_t)insn_get(s, OT_BYTE);
3169 3156
        val += s->pc - s->cs_base;

Also available in: Unified diff