static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,

                                   int error_code, unsigned int next_eip,

                                   int is_hw)

{

    SegmentCache *dt;

    target_ulong ptr, ssp;

    int type, dpl, selector, ss_dpl, cpl;

    int has_error_code, new_stack, shift;

    uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;

    uint32_t old_eip, sp_mask;

    int vm86 = env->eflags & VM_MASK;



    has_error_code = 0;

    if (!is_int && !is_hw) {

        has_error_code = exception_has_error_code(intno);

    }

    if (is_int) {

        old_eip = next_eip;

    } else {

        old_eip = env->eip;

    }



    dt = &env->idt;

    if (intno * 8 + 7 > dt->limit) {

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

    }

    ptr = dt->base + intno * 8;

    e1 = cpu_ldl_kernel(env, ptr);

    e2 = cpu_ldl_kernel(env, ptr + 4);

    /* check gate type */

    type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;

    switch (type) {

    case 5: /* task gate */

        /* must do that check here to return the correct error code */

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);

        }

        switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);

        if (has_error_code) {

            int type;

            uint32_t mask;



            /* push the error code */

            type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;

            shift = type >> 3;

            if (env->segs[R_SS].flags & DESC_B_MASK) {

                mask = 0xffffffff;

            } else {

                mask = 0xffff;

            }

            esp = (env->regs[R_ESP] - (2 << shift)) & mask;

            ssp = env->segs[R_SS].base + esp;

            if (shift) {

                cpu_stl_kernel(env, ssp, error_code);

            } else {

                cpu_stw_kernel(env, ssp, error_code);

            }

            SET_ESP(esp, mask);

        }

        return;

    case 6: /* 286 interrupt gate */

    case 7: /* 286 trap gate */

    case 14: /* 386 interrupt gate */

    case 15: /* 386 trap gate */

        break;

    default:

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

        break;

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    cpl = env->hflags & HF_CPL_MASK;

    /* check privilege if software int */

    if (is_int && dpl < cpl) {

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

    }

    /* check valid bit */

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);

    }

    selector = e1 >> 16;

    offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    if ((selector & 0xfffc) == 0) {

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

    if (load_segment(env, &e1, &e2, selector) != 0) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    if (dpl > cpl) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);

    }

    if (!(e2 & DESC_C_MASK) && dpl < cpl) {

        /* to inner privilege */

        get_ss_esp_from_tss(env, &ss, &esp, dpl, 0);

        if ((ss & 0xfffc) == 0) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if ((ss & 3) != dpl) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;

        if (ss_dpl != dpl) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_S_MASK) ||

            (ss_e2 & DESC_CS_MASK) ||

            !(ss_e2 & DESC_W_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        new_stack = 1;

        sp_mask = get_sp_mask(ss_e2);

        ssp = get_seg_base(ss_e1, ss_e2);

    } else if ((e2 & DESC_C_MASK) || dpl == cpl) {

        /* to same privilege */

        if (vm86) {

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

        new_stack = 0;

        sp_mask = get_sp_mask(env->segs[R_SS].flags);

        ssp = env->segs[R_SS].base;

        esp = env->regs[R_ESP];

        dpl = cpl;

    } else {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        new_stack = 0; /* avoid warning */

        sp_mask = 0; /* avoid warning */

        ssp = 0; /* avoid warning */

        esp = 0; /* avoid warning */

    }



    shift = type >> 3;



#if 0

    /* XXX: check that enough room is available */

    push_size = 6 + (new_stack << 2) + (has_error_code << 1);

    if (vm86) {

        push_size += 8;

    }

    push_size <<= shift;

#endif

    if (shift == 1) {

        if (new_stack) {

            if (vm86) {

                PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);

            }

            PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);

            PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]);

        }

        PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env));

        PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);

        PUSHL(ssp, esp, sp_mask, old_eip);

        if (has_error_code) {

            PUSHL(ssp, esp, sp_mask, error_code);

        }

    } else {

        if (new_stack) {

            if (vm86) {

                PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);

            }

            PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);

            PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]);

        }

        PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));

        PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);

        PUSHW(ssp, esp, sp_mask, old_eip);

        if (has_error_code) {

            PUSHW(ssp, esp, sp_mask, error_code);

        }

    }



    /* interrupt gate clear IF mask */

    if ((type & 1) == 0) {

        env->eflags &= ~IF_MASK;

    }

    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);



    if (new_stack) {

        if (vm86) {

            cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);

        }

        ss = (ss & ~3) | dpl;

        cpu_x86_load_seg_cache(env, R_SS, ss,

                               ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);

    }

    SET_ESP(esp, sp_mask);



    selector = (selector & ~3) | dpl;

    cpu_x86_load_seg_cache(env, R_CS, selector,

                   get_seg_base(e1, e2),

                   get_seg_limit(e1, e2),

                   e2);

    env->eip = offset;

}

