Revision 4136f33c

b/target-i386/exec.h
512 512
    return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
513 513
}
514 514

  
515
#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)
516

  
517
#define FL_UPDATE_CPL0_MASK (TF_MASK | IF_MASK | IOPL_MASK | NT_MASK | \
518
                             RF_MASK | AC_MASK | ID_MASK)
519

  
520 515
/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
521 516
static inline void load_eflags(int eflags, int update_mask)
522 517
{
b/target-i386/helper.c
419 419
    /* load all registers without an exception, then reload them with
420 420
       possible exception */
421 421
    env->eip = new_eip;
422
    eflags_mask = FL_UPDATE_CPL0_MASK;
422
    eflags_mask = TF_MASK | AC_MASK | ID_MASK | 
423
        IF_MASK | IOPL_MASK | VM_MASK | RF_MASK;
423 424
    if (!(type & 8))
424 425
        eflags_mask &= 0xffff;
425 426
    load_eflags(new_eflags, eflags_mask);
......
575 576
    uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
576 577
    uint32_t old_eip;
577 578

  
578
#ifdef DEBUG_PCALL
579
    if (loglevel) {
580
        static int count;
581
        fprintf(logfile, "%d: interrupt: vector=%02x error_code=%04x int=%d CS:IP=%04x:%08x CPL=%d\n",
582
                count, intno, error_code, is_int, env->segs[R_CS].selector, env->eip, env->hflags & 3);
583
#if 0
584
        {
585
            int i;
586
            uint8_t *ptr;
587
            printf("       code=");
588
            ptr = env->segs[R_CS].base + env->eip;
589
            for(i = 0; i < 16; i++) {
590
                printf(" %02x", ldub(ptr + i));
591
            }
592
            printf("\n");
593
        }
594
#endif
595
        count++;
596
    }
597
#endif
598

  
599 579
    has_error_code = 0;
600 580
    if (!is_int && !is_hw) {
601 581
        switch(intno) {
......
775 755

  
776 756
/* real mode interrupt */
777 757
static void do_interrupt_real(int intno, int is_int, int error_code,
778
                                 unsigned int next_eip)
758
                              unsigned int next_eip)
779 759
{
780 760
    SegmentCache *dt;
781 761
    uint8_t *ptr, *ssp;
......
844 824
void do_interrupt(int intno, int is_int, int error_code, 
845 825
                  unsigned int next_eip, int is_hw)
846 826
{
827
#ifdef DEBUG_PCALL
828
    if (loglevel) {
829
        static int count;
830
        fprintf(logfile, "%d: interrupt: vector=%02x error_code=%04x int=%d\n",
831
                count, intno, error_code, is_int);
832
        cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
833
#if 0
834
        {
835
            int i;
836
            uint8_t *ptr;
837
            printf("       code=");
838
            ptr = env->segs[R_CS].base + env->eip;
839
            for(i = 0; i < 16; i++) {
840
                printf(" %02x", ldub(ptr + i));
841
            }
842
            printf("\n");
843
        }
844
#endif
845
        count++;
846
    }
847
#endif
847 848
    if (env->cr[0] & CR0_PE_MASK) {
848 849
        do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
849 850
    } else {
......
1293 1294
    if (loglevel) {
1294 1295
        fprintf(logfile, "lcall %04x:%08x\n",
1295 1296
                new_cs, new_eip);
1297
        cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
1296 1298
    }
1297 1299
#endif
1298 1300
    if ((new_cs & 0xfffc) == 0)
......
1493 1495
        POPW(ssp, sp, sp_mask, new_cs);
1494 1496
        POPW(ssp, sp, sp_mask, new_eflags);
1495 1497
    }
1496
    ESP = (ESP & ~sp_mask) | (sp & 0xffff);
1498
    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
1497 1499
    load_seg_vm(R_CS, new_cs);
1498 1500
    env->eip = new_eip;
1499 1501
    if (env->eflags & VM_MASK)
1500
        eflags_mask = FL_UPDATE_MASK32 | IF_MASK | RF_MASK;
1502
        eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK;
1501 1503
    else
1502
        eflags_mask = FL_UPDATE_CPL0_MASK;
1504
        eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK;
1503 1505
    if (shift == 0)
1504 1506
        eflags_mask &= 0xffff;
1505 1507
    load_eflags(new_eflags, eflags_mask);
......
1511 1513
    uint32_t sp, new_cs, new_eip, new_eflags, new_esp, new_ss, sp_mask;
1512 1514
    uint32_t new_es, new_ds, new_fs, new_gs;
1513 1515
    uint32_t e1, e2, ss_e1, ss_e2;
1514
    int cpl, dpl, rpl, eflags_mask;
1516
    int cpl, dpl, rpl, eflags_mask, iopl;
1515 1517
    uint8_t *ssp;
1516 1518
    
1517 1519
    sp_mask = get_sp_mask(env->segs[R_SS].flags);
......
1536 1538
    }
1537 1539
#ifdef DEBUG_PCALL
1538 1540
    if (loglevel) {
1539
        fprintf(logfile, "lret new %04x:%08x\n",
1540
                new_cs, new_eip);
1541
        fprintf(logfile, "lret new %04x:%08x addend=0x%x\n",
1542
                new_cs, new_eip, addend);
1543
        cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
1541 1544
    }
1542 1545
#endif
1543 1546
    if ((new_cs & 0xfffc) == 0)
......
1611 1614
    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
1612 1615
    env->eip = new_eip;
1613 1616
    if (is_iret) {
1614
        /* NOTE: 'cpl' can be different from the current CPL */
1617
        /* NOTE: 'cpl' is the _old_ CPL */
1618
        eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK;
1615 1619
        if (cpl == 0)
1616
            eflags_mask = FL_UPDATE_CPL0_MASK;
1617
        else
1618
            eflags_mask = FL_UPDATE_MASK32;
1620
            eflags_mask |= IOPL_MASK;
1621
        iopl = (env->eflags >> IOPL_SHIFT) & 3;
1622
        if (cpl <= iopl)
1623
            eflags_mask |= IF_MASK;
1619 1624
        if (shift == 0)
1620 1625
            eflags_mask &= 0xffff;
1621 1626
        load_eflags(new_eflags, eflags_mask);
......
1631 1636
    POPL(ssp, sp, sp_mask, new_gs);
1632 1637
    
1633 1638
    /* modify processor state */
1634
    load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);
1639
    load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK | 
1640
                IF_MASK | IOPL_MASK | VM_MASK | VIF_MASK | VIP_MASK);
1635 1641
    load_seg_vm(R_CS, new_cs & 0xffff);
1636 1642
    cpu_x86_set_cpl(env, 3);
1637 1643
    load_seg_vm(R_SS, new_ss & 0xffff);
b/target-i386/op.c
1138 1138
    CC_OP = PARAM1;
1139 1139
}
1140 1140

  
1141
#define FL_UPDATE_MASK16 (FL_UPDATE_MASK32 & 0xffff)
1141
/* XXX: clear VIF/VIP in all ops ? */
1142 1142

  
1143 1143
void OPPROTO op_movl_eflags_T0(void)
1144 1144
{
1145
    int eflags;
1146
    eflags = T0;
1147
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1148
    DF = 1 - (2 * ((eflags >> 10) & 1));
1149
    /* we also update some system flags as in user mode */
1150
    env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | 
1151
        (eflags & FL_UPDATE_MASK32);
1145
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK));
1152 1146
}
1153 1147

  
1154 1148
void OPPROTO op_movw_eflags_T0(void)
1155 1149
{
1156
    int eflags;
1157
    eflags = T0;
1158
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1159
    DF = 1 - (2 * ((eflags >> 10) & 1));
1160
    /* we also update some system flags as in user mode */
1161
    env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | 
1162
        (eflags & FL_UPDATE_MASK16);
1150
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK) & 0xffff);
1151
}
1152

  
1153
void OPPROTO op_movl_eflags_T0_io(void)
1154
{
1155
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK));
1156
}
1157

  
1158
void OPPROTO op_movw_eflags_T0_io(void)
1159
{
1160
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK) & 0xffff);
1163 1161
}
1164 1162

  
1165 1163
void OPPROTO op_movl_eflags_T0_cpl0(void)
1166 1164
{
1167
    load_eflags(T0, FL_UPDATE_CPL0_MASK);
1165
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK));
1168 1166
}
1169 1167

  
1170 1168
void OPPROTO op_movw_eflags_T0_cpl0(void)
1171 1169
{
1172
    load_eflags(T0, FL_UPDATE_CPL0_MASK & 0xffff);
1170
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK) & 0xffff);
1173 1171
}
1174 1172

  
1175 1173
#if 0
b/target-i386/translate.c
3540 3540
                    gen_op_movw_eflags_T0_cpl0();
3541 3541
                }
3542 3542
            } else {
3543
                if (s->dflag) {
3544
                    gen_op_movl_eflags_T0();
3543
                if (s->cpl <= s->iopl) {
3544
                    if (s->dflag) {
3545
                        gen_op_movl_eflags_T0_io();
3546
                    } else {
3547
                        gen_op_movw_eflags_T0_io();
3548
                    }
3545 3549
                } else {
3546
                    gen_op_movw_eflags_T0();
3550
                    if (s->dflag) {
3551
                        gen_op_movl_eflags_T0();
3552
                    } else {
3553
                        gen_op_movw_eflags_T0();
3554
                    }
3547 3555
                }
3548 3556
            }
3549 3557
            gen_pop_update(s);
......
4265 4273
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
4266 4274
    [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
4267 4275
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
4276
    [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
4277
    [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
4278
    [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
4279
    [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
4268 4280
    [INDEX_op_clc] = CC_C,
4269 4281
    [INDEX_op_stc] = CC_C,
4270 4282
    [INDEX_op_cmc] = CC_C,

Also available in: Unified diff