Revision a2cc3b24 target-i386/translate.c

b/target-i386/translate.c
1747 1747
{
1748 1748
    if (s->cc_op != CC_OP_DYNAMIC)
1749 1749
        gen_op_set_cc_op(s->cc_op);
1750
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
1751
        gen_op_reset_inhibit_irq();
1752
    }
1750 1753
    if (s->singlestep_enabled) {
1751 1754
        gen_op_debug();
1752 1755
    } else if (s->tf) {
......
2385 2388
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
2386 2389
        gen_pop_update(s);
2387 2390
        if (reg == R_SS) {
2388
            /* if reg == SS, inhibit interrupts/trace */
2389
            gen_op_set_inhibit_irq();
2391
            /* if reg == SS, inhibit interrupts/trace. */
2392
            /* If several instructions disable interrupts, only the
2393
               _first_ does it */
2394
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
2395
                gen_op_set_inhibit_irq();
2390 2396
            s->tf = 0;
2391 2397
        }
2392 2398
        if (s->is_jmp) {
......
2457 2463
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
2458 2464
        if (reg == R_SS) {
2459 2465
            /* if reg == SS, inhibit interrupts/trace */
2460
            gen_op_set_inhibit_irq();
2466
            /* If several instructions disable interrupts, only the
2467
               _first_ does it */
2468
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
2469
                gen_op_set_inhibit_irq();
2461 2470
            s->tf = 0;
2462 2471
        }
2463 2472
        if (s->is_jmp) {
......
3176 3185
                gen_op_fpop();
3177 3186
                s->cc_op = CC_OP_EFLAGS;
3178 3187
                break;
3188
            case 0x10 ... 0x13: /* fcmovxx */
3189
            case 0x18 ... 0x1b:
3190
                {
3191
                    int op1;
3192
                    const static uint8_t fcmov_cc[8] = {
3193
                        (JCC_B << 1),
3194
                        (JCC_Z << 1),
3195
                        (JCC_BE << 1),
3196
                        (JCC_P << 1),
3197
                    };
3198
                    op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
3199
                    gen_setcc(s, op1);
3200
                    gen_op_fcmov_ST0_STN_T0(opreg);
3201
                }
3202
                break;
3179 3203
            default:
3180 3204
                goto illegal_op;
3181 3205
            }
......
3730 3754
            gen_sti:
3731 3755
                gen_op_sti();
3732 3756
                /* interruptions are enabled only the first insn after sti */
3733
                gen_op_set_inhibit_irq();
3757
                /* If several instructions disable interrupts, only the
3758
                   _first_ does it */
3759
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3760
                    gen_op_set_inhibit_irq();
3734 3761
                /* give a chance to handle pending irqs */
3735 3762
                gen_op_jmp_im(s->pc - s->cs_base);
3736 3763
                gen_eob(s);
......
4459 4486
        else
4460 4487
            dc->mem_index = 3;
4461 4488
    }
4462
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled
4489
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
4490
                    (flags & HF_INHIBIT_IRQ_MASK)
4463 4491
#ifndef CONFIG_SOFTMMU
4464 4492
                    || (flags & HF_SOFTMMU_MASK)
4465 4493
#endif
......
4472 4500
    pc_ptr = pc_start;
4473 4501
    lj = -1;
4474 4502

  
4475
    /* if irq were inhibited for the next instruction, we can disable
4476
       them here as it is simpler (otherwise jumps would have to
4477
       handled as special case) */
4478
    if (flags & HF_INHIBIT_IRQ_MASK) {
4479
        gen_op_reset_inhibit_irq();
4480
    }
4481 4503
    for(;;) {
4482 4504
        if (env->nb_breakpoints > 0) {
4483 4505
            for(j = 0; j < env->nb_breakpoints; j++) {
......
4504 4526
            break;
4505 4527
        /* if single step mode, we generate only one instruction and
4506 4528
           generate an exception */
4507
        if (dc->tf || dc->singlestep_enabled) {
4529
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
4530
           the flag and abort the translation to give the irqs a
4531
           change to be happen */
4532
        if (dc->tf || dc->singlestep_enabled || 
4533
            (flags & HF_INHIBIT_IRQ_MASK)) {
4508 4534
            gen_op_jmp_im(pc_ptr - dc->cs_base);
4509 4535
            gen_eob(dc);
4510 4536
            break;

Also available in: Unified diff