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

                           int error_code, target_ulong next_eip, int is_hw)

{

    SegmentCache *dt;

    target_ulong ptr;

    int type, dpl, selector, cpl, ist;

    int has_error_code, new_stack;

    uint32_t e1, e2, e3, ss;

    target_ulong old_eip, esp, offset;



    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 * 16 + 15 > dt->limit) {

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

    }

    ptr = dt->base + intno * 16;

    e1 = cpu_ldl_kernel(env, ptr);

    e2 = cpu_ldl_kernel(env, ptr + 4);

    e3 = cpu_ldl_kernel(env, ptr + 8);

    /* check gate type */

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

    switch (type) {

    case 14: /* 386 interrupt gate */

    case 15: /* 386 trap gate */

        break;

    default:

        raise_exception_err(env, EXCP0D_GPF, intno * 16 + 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 * 16 + 2);

    }

    /* check valid bit */

    if (!(e2 & DESC_P_MASK)) {

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

    }

    selector = e1 >> 16;

    offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    ist = e2 & 7;

    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_L_MASK) || (e2 & DESC_B_MASK)) {

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

    }

    if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {

        /* to inner privilege */

        if (ist != 0) {

            esp = get_rsp_from_tss(env, ist + 3);

        } else {

            esp = get_rsp_from_tss(env, dpl);

        }

        esp &= ~0xfLL; /* align stack */

        ss = 0;

        new_stack = 1;

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

        /* to same privilege */

        if (env->eflags & VM_MASK) {

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

        }

        new_stack = 0;

        if (ist != 0) {

            esp = get_rsp_from_tss(env, ist + 3);

        } else {

            esp = env->regs[R_ESP];

        }

        esp &= ~0xfLL; /* align stack */

        dpl = cpl;

    } else {

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

        new_stack = 0; /* avoid warning */

        esp = 0; /* avoid warning */

    }



    PUSHQ(esp, env->segs[R_SS].selector);

    PUSHQ(esp, env->regs[R_ESP]);

    PUSHQ(esp, cpu_compute_eflags(env));

    PUSHQ(esp, env->segs[R_CS].selector);

    PUSHQ(esp, old_eip);

    if (has_error_code) {

        PUSHQ(esp, 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) {

        ss = 0 | dpl;

        cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);

    }

    env->regs[R_ESP] = esp;



    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_interrupt64(CPUX86State *env, int intno, int is_int,

                           int error_code, target_ulong next_eip, int is_hw)

{

    SegmentCache *dt;

    target_ulong ptr;

    int type, dpl, selector, cpl, ist;

    int has_error_code, new_stack;

    uint32_t e1, e2, e3, ss;

    target_ulong old_eip, esp, offset;



    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 * 16 + 15 > dt->limit) {

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

    }

    ptr = dt->base + intno * 16;

    e1 = cpu_ldl_kernel(env, ptr);

    e2 = cpu_ldl_kernel(env, ptr + 4);

    e3 = cpu_ldl_kernel(env, ptr + 8);

    

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

    switch (type) {

    case 14: 

    case 15: 

        break;

    default:

        raise_exception_err(env, EXCP0D_GPF, intno * 16 + 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 * 16 + 2);

    }

    

    if (!(e2 & DESC_P_MASK)) {

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

    }

    selector = e1 >> 16;

    offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    ist = e2 & 7;

    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_L_MASK) || (e2 & DESC_B_MASK)) {

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

    }

    if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {

        

        if (ist != 0) {

            esp = get_rsp_from_tss(env, ist + 3);

        } else {

            esp = get_rsp_from_tss(env, dpl);

        }

        esp &= ~0xfLL; 

        ss = 0;

        new_stack = 1;

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

        

        if (env->eflags & VM_MASK) {

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

        }

        new_stack = 0;

        if (ist != 0) {

            esp = get_rsp_from_tss(env, ist + 3);

        } else {

            esp = env->regs[R_ESP];

        }

        esp &= ~0xfLL; 

        dpl = cpl;

    } else {

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

        new_stack = 0; 

        esp = 0; 

    }



    PUSHQ(esp, env->segs[R_SS].selector);

    PUSHQ(esp, env->regs[R_ESP]);

    PUSHQ(esp, cpu_compute_eflags(env));

    PUSHQ(esp, env->segs[R_CS].selector);

    PUSHQ(esp, old_eip);

    if (has_error_code) {

        PUSHQ(esp, error_code);

    }



    

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

        env->eflags &= ~IF_MASK;

    }

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



    if (new_stack) {

        ss = 0 | dpl;

        cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);

    }

    env->regs[R_ESP] = esp;



    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, target_ulong VAR_4, int VAR_5)