static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,

                                   int error_code, unsigned int next_eip,

                                   int is_hw)

{

    SegmentCache *dt;

    target_ulong ptr, ssp;

    int type, dpl, selector, ss_dpl, cpl;

    int has_error_code, new_stack, shift;

    uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;

    uint32_t old_eip, sp_mask;

    int vm86 = env->eflags & VM_MASK;



    has_error_code = 0;

    if (!is_int && !is_hw) {

        has_error_code = exception_has_error_code(intno);

    }

    if (is_int) {

        old_eip = next_eip;

    } else {

        old_eip = env->eip;

    }



    dt = &env->idt;

    if (intno * 8 + 7 > dt->limit) {

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

    }

    ptr = dt->base + intno * 8;

    e1 = cpu_ldl_kernel(env, ptr);

    e2 = cpu_ldl_kernel(env, ptr + 4);

    

    type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;

    switch (type) {

    case 5: 

        

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);

        }

        switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);

        if (has_error_code) {

            int type;

            uint32_t mask;



            

            type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;

            shift = type >> 3;

            if (env->segs[R_SS].flags & DESC_B_MASK) {

                mask = 0xffffffff;

            } else {

                mask = 0xffff;

            }

            esp = (env->regs[R_ESP] - (2 << shift)) & mask;

            ssp = env->segs[R_SS].base + esp;

            if (shift) {

                cpu_stl_kernel(env, ssp, error_code);

            } else {

                cpu_stw_kernel(env, ssp, error_code);

            }

            SET_ESP(esp, mask);

        }

        return;

    case 6: 

    case 7: 

    case 14: 

    case 15: 

        break;

    default:

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

        break;

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    cpl = env->hflags & HF_CPL_MASK;

    

    if (is_int && dpl < cpl) {

        raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);

    }

    

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);

    }

    selector = e1 >> 16;

    offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    if ((selector & 0xfffc) == 0) {

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

    if (load_segment(env, &e1, &e2, selector) != 0) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    if (dpl > cpl) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);

    }

    if (!(e2 & DESC_C_MASK) && dpl < cpl) {

        

        get_ss_esp_from_tss(env, &ss, &esp, dpl, 0);

        if ((ss & 0xfffc) == 0) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if ((ss & 3) != dpl) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;

        if (ss_dpl != dpl) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_S_MASK) ||

            (ss_e2 & DESC_CS_MASK) ||

            !(ss_e2 & DESC_W_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

        }

        new_stack = 1;

        sp_mask = get_sp_mask(ss_e2);

        ssp = get_seg_base(ss_e1, ss_e2);

    } else if ((e2 & DESC_C_MASK) || dpl == cpl) {

        

        if (vm86) {

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

        new_stack = 0;

        sp_mask = get_sp_mask(env->segs[R_SS].flags);

        ssp = env->segs[R_SS].base;

        esp = env->regs[R_ESP];

        dpl = cpl;

    } else {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        new_stack = 0; 

        sp_mask = 0; 

        ssp = 0; 

        esp = 0; 

    }



    shift = type >> 3;



#if 0

    

    push_size = 6 + (new_stack << 2) + (has_error_code << 1);

    if (vm86) {

        push_size += 8;

    }

    push_size <<= shift;

#endif

    if (shift == 1) {

        if (new_stack) {

            if (vm86) {

                PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector);

                PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);

            }

            PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);

            PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]);

        }

        PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env));

        PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);

        PUSHL(ssp, esp, sp_mask, old_eip);

        if (has_error_code) {

            PUSHL(ssp, esp, sp_mask, error_code);

        }

    } else {

        if (new_stack) {

            if (vm86) {

                PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector);

                PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);

            }

            PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);

            PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]);

        }

        PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));

        PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);

        PUSHW(ssp, esp, sp_mask, old_eip);

        if (has_error_code) {

            PUSHW(ssp, esp, sp_mask, error_code);

        }

    }



    

    if ((type & 1) == 0) {

        env->eflags &= ~IF_MASK;

    }

    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);



    if (new_stack) {

        if (vm86) {

            cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);

        }

        ss = (ss & ~3) | dpl;

        cpu_x86_load_seg_cache(env, R_SS, ss,

                               ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);

    }

    SET_ESP(esp, sp_mask);



    selector = (selector & ~3) | dpl;

    cpu_x86_load_seg_cache(env, R_CS, selector,

                   get_seg_base(e1, e2),

                   get_seg_limit(e1, e2),

                   e2);

    env->eip = offset;

}

