Revision 982b4315 translate-i386.c

b/translate-i386.c
130 130
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
131 131
    int f_st;   /* currently unused */
132 132
    int vm86;   /* vm86 mode */
133
    int cpl;
134
    int iopl;
133 135
} DisasContext;
134 136

  
135 137
/* i386 arith/logic operations */
......
2766 2768
        break;
2767 2769
    case 0x6c: /* insS */
2768 2770
    case 0x6d:
2769
        if ((b & 1) == 0)
2770
            ot = OT_BYTE;
2771
        else
2772
            ot = dflag ? OT_LONG : OT_WORD;
2773
        if (prefixes & PREFIX_REPZ) {
2774
            gen_string_es(s, ot, gen_op_ins + 9);
2771
        if (s->cpl > s->iopl || s->vm86) {
2772
            /* NOTE: even for (E)CX = 0 the exception is raised */
2773
            gen_op_gpf(pc_start - s->cs_base);
2775 2774
        } else {
2776
            gen_string_es(s, ot, gen_op_ins);
2775
            if ((b & 1) == 0)
2776
                ot = OT_BYTE;
2777
            else
2778
                ot = dflag ? OT_LONG : OT_WORD;
2779
            if (prefixes & PREFIX_REPZ) {
2780
                gen_string_es(s, ot, gen_op_ins + 9);
2781
            } else {
2782
                gen_string_es(s, ot, gen_op_ins);
2783
            }
2777 2784
        }
2778 2785
        break;
2779 2786
    case 0x6e: /* outsS */
2780 2787
    case 0x6f:
2781
        if ((b & 1) == 0)
2782
            ot = OT_BYTE;
2783
        else
2784
            ot = dflag ? OT_LONG : OT_WORD;
2785
        if (prefixes & PREFIX_REPZ) {
2786
            gen_string_ds(s, ot, gen_op_outs + 9);
2788
        if (s->cpl > s->iopl || s->vm86) {
2789
            /* NOTE: even for (E)CX = 0 the exception is raised */
2790
            gen_op_gpf(pc_start - s->cs_base);
2787 2791
        } else {
2788
            gen_string_ds(s, ot, gen_op_outs);
2792
            if ((b & 1) == 0)
2793
                ot = OT_BYTE;
2794
            else
2795
                ot = dflag ? OT_LONG : OT_WORD;
2796
            if (prefixes & PREFIX_REPZ) {
2797
                gen_string_ds(s, ot, gen_op_outs + 9);
2798
            } else {
2799
                gen_string_ds(s, ot, gen_op_outs);
2800
            }
2789 2801
        }
2790 2802
        break;
2791 2803

  
......
2793 2805
        /* port I/O */
2794 2806
    case 0xe4:
2795 2807
    case 0xe5:
2796
        if ((b & 1) == 0)
2797
            ot = OT_BYTE;
2798
        else
2799
            ot = dflag ? OT_LONG : OT_WORD;
2800
        val = ldub(s->pc++);
2801
        gen_op_movl_T0_im(val);
2802
        gen_op_in[ot]();
2803
        gen_op_mov_reg_T1[ot][R_EAX]();
2808
        if (s->cpl > s->iopl || s->vm86) {
2809
            gen_op_gpf(pc_start - s->cs_base);
2810
        } else {
2811
            if ((b & 1) == 0)
2812
                ot = OT_BYTE;
2813
            else
2814
                ot = dflag ? OT_LONG : OT_WORD;
2815
            val = ldub(s->pc++);
2816
            gen_op_movl_T0_im(val);
2817
            gen_op_in[ot]();
2818
            gen_op_mov_reg_T1[ot][R_EAX]();
2819
        }
2804 2820
        break;
2805 2821
    case 0xe6:
2806 2822
    case 0xe7:
2807
        if ((b & 1) == 0)
2808
            ot = OT_BYTE;
2809
        else
2810
            ot = dflag ? OT_LONG : OT_WORD;
2811
        val = ldub(s->pc++);
2812
        gen_op_movl_T0_im(val);
2813
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2814
        gen_op_out[ot]();
2823
        if (s->cpl > s->iopl || s->vm86) {
2824
            gen_op_gpf(pc_start - s->cs_base);
2825
        } else {
2826
            if ((b & 1) == 0)
2827
                ot = OT_BYTE;
2828
            else
2829
                ot = dflag ? OT_LONG : OT_WORD;
2830
            val = ldub(s->pc++);
2831
            gen_op_movl_T0_im(val);
2832
            gen_op_mov_TN_reg[ot][1][R_EAX]();
2833
            gen_op_out[ot]();
2834
        }
2815 2835
        break;
2816 2836
    case 0xec:
2817 2837
    case 0xed:
2818
        if ((b & 1) == 0)
2819
            ot = OT_BYTE;
2820
        else
2821
            ot = dflag ? OT_LONG : OT_WORD;
2822
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2823
        gen_op_in[ot]();
2824
        gen_op_mov_reg_T1[ot][R_EAX]();
2838
        if (s->cpl > s->iopl || s->vm86) {
2839
            gen_op_gpf(pc_start - s->cs_base);
2840
        } else {
2841
            if ((b & 1) == 0)
2842
                ot = OT_BYTE;
2843
            else
2844
                ot = dflag ? OT_LONG : OT_WORD;
2845
            gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2846
            gen_op_in[ot]();
2847
            gen_op_mov_reg_T1[ot][R_EAX]();
2848
        }
2825 2849
        break;
2826 2850
    case 0xee:
2827 2851
    case 0xef:
2828
        if ((b & 1) == 0)
2829
            ot = OT_BYTE;
2830
        else
2831
            ot = dflag ? OT_LONG : OT_WORD;
2832
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2833
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2834
        gen_op_out[ot]();
2852
        if (s->cpl > s->iopl || s->vm86) {
2853
            gen_op_gpf(pc_start - s->cs_base);
2854
        } else {
2855
            if ((b & 1) == 0)
2856
                ot = OT_BYTE;
2857
            else
2858
                ot = dflag ? OT_LONG : OT_WORD;
2859
            gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2860
            gen_op_mov_TN_reg[ot][1][R_EAX]();
2861
            gen_op_out[ot]();
2862
        }
2835 2863
        break;
2836 2864

  
2837 2865
        /************************/
......
3219 3247
        break;
3220 3248
    case 0xcd: /* int N */
3221 3249
        val = ldub(s->pc++);
3222
        /* XXX: currently we ignore the interrupt number */
3223
        gen_op_int_im(pc_start - s->cs_base);
3250
        gen_op_int_im(val, pc_start - s->cs_base);
3224 3251
        s->is_jmp = 1;
3225 3252
        break;
3226 3253
    case 0xce: /* into */
......
3229 3256
        gen_op_into();
3230 3257
        break;
3231 3258
    case 0xfa: /* cli */
3232
        if (s->vm86) 
3233
            gen_op_cli_vm();
3234
        else
3235
            gen_op_cli();
3259
        if (!s->vm86) {
3260
            if (s->cpl <= s->iopl)
3261
                gen_op_cli();
3262
            else
3263
                gen_op_gpf(pc_start - s->cs_base);
3264
        } else {
3265
            if (s->iopl == 3)
3266
                gen_op_cli();
3267
            else
3268
                gen_op_cli_vm();
3269
        }
3236 3270
        break;
3237 3271
    case 0xfb: /* sti */
3238
        if (s->vm86) 
3239
            gen_op_sti_vm(pc_start - s->cs_base);
3240
        else
3241
            gen_op_sti();
3272
        if (!s->vm86) {
3273
            if (s->cpl <= s->iopl)
3274
                gen_op_sti();
3275
            else
3276
                gen_op_gpf(pc_start - s->cs_base);
3277
        } else {
3278
            if (s->iopl == 3)
3279
                gen_op_sti();
3280
            else
3281
                gen_op_sti_vm(pc_start - s->cs_base);
3282
        }
3242 3283
        break;
3243 3284
    case 0x62: /* bound */
3244 3285
        ot = dflag ? OT_LONG : OT_WORD;
......
3286 3327
    case 0x1a2: /* cpuid */
3287 3328
        gen_op_cpuid();
3288 3329
        break;
3330
    case 0xf4: /* hlt */
3331
        if (s->cpl == 0) {
3332
            /* ignored */
3333
        } else {
3334
            gen_op_gpf(pc_start - s->cs_base);
3335
        }
3336
        break;
3289 3337
    default:
3290 3338
        goto illegal_op;
3291 3339
    }
......
3315 3363
    [INDEX_op_sbbw_T0_T1_cc] = CC_C,
3316 3364
    [INDEX_op_sbbl_T0_T1_cc] = CC_C,
3317 3365

  
3366
    /* subtle: due to the incl/decl implementation, C is used */
3367
    [INDEX_op_incl_T0_cc] = CC_C, 
3368
    [INDEX_op_decl_T0_cc] = CC_C,
3369

  
3318 3370
    [INDEX_op_into] = CC_O,
3319 3371

  
3320 3372
    [INDEX_op_jo_cc] = CC_O,
......
3416 3468
    [INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,
3417 3469
    [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
3418 3470
    [INDEX_op_negl_T0_cc] = CC_OSZAPC,
3419
    [INDEX_op_incl_T0_cc] = CC_OSZAP,
3420
    [INDEX_op_decl_T0_cc] = CC_OSZAP,
3471
    /* subtle: due to the incl/decl implementation, C is used */
3472
    [INDEX_op_incl_T0_cc] = CC_OSZAPC, 
3473
    [INDEX_op_decl_T0_cc] = CC_OSZAPC,
3421 3474
    [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
3422 3475

  
3423 3476
    [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
......
3659 3712
    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
3660 3713
    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
3661 3714
    dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;
3715
    dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;
3716
    dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;
3662 3717
    dc->cc_op = CC_OP_DYNAMIC;
3663 3718
    dc->cs_base = cs_base;
3664 3719

  
......
3697 3752
	disas(logfile, pc_start, pc_ptr - pc_start,
3698 3753
	      dc->code32 ? DISAS_I386_I386 : DISAS_I386_I8086);
3699 3754
        fprintf(logfile, "\n");
3700
        
3755

  
3701 3756
        fprintf(logfile, "OP:\n");
3702 3757
        dump_ops(gen_opc_buf, gen_opparam_buf);
3703 3758
        fprintf(logfile, "\n");

Also available in: Unified diff