{

    SegmentCache *dt;

    target_ulong ptr;

    int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10;

    int VAR_11, VAR_12;

    uint32_t e1, e2, e3, ss;

    target_ulong old_eip, esp, offset;



    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 * 16 + 15 > dt->limit) {

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

    }

    ptr = dt->base + VAR_1 * 16;

    e1 = cpu_ldl_kernel(VAR_0, ptr);

    e2 = cpu_ldl_kernel(VAR_0, ptr + 4);

    e3 = cpu_ldl_kernel(VAR_0, ptr + 8);

    

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

    switch (VAR_6) {

    case 14: 

    case 15: 

        break;

    default:

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

        break;

    }

    VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3;

    VAR_9 = VAR_0->hflags & HF_CPL_MASK;

    

    if (VAR_2 && VAR_7 < VAR_9) {

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

    }

    

    if (!(e2 & DESC_P_MASK)) {

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

    }

    VAR_8 = e1 >> 16;

    offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    VAR_10 = e2 & 7;

    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_9) {

        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_L_MASK) || (e2 & DESC_B_MASK)) {

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

    }

    if ((!(e2 & DESC_C_MASK) && VAR_7 < VAR_9) || VAR_10 != 0) {

        

        if (VAR_10 != 0) {

            esp = get_rsp_from_tss(VAR_0, VAR_10 + 3);

        } else {

            esp = get_rsp_from_tss(VAR_0, VAR_7);

        }

        esp &= ~0xfLL; 

        ss = 0;

        VAR_12 = 1;

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

        

        if (VAR_0->eflags & VM_MASK) {

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

        }

        VAR_12 = 0;

        if (VAR_10 != 0) {

            esp = get_rsp_from_tss(VAR_0, VAR_10 + 3);

        } else {

            esp = VAR_0->regs[R_ESP];

        }

        esp &= ~0xfLL; 

        VAR_7 = VAR_9;

    } else {

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

        VAR_12 = 0; 

        esp = 0; 

    }



    PUSHQ(esp, VAR_0->segs[R_SS].VAR_8);

    PUSHQ(esp, VAR_0->regs[R_ESP]);

    PUSHQ(esp, cpu_compute_eflags(VAR_0));

    PUSHQ(esp, VAR_0->segs[R_CS].VAR_8);

    PUSHQ(esp, old_eip);

    if (VAR_11) {

        PUSHQ(esp, VAR_3);

    }



    

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

        VAR_0->eflags &= ~IF_MASK;

    }

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



    if (VAR_12) {

        ss = 0 | VAR_7;

        cpu_x86_load_seg_cache(VAR_0, R_SS, ss, 0, 0, 0);

    }

    VAR_0->regs[R_ESP] = esp;



    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, target_ulong VAR_4, int VAR_5)
{ SegmentCache *dt; target_ulong ptr; int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10; int VAR_11, VAR_12; uint32_t e1, e2, e3, ss; target_ulong old_eip, esp, offset; 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 * 16 + 15 > dt->limit) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 16 + 2); } ptr = dt->base + VAR_1 * 16; e1 = cpu_ldl_kernel(VAR_0, ptr); e2 = cpu_ldl_kernel(VAR_0, ptr + 4); e3 = cpu_ldl_kernel(VAR_0, ptr + 8); VAR_6 = (e2 >> DESC_TYPE_SHIFT) & 0x1f; switch (VAR_6) { case 14:
case 15:
break; default:
raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 16 + 2); break; } VAR_7 = (e2 >> DESC_DPL_SHIFT) & 3; VAR_9 = VAR_0->hflags & HF_CPL_MASK; if (VAR_2 && VAR_7 < VAR_9) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_1 * 16 + 2); } if (!(e2 & DESC_P_MASK)) { raise_exception_err(VAR_0, EXCP0B_NOSEG, VAR_1 * 16 + 2); } VAR_8 = e1 >> 16; offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff); VAR_10 = e2 & 7; 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_9) { 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_L_MASK) || (e2 & DESC_B_MASK)) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } if ((!(e2 & DESC_C_MASK) && VAR_7 < VAR_9) || VAR_10 != 0) { if (VAR_10 != 0) { esp = get_rsp_from_tss(VAR_0, VAR_10 + 3); } else { esp = get_rsp_from_tss(VAR_0, VAR_7); } esp &= ~0xfLL; ss = 0; VAR_12 = 1; } else if ((e2 & DESC_C_MASK) || VAR_7 == VAR_9) { if (VAR_0->eflags & VM_MASK) { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); } VAR_12 = 0; if (VAR_10 != 0) { esp = get_rsp_from_tss(VAR_0, VAR_10 + 3); } else { esp = VAR_0->regs[R_ESP]; } esp &= ~0xfLL; VAR_7 = VAR_9; } else { raise_exception_err(VAR_0, EXCP0D_GPF, VAR_8 & 0xfffc); VAR_12 = 0; esp = 0; } PUSHQ(esp, VAR_0->segs[R_SS].VAR_8); PUSHQ(esp, VAR_0->regs[R_ESP]); PUSHQ(esp, cpu_compute_eflags(VAR_0)); PUSHQ(esp, VAR_0->segs[R_CS].VAR_8); PUSHQ(esp, old_eip); if (VAR_11) { PUSHQ(esp, VAR_3); } if ((VAR_6 & 1) == 0) { VAR_0->eflags &= ~IF_MASK; } VAR_0->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); if (VAR_12) { ss = 0 | VAR_7; cpu_x86_load_seg_cache(VAR_0, R_SS, ss, 0, 0, 0); } VAR_0->regs[R_ESP] = esp; 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; }