static void FUNC_0(CPUX86State *VAR_0, int VAR_1, int VAR_2,

                                   int VAR_3, unsigned int VAR_4,

                                   int VAR_5)

{

    SegmentCache *dt;

    target_ulong ptr, ssp;

    int VAR_15, VAR_7, VAR_8, VAR_9, VAR_10;

    int VAR_11, VAR_12, VAR_13;

    uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;

    uint32_t old_eip, sp_mask;

    int VAR_14 = VAR_0->eflags & VM_MASK;



    VAR_11 = 0;

    if (!VAR_2 && !VAR_5) {

        VAR_11 = exception_has_error_code(VAR_1);

    }

    if (VAR_2) {

        old_eip = VAR_4;

    } else {

        old_eip = VAR_0->eip;

    }



    dt = &VAR_0->idt;

    if (VAR_1 * 8 + 7 > dt->limit) {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2);

    }

    ptr = dt->base + VAR_1 * 8;

    e1 = cpu_ldl_kernel(VAR_0, ptr);

    e2 = cpu_ldl_kernel(VAR_0, ptr + 4);

    

    VAR_15 = (e2 >> DESC_TYPE_SHIFT) & 0x1f;

    switch (VAR_15) {

    case 5: 

        

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_1 * 8 + 2);

        }

        switch_tss(VAR_0, VAR_1 * 8, e1, e2, SWITCH_TSS_CALL, old_eip);

        if (VAR_11) {

            int VAR_15;

            uint32_t mask;



            

            VAR_15 = (VAR_0->tr.flags >> DESC_TYPE_SHIFT) & 0xf;

            VAR_13 = VAR_15 >> 3;

            if (VAR_0->segs[R_SS].flags & DESC_B_MASK) {

                mask = 0xffffffff;

            } else {

                mask = 0xffff;

            }

            esp = (VAR_0->regs[R_ESP] - (2 << VAR_13)) & mask;

            ssp = VAR_0->segs[R_SS].base + esp;

            if (VAR_13) {

                cpu_stl_kernel(VAR_0, ssp, VAR_3);

            } else {

                cpu_stw_kernel(VAR_0, ssp, VAR_3);

            }

            SET_ESP(esp, mask);

        }

        return;

    case 6: 

    case 7: 

    case 14: 

    case 15: 

        break;

    default:

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2);

        break;

    }

    VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3;

    VAR_10 = VAR_0->hflags & HF_CPL_MASK;

    

    if (VAR_2 && VAR_7 < VAR_10) {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2);

    }

    

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_1 * 8 + 2);

    }

    VAR_8 = e1 >> 16;

    offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    if ((VAR_8 & 0xfffc) == 0) {

        raise_exception_err(VAR_0, EXCP0D_GPF, 0);

    }

    if (load_segment(VAR_0, &e1, &e2, VAR_8) != 0) {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc);

    }

    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc);

    }

    VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3;

    if (VAR_7 > VAR_10) {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc);

    }

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_8 & 0xfffc);

    }

    if (!(e2 & DESC_C_MASK) && VAR_7 < VAR_10) {

        

        get_ss_esp_from_tss(VAR_0, &ss, &esp, VAR_7, 0);

        if ((ss & 0xfffc) == 0) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        if ((ss & 3) != VAR_7) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        if (load_segment(VAR_0, &ss_e1, &ss_e2, ss) != 0) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        VAR_9 = (ss_e2 >> DESC_DPL_SHIFT) & 3;

        if (VAR_9 != VAR_7) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_S_MASK) ||

            (ss_e2 & DESC_CS_MASK) ||

            !(ss_e2 & DESC_W_MASK)) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        if (!(ss_e2 & DESC_P_MASK)) {

            raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc);

        }

        VAR_12 = 1;

        sp_mask = get_sp_mask(ss_e2);

        ssp = get_seg_base(ss_e1, ss_e2);

    } else if ((e2 & DESC_C_MASK) || VAR_7 == VAR_10) {

        

        if (VAR_14) {

            raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc);

        }

        VAR_12 = 0;

        sp_mask = get_sp_mask(VAR_0->segs[R_SS].flags);

        ssp = VAR_0->segs[R_SS].base;

        esp = VAR_0->regs[R_ESP];

        VAR_7 = VAR_10;

    } else {

        raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc);

        VAR_12 = 0; 

        sp_mask = 0; 

        ssp = 0; 

        esp = 0; 

    }



    VAR_13 = VAR_15 >> 3;



