Revision c50c0c3f translate-i386.c

b/translate-i386.c
132 132
    int vm86;   /* vm86 mode */
133 133
    int cpl;
134 134
    int iopl;
135
    int tf;     /* TF cpu flag */
135 136
} DisasContext;
136 137

  
137 138
/* i386 arith/logic operations */
......
1366 1367
    gen_op_mov_reg_T1[ot][R_ESP]();
1367 1368
}
1368 1369

  
1370
static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip)
1371
{
1372
    if (s->cc_op != CC_OP_DYNAMIC)
1373
        gen_op_set_cc_op(s->cc_op);
1374
    gen_op_jmp_im(cur_eip);
1375
    gen_op_raise_exception(trapno);
1376
    s->is_jmp = 1;
1377
}
1378

  
1369 1379
/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1370 1380
   is set to true if the instruction sets the PC (last instruction of
1371 1381
   a basic block) */
......
2770 2780
    case 0x6d:
2771 2781
        if (s->cpl > s->iopl || s->vm86) {
2772 2782
            /* NOTE: even for (E)CX = 0 the exception is raised */
2773
            gen_op_gpf(pc_start - s->cs_base);
2774
            s->is_jmp = 1;
2783
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2775 2784
        } else {
2776 2785
            if ((b & 1) == 0)
2777 2786
                ot = OT_BYTE;
......
2788 2797
    case 0x6f:
2789 2798
        if (s->cpl > s->iopl || s->vm86) {
2790 2799
            /* NOTE: even for (E)CX = 0 the exception is raised */
2791
            gen_op_gpf(pc_start - s->cs_base);
2792
            s->is_jmp = 1;
2800
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2793 2801
        } else {
2794 2802
            if ((b & 1) == 0)
2795 2803
                ot = OT_BYTE;
......
2808 2816
    case 0xe4:
2809 2817
    case 0xe5:
2810 2818
        if (s->cpl > s->iopl || s->vm86) {
2811
            gen_op_gpf(pc_start - s->cs_base);
2812
            s->is_jmp = 1;
2819
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2813 2820
        } else {
2814 2821
            if ((b & 1) == 0)
2815 2822
                ot = OT_BYTE;
......
2824 2831
    case 0xe6:
2825 2832
    case 0xe7:
2826 2833
        if (s->cpl > s->iopl || s->vm86) {
2827
            gen_op_gpf(pc_start - s->cs_base);
2828
            s->is_jmp = 1;
2834
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2829 2835
        } else {
2830 2836
            if ((b & 1) == 0)
2831 2837
                ot = OT_BYTE;
......
2840 2846
    case 0xec:
2841 2847
    case 0xed:
2842 2848
        if (s->cpl > s->iopl || s->vm86) {
2843
            gen_op_gpf(pc_start - s->cs_base);
2844
            s->is_jmp = 1;
2849
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2845 2850
        } else {
2846 2851
            if ((b & 1) == 0)
2847 2852
                ot = OT_BYTE;
......
2855 2860
    case 0xee:
2856 2861
    case 0xef:
2857 2862
        if (s->cpl > s->iopl || s->vm86) {
2858
            gen_op_gpf(pc_start - s->cs_base);
2859
            s->is_jmp = 1;
2863
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2860 2864
        } else {
2861 2865
            if ((b & 1) == 0)
2862 2866
                ot = OT_BYTE;
......
2928 2932
        break;
2929 2933
    case 0xcf: /* iret */
2930 2934
        if (s->vm86 && s->iopl != 3) {
2931
            gen_op_gpf(pc_start - s->cs_base);
2932
            s->is_jmp = 1;
2935
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2933 2936
        } else {
2934 2937
            /* XXX: not restartable */
2935 2938
            /* pop offset */
......
3066 3069
        /* flags */
3067 3070
    case 0x9c: /* pushf */
3068 3071
        if (s->vm86 && s->iopl != 3) {
3069
            gen_op_gpf(pc_start - s->cs_base);
3070
            s->is_jmp = 1;
3072
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3071 3073
        } else {
3072 3074
            if (s->cc_op != CC_OP_DYNAMIC)
3073 3075
                gen_op_set_cc_op(s->cc_op);
......
3077 3079
        break;
3078 3080
    case 0x9d: /* popf */
3079 3081
        if (s->vm86 && s->iopl != 3) {
3080
            gen_op_gpf(pc_start - s->cs_base);
3081
            s->is_jmp = 1;
3082
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3082 3083
        } else {
3083 3084
            gen_pop_T0(s);
3084 3085
            if (s->dflag) {
......
3248 3249
    case 0x90: /* nop */
3249 3250
        break;
3250 3251
    case 0xcc: /* int3 */
3251
        gen_op_int3((long)pc_start);
3252
        s->is_jmp = 1;
3252
        gen_exception(s, EXCP03_INT3, pc_start - s->cs_base);
3253 3253
        break;
3254 3254
    case 0xcd: /* int N */
3255 3255
        val = ldub(s->pc++);
3256
        if (s->cc_op != CC_OP_DYNAMIC)
3257
            gen_op_set_cc_op(s->cc_op);
3256 3258
        gen_op_int_im(val, pc_start - s->cs_base);
3257 3259
        s->is_jmp = 1;
3258 3260
        break;
......
3266 3268
            if (s->cpl <= s->iopl) {
3267 3269
                gen_op_cli();
3268 3270
            } else {
3269
                gen_op_gpf(pc_start - s->cs_base);
3270
                s->is_jmp = 1;
3271
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3271 3272
            }
3272 3273
        } else {
3273 3274
            if (s->iopl == 3) {
3274 3275
                gen_op_cli();
3275 3276
            } else {
3276
                gen_op_gpf(pc_start - s->cs_base);
3277
                s->is_jmp = 1;
3277
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3278 3278
            }
3279 3279
        }
3280 3280
        break;
......
3283 3283
            if (s->cpl <= s->iopl) {
3284 3284
                gen_op_sti();
3285 3285
            } else {
3286
                gen_op_gpf(pc_start - s->cs_base);
3287
                s->is_jmp = 1;
3286
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3288 3287
            }
3289 3288
        } else {
3290 3289
            if (s->iopl == 3) {
3291 3290
                gen_op_sti();
3292 3291
            } else {
3293
                gen_op_gpf(pc_start - s->cs_base);
3294
                s->is_jmp = 1;
3292
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3295 3293
            }
3296 3294
        }
3297 3295
        break;
......
3343 3341
        break;
3344 3342
    case 0xf4: /* hlt */
3345 3343
        /* XXX: if cpl == 0, then should do something else */
3346
        gen_op_gpf(pc_start - s->cs_base);
3347
        s->is_jmp = 1;
3344
        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3348 3345
        break;
3349 3346
    default:
3350 3347
        goto illegal_op;
......
3453 3450
    [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
3454 3451

  
3455 3452
    [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
3456
    [INDEX_op_movl_T0_eflags_vm] = CC_OSZAPC,
3457 3453
    [INDEX_op_cmc] = CC_C,
3458 3454
    [INDEX_op_salc] = CC_C,
3459 3455

  
......
3504 3500

  
3505 3501
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
3506 3502
    [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
3507
    [INDEX_op_movw_eflags_T0_vm] = CC_OSZAPC,
3508 3503
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
3509
    [INDEX_op_movl_eflags_T0_vm] = CC_OSZAPC,
3510 3504
    [INDEX_op_clc] = CC_C,
3511 3505
    [INDEX_op_stc] = CC_C,
3512 3506
    [INDEX_op_cmc] = CC_C,
......
3726 3720
    dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;
3727 3721
    dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;
3728 3722
    dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;
3723
    dc->tf = (flags >> GEN_FLAG_TF_SHIFT) & 1;
3729 3724
    dc->cc_op = CC_OP_DYNAMIC;
3730 3725
    dc->cs_base = cs_base;
3731 3726

  
......
3747 3742
                break;
3748 3743
        }
3749 3744
        pc_ptr = (void *)ret;
3745
        /* if single step mode, we generate only one instruction and
3746
           generate an exception */
3747
        if (dc->tf)
3748
            break;
3750 3749
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);
3751 3750
    /* we must store the eflags state if it is not already done */
3752 3751
    if (dc->cc_op != CC_OP_DYNAMIC)
......
3755 3754
        /* we add an additionnal jmp to update the simulated PC */
3756 3755
        gen_op_jmp_im(ret - (unsigned long)dc->cs_base);
3757 3756
    }
3757
    if (dc->tf) {
3758
        gen_op_raise_exception(EXCP01_SSTP);
3759
    }
3760

  
3758 3761
    *gen_opc_ptr = INDEX_op_end;
3759 3762

  
3760 3763
#ifdef DEBUG_DISAS

Also available in: Unified diff