#if 0

    

    push_size = 6 + (VAR_12 << 2) + (VAR_11 << 1);

    if (VAR_14) {

        push_size += 8;

    }

    push_size <<= VAR_13;

#endif

    if (VAR_13 == 1) {

        if (VAR_12) {

            if (VAR_14) {

                PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_GS].VAR_8);

                PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_FS].VAR_8);

                PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_DS].VAR_8);

                PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_ES].VAR_8);

            }

            PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_SS].VAR_8);

            PUSHL(ssp, esp, sp_mask, VAR_0->regs[R_ESP]);

        }

        PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(VAR_0));

        PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_CS].VAR_8);

        PUSHL(ssp, esp, sp_mask, old_eip);

        if (VAR_11) {

            PUSHL(ssp, esp, sp_mask, VAR_3);

        }

    } else {

        if (VAR_12) {

            if (VAR_14) {

                PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_GS].VAR_8);

                PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_FS].VAR_8);

                PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_DS].VAR_8);

                PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_ES].VAR_8);

            }

            PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_SS].VAR_8);

            PUSHW(ssp, esp, sp_mask, VAR_0->regs[R_ESP]);

        }

        PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(VAR_0));

        PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_CS].VAR_8);

        PUSHW(ssp, esp, sp_mask, old_eip);

        if (VAR_11) {

            PUSHW(ssp, esp, sp_mask, VAR_3);

        }

    }



    

    if ((VAR_15 & 1) == 0) {

        VAR_0->eflags &= ~IF_MASK;

    }

    VAR_0->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);



    if (VAR_12) {

        if (VAR_14) {

            cpu_x86_load_seg_cache(VAR_0, R_ES, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(VAR_0, R_DS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(VAR_0, R_FS, 0, 0, 0, 0);

            cpu_x86_load_seg_cache(VAR_0, R_GS, 0, 0, 0, 0);

        }

        ss = (ss & ~3) | VAR_7;

        cpu_x86_load_seg_cache(VAR_0, R_SS, ss,

                               ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);

    }

    SET_ESP(esp, sp_mask);



    VAR_8 = (VAR_8 & ~3) | VAR_7;

    cpu_x86_load_seg_cache(VAR_0, R_CS, VAR_8,

                   get_seg_base(e1, e2),

                   get_seg_limit(e1, e2),

                   e2);

    VAR_0->eip = offset;

}

static void FUNC_0(CPUX86State *VAR_0, int VAR_1, int VAR_2,
int VAR_3, unsigned int VAR_4,
int VAR_5)
{ SegmentCache *dt; target_ulong ptr, ssp; int VAR_15, VAR_7, VAR_8, VAR_9, VAR_10; int VAR_11, VAR_12, VAR_13; uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0; uint32_t old_eip, sp_mask; int VAR_14 = VAR_0->eflags & VM_MASK; VAR_11 = 0; if (!VAR_2 && !VAR_5) { VAR_11 = exception_has_error_code(VAR_1); } if (VAR_2) { old_eip = VAR_4; } else { old_eip = VAR_0->eip; } dt = &VAR_0->idt; if (VAR_1 * 8 + 7 > dt->limit) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2); } ptr = dt->base + VAR_1 * 8; e1 = cpu_ldl_kernel(VAR_0, ptr); e2 = cpu_ldl_kernel(VAR_0, ptr + 4); VAR_15 = (e2 >> DESC_TYPE_SHIFT) & 0x1f; switch (VAR_15) { case 5:
if (!(e2 & DESC_P_MASK)) { raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_1 * 8 + 2); } switch_tss(VAR_0, VAR_1 * 8, e1, e2, SWITCH_TSS_CALL, old_eip); if (VAR_11) { int VAR_15; uint32_t mask; VAR_15 = (VAR_0->tr.flags >> DESC_TYPE_SHIFT) & 0xf; VAR_13 = VAR_15 >> 3; if (VAR_0->segs[R_SS].flags & DESC_B_MASK) { mask = 0xffffffff; } else { mask = 0xffff; } esp = (VAR_0->regs[R_ESP] - (2 << VAR_13)) & mask; ssp = VAR_0->segs[R_SS].base + esp; if (VAR_13) { cpu_stl_kernel(VAR_0, ssp, VAR_3); } else { cpu_stw_kernel(VAR_0, ssp, VAR_3); } SET_ESP(esp, mask); } return; case 6:
case 7:
case 14:
case 15:
break; default:
raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2); break; } VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3; VAR_10 = VAR_0->hflags & HF_CPL_MASK; if (VAR_2 && VAR_7 < VAR_10) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 8 + 2); } if (!(e2 & DESC_P_MASK)) { raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_1 * 8 + 2); } VAR_8 = e1 >> 16; offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); if ((VAR_8 & 0xfffc) == 0) { raise_exception_err(VAR_0, EXCP0D_GPF, 0); } if (load_segment(VAR_0, &e1, &e2, VAR_8) != 0) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3; if (VAR_7 > VAR_10) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } if (!(e2 & DESC_P_MASK)) { raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_8 & 0xfffc); } if (!(e2 & DESC_C_MASK) && VAR_7 < VAR_10) { get_ss_esp_from_tss(VAR_0, &ss, &esp, VAR_7, 0); if ((ss & 0xfffc) == 0) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } if ((ss & 3) != VAR_7) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } if (load_segment(VAR_0, &ss_e1, &ss_e2, ss) != 0) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } VAR_9 = (ss_e2 >> DESC_DPL_SHIFT) & 3; if (VAR_9 != VAR_7) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } if (!(ss_e2 & DESC_S_MASK) ||
(ss_e2 & DESC_CS_MASK) ||
!(ss_e2 & DESC_W_MASK)) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } if (!(ss_e2 & DESC_P_MASK)) { raise_exception_err(VAR_0, EXCP0A_TSS, ss & 0xfffc); } VAR_12 = 1; sp_mask = get_sp_mask(ss_e2); ssp = get_seg_base(ss_e1, ss_e2); } else if ((e2 & DESC_C_MASK) || VAR_7 == VAR_10) { if (VAR_14) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } VAR_12 = 0; sp_mask = get_sp_mask(VAR_0->segs[R_SS].flags); ssp = VAR_0->segs[R_SS].base; esp = VAR_0->regs[R_ESP]; VAR_7 = VAR_10; } else { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); VAR_12 = 0; sp_mask = 0; ssp = 0; esp = 0; } VAR_13 = VAR_15 >> 3; #if 0
push_size = 6 + (VAR_12 << 2) + (VAR_11 << 1); if (VAR_14) { push_size += 8; } push_size <<= VAR_13; #endif
if (VAR_13 == 1) { if (VAR_12) { if (VAR_14) { PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_GS].VAR_8); PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_FS].VAR_8); PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_DS].VAR_8); PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_ES].VAR_8); } PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_SS].VAR_8); PUSHL(ssp, esp, sp_mask, VAR_0->regs[R_ESP]); } PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(VAR_0)); PUSHL(ssp, esp, sp_mask, VAR_0->segs[R_CS].VAR_8); PUSHL(ssp, esp, sp_mask, old_eip); if (VAR_11) { PUSHL(ssp, esp, sp_mask, VAR_3); } } else { if (VAR_12) { if (VAR_14) { PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_GS].VAR_8); PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_FS].VAR_8); PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_DS].VAR_8); PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_ES].VAR_8); } PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_SS].VAR_8); PUSHW(ssp, esp, sp_mask, VAR_0->regs[R_ESP]); } PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(VAR_0)); PUSHW(ssp, esp, sp_mask, VAR_0->segs[R_CS].VAR_8); PUSHW(ssp, esp, sp_mask, old_eip); if (VAR_11) { PUSHW(ssp, esp, sp_mask, VAR_3); } } if ((VAR_15 & 1) == 0) { VAR_0->eflags &= ~IF_MASK; } VAR_0->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); if (VAR_12) { if (VAR_14) { cpu_x86_load_seg_cache(VAR_0, R_ES, 0, 0, 0, 0); cpu_x86_load_seg_cache(VAR_0, R_DS, 0, 0, 0, 0); cpu_x86_load_seg_cache(VAR_0, R_FS, 0, 0, 0, 0); cpu_x86_load_seg_cache(VAR_0, R_GS, 0, 0, 0, 0); } ss = (ss & ~3) | VAR_7; cpu_x86_load_seg_cache(VAR_0, R_SS, ss,
ssp, get_seg_limit(ss_e1, ss_e2), ss_e2); } SET_ESP(esp, sp_mask); VAR_8 = (VAR_8 & ~3) | VAR_7; cpu_x86_load_seg_cache(VAR_0, R_CS, VAR_8,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2); VAR_0->eip = offset; }