void do_interrupt (CPUState *env)

{

#if defined (CONFIG_USER_ONLY)

    env->exception_index |= 0x100;

#else

    uint32_t msr;

    int excp = env->exception_index;



    msr = _load_msr(env);

#if defined (DEBUG_EXCEPTIONS)

    if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) 

    {

        if (loglevel > 0) {

            fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",

                    env->nip, excp << 8, env->error_code);

    }

	if (loglevel > 0)

	    cpu_ppc_dump_state(env, logfile, 0);

    }

#endif

    /* Generate informations in save/restore registers */

    switch (excp) {

    case EXCP_OFCALL:

#if defined (USE_OPEN_FIRMWARE)

        env->gpr[3] = OF_client_entry((void *)env->gpr[3]);

#endif

        return;

    case EXCP_RTASCALL:

#if defined (USE_OPEN_FIRMWARE)

        printf("RTAS call !\n");

        env->gpr[3] = RTAS_entry((void *)env->gpr[3]);

        printf("RTAS call done\n");

#endif

        return;

    case EXCP_NONE:

        /* Do nothing */

#if defined (DEBUG_EXCEPTIONS)

        printf("%s: escape EXCP_NONE\n", __func__);

#endif

        return;

    case EXCP_RESET:

        if (msr_ip)

            excp += 0xFFC00;

        goto store_next;

    case EXCP_MACHINE_CHECK:

        if (msr_me == 0) {

            cpu_abort(env, "Machine check exception while not allowed\n");

        }

        msr_me = 0;

        break;

    case EXCP_DSI:

        /* Store exception cause */

        /* data location address has been stored

         * when the fault has been detected

     */

	msr &= ~0xFFFF0000;

	env->spr[DSISR] = 0;

	if (env->error_code &  EXCP_DSI_TRANSLATE)

	    env->spr[DSISR] |= 0x40000000;

	else if (env->error_code & EXCP_DSI_PROT)

	    env->spr[DSISR] |= 0x08000000;

	else if (env->error_code & EXCP_DSI_NOTSUP) {

	    env->spr[DSISR] |= 0x80000000;

	    if (env->error_code & EXCP_DSI_DIRECT)

		env->spr[DSISR] |= 0x04000000;

	}

	if (env->error_code & EXCP_DSI_STORE)

	    env->spr[DSISR] |= 0x02000000;

	if ((env->error_code & 0xF) == EXCP_DSI_DABR)

	    env->spr[DSISR] |= 0x00400000;

	if (env->error_code & EXCP_DSI_ECXW)

	    env->spr[DSISR] |= 0x00100000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",

		    env->spr[DSISR], env->spr[DAR]);

	} else {

	    printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",

		   env->spr[DSISR], env->spr[DAR], env->nip);

	}

#endif

        goto store_next;

    case EXCP_ISI:

        /* Store exception cause */

	msr &= ~0xFFFF0000;

        if (env->error_code == EXCP_ISI_TRANSLATE)

            msr |= 0x40000000;

        else if (env->error_code == EXCP_ISI_NOEXEC ||

		 env->error_code == EXCP_ISI_GUARD ||

		 env->error_code == EXCP_ISI_DIRECT)

            msr |= 0x10000000;

        else

            msr |= 0x08000000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",

		    msr, env->nip);

	} else {

	    printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",

		   msr, env->nip, env->spr[V_TBL]);

	}

#endif

        goto store_next;

    case EXCP_EXTERNAL:

        if (msr_ee == 0) {

#if defined (DEBUG_EXCEPTIONS)

            if (loglevel > 0) {

                fprintf(logfile, "Skipping hardware interrupt\n");

    }

#endif

            /* Requeue it */

            do_raise_exception(EXCP_EXTERNAL);

            return;

            }

        goto store_next;

    case EXCP_ALIGN:

        /* Store exception cause */

        /* Get rS/rD and rA from faulting opcode */

        env->spr[DSISR] |=

            (ldl_code((void *)(env->nip - 4)) & 0x03FF0000) >> 16;

        /* data location address has been stored

         * when the fault has been detected

         */

        goto store_current;

    case EXCP_PROGRAM:

        msr &= ~0xFFFF0000;

        switch (env->error_code & ~0xF) {

        case EXCP_FP:

            if (msr_fe0 == 0 && msr_fe1 == 0) {

#if defined (DEBUG_EXCEPTIONS)

                printf("Ignore floating point exception\n");

#endif

                return;

        }

            msr |= 0x00100000;

            /* Set FX */

            env->fpscr[7] |= 0x8;

            /* Finally, update FEX */

            if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &

                ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))

                env->fpscr[7] |= 0x4;

        break;

        case EXCP_INVAL:

            //	    printf("Invalid instruction at 0x%08x\n", env->nip);

            msr |= 0x00080000;

        break;

        case EXCP_PRIV:

            msr |= 0x00040000;

        break;

        case EXCP_TRAP:

            msr |= 0x00020000;

            break;

        default:

            /* Should never occur */

        break;

    }

        msr |= 0x00010000;

        goto store_current;

    case EXCP_NO_FP:

        goto store_current;

    case EXCP_DECR:

        if (msr_ee == 0) {

            /* Requeue it */

            do_raise_exception(EXCP_DECR);

            return;

        }

        goto store_next;

    case EXCP_SYSCALL:

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr) {

	    if (loglevel) {

		fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",

			env->gpr[0], env->gpr[3], env->gpr[4],

			env->gpr[5], env->gpr[6]);

	    } else {

		printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",

		       env->gpr[0], env->nip, env->gpr[3], env->gpr[4],

		       env->gpr[5], env->gpr[6]);

	    }

	}

#endif

        goto store_next;

    case EXCP_TRACE:

        goto store_next;

    case EXCP_FP_ASSIST:

        goto store_next;

    case EXCP_MTMSR:

        /* Nothing to do */

        return;

    case EXCP_BRANCH:

        /* Nothing to do */

        return;

    case EXCP_RFI:

        /* Restore user-mode state */

	tb_flush(env);

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr == 1)

	    printf("Return from exception => 0x%08x\n", (uint32_t)env->nip);

#endif

        return;

    store_current:

        /* SRR0 is set to current instruction */

        env->spr[SRR0] = (uint32_t)env->nip - 4;

        break;

    store_next:

        /* SRR0 is set to next instruction */

        env->spr[SRR0] = (uint32_t)env->nip;

        break;

    }

    env->spr[SRR1] = msr;

    /* reload MSR with correct bits */

    msr_pow = 0;

    msr_ee = 0;

    msr_pr = 0;

    msr_fp = 0;

    msr_fe0 = 0;

    msr_se = 0;

    msr_be = 0;

    msr_fe1 = 0;

    msr_ir = 0;

    msr_dr = 0;

    msr_ri = 0;

    msr_le = msr_ile;

    /* Jump to handler */

    env->nip = excp << 8;

    env->exception_index = EXCP_NONE;

    /* Invalidate all TLB as we may have changed translation mode */

    tlb_flush(env, 1);

    /* ensure that no TB jump will be modified as

       the program flow was changed */

#ifdef __sparc__

    tmp_T0 = 0;

#else

    T0 = 0;

#endif

#endif

    env->exception_index = -1;

}

void do_interrupt (CPUState *env)

{

#if defined (CONFIG_USER_ONLY)

    env->exception_index |= 0x100;

#else

    uint32_t msr;

    int excp = env->exception_index;



    msr = _load_msr(env);

#if defined (DEBUG_EXCEPTIONS)

    if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) 

    {

        if (loglevel > 0) {

            fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",

                    env->nip, excp << 8, env->error_code);

    }

	if (loglevel > 0)

	    cpu_ppc_dump_state(env, logfile, 0);

    }

#endif

    

    switch (excp) {

    case EXCP_OFCALL:

#if defined (USE_OPEN_FIRMWARE)

        env->gpr[3] = OF_client_entry((void *)env->gpr[3]);

#endif

        return;

    case EXCP_RTASCALL:

#if defined (USE_OPEN_FIRMWARE)

        printf("RTAS call !\n");

        env->gpr[3] = RTAS_entry((void *)env->gpr[3]);

        printf("RTAS call done\n");

#endif

        return;

    case EXCP_NONE:

        

#if defined (DEBUG_EXCEPTIONS)

        printf("%s: escape EXCP_NONE\n", __func__);

#endif

        return;

    case EXCP_RESET:

        if (msr_ip)

            excp += 0xFFC00;

        goto store_next;

    case EXCP_MACHINE_CHECK:

        if (msr_me == 0) {

            cpu_abort(env, "Machine check exception while not allowed\n");

        }

        msr_me = 0;

        break;

    case EXCP_DSI:

        

        





	msr &= ~0xFFFF0000;

	env->spr[DSISR] = 0;

	if (env->error_code &  EXCP_DSI_TRANSLATE)

	    env->spr[DSISR] |= 0x40000000;

	else if (env->error_code & EXCP_DSI_PROT)

	    env->spr[DSISR] |= 0x08000000;

	else if (env->error_code & EXCP_DSI_NOTSUP) {

	    env->spr[DSISR] |= 0x80000000;

	    if (env->error_code & EXCP_DSI_DIRECT)

		env->spr[DSISR] |= 0x04000000;

	}

	if (env->error_code & EXCP_DSI_STORE)

	    env->spr[DSISR] |= 0x02000000;

	if ((env->error_code & 0xF) == EXCP_DSI_DABR)

	    env->spr[DSISR] |= 0x00400000;

	if (env->error_code & EXCP_DSI_ECXW)

	    env->spr[DSISR] |= 0x00100000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",

		    env->spr[DSISR], env->spr[DAR]);

	} else {

	    printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",

		   env->spr[DSISR], env->spr[DAR], env->nip);

	}

#endif

        goto store_next;

    case EXCP_ISI:

        

	msr &= ~0xFFFF0000;

        if (env->error_code == EXCP_ISI_TRANSLATE)

            msr |= 0x40000000;

        else if (env->error_code == EXCP_ISI_NOEXEC ||

		 env->error_code == EXCP_ISI_GUARD ||

		 env->error_code == EXCP_ISI_DIRECT)

            msr |= 0x10000000;

        else

            msr |= 0x08000000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",

		    msr, env->nip);

	} else {

	    printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",

		   msr, env->nip, env->spr[V_TBL]);

	}

#endif

        goto store_next;

    case EXCP_EXTERNAL:

        if (msr_ee == 0) {

#if defined (DEBUG_EXCEPTIONS)

            if (loglevel > 0) {

                fprintf(logfile, "Skipping hardware interrupt\n");

    }

#endif

            

            do_raise_exception(EXCP_EXTERNAL);

            return;

            }

        goto store_next;

    case EXCP_ALIGN:

        

        

        env->spr[DSISR] |=

            (ldl_code((void *)(env->nip - 4)) & 0x03FF0000) >> 16;

        





        goto store_current;

    case EXCP_PROGRAM:

        msr &= ~0xFFFF0000;

        switch (env->error_code & ~0xF) {

        case EXCP_FP:

            if (msr_fe0 == 0 && msr_fe1 == 0) {

#if defined (DEBUG_EXCEPTIONS)

                printf("Ignore floating point exception\n");

#endif

                return;

        }

            msr |= 0x00100000;

            

            env->fpscr[7] |= 0x8;

            

            if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &

                ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))

                env->fpscr[7] |= 0x4;

        break;

        case EXCP_INVAL:

            

            msr |= 0x00080000;

        break;

        case EXCP_PRIV:

            msr |= 0x00040000;

        break;

        case EXCP_TRAP:

            msr |= 0x00020000;

            break;

        default:

            

        break;

    }

        msr |= 0x00010000;

        goto store_current;

    case EXCP_NO_FP:

        goto store_current;

    case EXCP_DECR:

        if (msr_ee == 0) {

            

            do_raise_exception(EXCP_DECR);

            return;

        }

        goto store_next;

    case EXCP_SYSCALL:

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr) {

	    if (loglevel) {

		fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",

			env->gpr[0], env->gpr[3], env->gpr[4],

			env->gpr[5], env->gpr[6]);

	    } else {

		printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",

		       env->gpr[0], env->nip, env->gpr[3], env->gpr[4],

		       env->gpr[5], env->gpr[6]);

	    }

	}

#endif

        goto store_next;

    case EXCP_TRACE:

        goto store_next;

    case EXCP_FP_ASSIST:

        goto store_next;

    case EXCP_MTMSR:

        

        return;

    case EXCP_BRANCH:

        

        return;

    case EXCP_RFI:

        

	tb_flush(env);

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr == 1)

	    printf("Return from exception => 0x%08x\n", (uint32_t)env->nip);

#endif

        return;

    store_current:

        

        env->spr[SRR0] = (uint32_t)env->nip - 4;

        break;

    store_next:

        

        env->spr[SRR0] = (uint32_t)env->nip;

        break;

    }

    env->spr[SRR1] = msr;

    

    msr_pow = 0;

    msr_ee = 0;

    msr_pr = 0;

    msr_fp = 0;

    msr_fe0 = 0;

    msr_se = 0;

    msr_be = 0;

    msr_fe1 = 0;

    msr_ir = 0;

    msr_dr = 0;

    msr_ri = 0;

    msr_le = msr_ile;

    

    env->nip = excp << 8;

    env->exception_index = EXCP_NONE;

    

    tlb_flush(env, 1);

    



#ifdef __sparc__

    tmp_T0 = 0;

#else

    T0 = 0;

#endif

#endif

    env->exception_index = -1;

}

void FUNC_0 (CPUState *VAR_0)

{

#if defined (CONFIG_USER_ONLY)

    VAR_0->exception_index |= 0x100;

#else

    uint32_t msr;

    int VAR_1 = VAR_0->exception_index;



    msr = _load_msr(VAR_0);

#if defined (DEBUG_EXCEPTIONS)

    if ((VAR_1 == EXCP_PROGRAM || VAR_1 == EXCP_DSI) && msr_pr == 1) 

    {

        if (loglevel > 0) {

            fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",

                    VAR_0->nip, VAR_1 << 8, VAR_0->error_code);

    }

	if (loglevel > 0)

	    cpu_ppc_dump_state(VAR_0, logfile, 0);

    }

#endif

    

    switch (VAR_1) {

    case EXCP_OFCALL:

#if defined (USE_OPEN_FIRMWARE)

        VAR_0->gpr[3] = OF_client_entry((void *)VAR_0->gpr[3]);

#endif

        return;

    case EXCP_RTASCALL:

#if defined (USE_OPEN_FIRMWARE)

        printf("RTAS call !\n");

        VAR_0->gpr[3] = RTAS_entry((void *)VAR_0->gpr[3]);

        printf("RTAS call done\n");

#endif

        return;

    case EXCP_NONE:

        

#if defined (DEBUG_EXCEPTIONS)

        printf("%s: escape EXCP_NONE\n", __func__);

#endif

        return;

    case EXCP_RESET:

        if (msr_ip)

            VAR_1 += 0xFFC00;

        goto store_next;

    case EXCP_MACHINE_CHECK:

        if (msr_me == 0) {

            cpu_abort(VAR_0, "Machine check exception while not allowed\n");

        }

        msr_me = 0;

        break;

    case EXCP_DSI:

        

        





	msr &= ~0xFFFF0000;

	VAR_0->spr[DSISR] = 0;

	if (VAR_0->error_code &  EXCP_DSI_TRANSLATE)

	    VAR_0->spr[DSISR] |= 0x40000000;

	else if (VAR_0->error_code & EXCP_DSI_PROT)

	    VAR_0->spr[DSISR] |= 0x08000000;

	else if (VAR_0->error_code & EXCP_DSI_NOTSUP) {

	    VAR_0->spr[DSISR] |= 0x80000000;

	    if (VAR_0->error_code & EXCP_DSI_DIRECT)

		VAR_0->spr[DSISR] |= 0x04000000;

	}

	if (VAR_0->error_code & EXCP_DSI_STORE)

	    VAR_0->spr[DSISR] |= 0x02000000;

	if ((VAR_0->error_code & 0xF) == EXCP_DSI_DABR)

	    VAR_0->spr[DSISR] |= 0x00400000;

	if (VAR_0->error_code & EXCP_DSI_ECXW)

	    VAR_0->spr[DSISR] |= 0x00100000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",

		    VAR_0->spr[DSISR], VAR_0->spr[DAR]);

	} else {

	    printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",

		   VAR_0->spr[DSISR], VAR_0->spr[DAR], VAR_0->nip);

	}

#endif

        goto store_next;

    case EXCP_ISI:

        

	msr &= ~0xFFFF0000;

        if (VAR_0->error_code == EXCP_ISI_TRANSLATE)

            msr |= 0x40000000;

        else if (VAR_0->error_code == EXCP_ISI_NOEXEC ||

		 VAR_0->error_code == EXCP_ISI_GUARD ||

		 VAR_0->error_code == EXCP_ISI_DIRECT)

            msr |= 0x10000000;

        else

            msr |= 0x08000000;

#if defined (DEBUG_EXCEPTIONS)

	if (loglevel) {

	    fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",

		    msr, VAR_0->nip);

	} else {

	    printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",

		   msr, VAR_0->nip, VAR_0->spr[V_TBL]);

	}

#endif

        goto store_next;

    case EXCP_EXTERNAL:

        if (msr_ee == 0) {

#if defined (DEBUG_EXCEPTIONS)

            if (loglevel > 0) {

                fprintf(logfile, "Skipping hardware interrupt\n");

    }

#endif

            

            do_raise_exception(EXCP_EXTERNAL);

            return;

            }

        goto store_next;

    case EXCP_ALIGN:

        

        

        VAR_0->spr[DSISR] |=

            (ldl_code((void *)(VAR_0->nip - 4)) & 0x03FF0000) >> 16;

        





        goto store_current;

    case EXCP_PROGRAM:

        msr &= ~0xFFFF0000;

        switch (VAR_0->error_code & ~0xF) {

        case EXCP_FP:

            if (msr_fe0 == 0 && msr_fe1 == 0) {

#if defined (DEBUG_EXCEPTIONS)

                printf("Ignore floating point exception\n");

#endif

                return;

        }

            msr |= 0x00100000;

            

            VAR_0->fpscr[7] |= 0x8;

            

            if ((((VAR_0->fpscr[7] & 0x3) << 3) | (VAR_0->fpscr[6] >> 1)) &

                ((VAR_0->fpscr[1] << 1) | (VAR_0->fpscr[0] >> 3)))

                VAR_0->fpscr[7] |= 0x4;

        break;

        case EXCP_INVAL:

            

            msr |= 0x00080000;

        break;

        case EXCP_PRIV:

            msr |= 0x00040000;

        break;

        case EXCP_TRAP:

            msr |= 0x00020000;

            break;

        default:

            

        break;

    }

        msr |= 0x00010000;

        goto store_current;

    case EXCP_NO_FP:

        goto store_current;

    case EXCP_DECR:

        if (msr_ee == 0) {

            

            do_raise_exception(EXCP_DECR);

            return;

        }

        goto store_next;

    case EXCP_SYSCALL:

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr) {

	    if (loglevel) {

		fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",

			VAR_0->gpr[0], VAR_0->gpr[3], VAR_0->gpr[4],

			VAR_0->gpr[5], VAR_0->gpr[6]);

	    } else {

		printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",

		       VAR_0->gpr[0], VAR_0->nip, VAR_0->gpr[3], VAR_0->gpr[4],

		       VAR_0->gpr[5], VAR_0->gpr[6]);

	    }

	}

#endif

        goto store_next;

    case EXCP_TRACE:

        goto store_next;

    case EXCP_FP_ASSIST:

        goto store_next;

    case EXCP_MTMSR:

        

        return;

    case EXCP_BRANCH:

        

        return;

    case EXCP_RFI:

        

	tb_flush(VAR_0);

#if defined (DEBUG_EXCEPTIONS)

	if (msr_pr == 1)

	    printf("Return from exception => 0x%08x\n", (uint32_t)VAR_0->nip);

#endif

        return;

    store_current:

        

        VAR_0->spr[SRR0] = (uint32_t)VAR_0->nip - 4;

        break;

    store_next:

        

        VAR_0->spr[SRR0] = (uint32_t)VAR_0->nip;

        break;

    }

    VAR_0->spr[SRR1] = msr;

    

    msr_pow = 0;

    msr_ee = 0;

    msr_pr = 0;

    msr_fp = 0;

    msr_fe0 = 0;

    msr_se = 0;

    msr_be = 0;

    msr_fe1 = 0;

    msr_ir = 0;

    msr_dr = 0;

    msr_ri = 0;

    msr_le = msr_ile;

    

    VAR_0->nip = VAR_1 << 8;

    VAR_0->exception_index = EXCP_NONE;

    

    tlb_flush(VAR_0, 1);

    



#ifdef __sparc__

    tmp_T0 = 0;

#else

    T0 = 0;

#endif

#endif

    VAR_0->exception_index = -1;

}

void FUNC_0 (CPUState *VAR_0)
{ #if defined (CONFIG_USER_ONLY)
VAR_0->exception_index |= 0x100; #else
uint32_t msr; int VAR_1 = VAR_0->exception_index; msr = _load_msr(VAR_0); #if defined (DEBUG_EXCEPTIONS)
if ((VAR_1 == EXCP_PROGRAM || VAR_1 == EXCP_DSI) && msr_pr == 1)
{ if (loglevel > 0) { fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",
VAR_0->nip, VAR_1 << 8, VAR_0->error_code); } if (loglevel > 0)
cpu_ppc_dump_state(VAR_0, logfile, 0); } #endif
switch (VAR_1) { case EXCP_OFCALL:
#if defined (USE_OPEN_FIRMWARE)
VAR_0->gpr[3] = OF_client_entry((void *)VAR_0->gpr[3]); #endif
return; case EXCP_RTASCALL:
#if defined (USE_OPEN_FIRMWARE)
printf("RTAS call !\n"); VAR_0->gpr[3] = RTAS_entry((void *)VAR_0->gpr[3]); printf("RTAS call done\n"); #endif
return; case EXCP_NONE:
#if defined (DEBUG_EXCEPTIONS)
printf("%s: escape EXCP_NONE\n", __func__); #endif
return; case EXCP_RESET:
if (msr_ip)
VAR_1 += 0xFFC00; goto store_next; case EXCP_MACHINE_CHECK:
if (msr_me == 0) { cpu_abort(VAR_0, "Machine check exception while not allowed\n"); } msr_me = 0; break; case EXCP_DSI:
msr &= ~0xFFFF0000; VAR_0->spr[DSISR] = 0; if (VAR_0->error_code &  EXCP_DSI_TRANSLATE)
VAR_0->spr[DSISR] |= 0x40000000; else if (VAR_0->error_code & EXCP_DSI_PROT)
VAR_0->spr[DSISR] |= 0x08000000; else if (VAR_0->error_code & EXCP_DSI_NOTSUP) { VAR_0->spr[DSISR] |= 0x80000000; if (VAR_0->error_code & EXCP_DSI_DIRECT)
VAR_0->spr[DSISR] |= 0x04000000; } if (VAR_0->error_code & EXCP_DSI_STORE)
VAR_0->spr[DSISR] |= 0x02000000; if ((VAR_0->error_code & 0xF) == EXCP_DSI_DABR)
VAR_0->spr[DSISR] |= 0x00400000; if (VAR_0->error_code & EXCP_DSI_ECXW)
VAR_0->spr[DSISR] |= 0x00100000; #if defined (DEBUG_EXCEPTIONS)
if (loglevel) { fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
VAR_0->spr[DSISR], VAR_0->spr[DAR]); } else { printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",
VAR_0->spr[DSISR], VAR_0->spr[DAR], VAR_0->nip); } #endif
goto store_next; case EXCP_ISI:
msr &= ~0xFFFF0000; if (VAR_0->error_code == EXCP_ISI_TRANSLATE)
msr |= 0x40000000; else if (VAR_0->error_code == EXCP_ISI_NOEXEC ||
VAR_0->error_code == EXCP_ISI_GUARD ||
VAR_0->error_code == EXCP_ISI_DIRECT)
msr |= 0x10000000; else
msr |= 0x08000000; #if defined (DEBUG_EXCEPTIONS)
if (loglevel) { fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",
msr, VAR_0->nip); } else { printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",
msr, VAR_0->nip, VAR_0->spr[V_TBL]); } #endif
goto store_next; case EXCP_EXTERNAL:
if (msr_ee == 0) { #if defined (DEBUG_EXCEPTIONS)
if (loglevel > 0) { fprintf(logfile, "Skipping hardware interrupt\n"); } #endif
do_raise_exception(EXCP_EXTERNAL); return; } goto store_next; case EXCP_ALIGN:
VAR_0->spr[DSISR] |=
(ldl_code((void *)(VAR_0->nip - 4)) & 0x03FF0000) >> 16; goto store_current; case EXCP_PROGRAM:
msr &= ~0xFFFF0000; switch (VAR_0->error_code & ~0xF) { case EXCP_FP:
if (msr_fe0 == 0 && msr_fe1 == 0) { #if defined (DEBUG_EXCEPTIONS)
printf("Ignore floating point exception\n"); #endif
return; } msr |= 0x00100000; VAR_0->fpscr[7] |= 0x8; if ((((VAR_0->fpscr[7] & 0x3) << 3) | (VAR_0->fpscr[6] >> 1)) &
((VAR_0->fpscr[1] << 1) | (VAR_0->fpscr[0] >> 3)))
VAR_0->fpscr[7] |= 0x4; break; case EXCP_INVAL:
msr |= 0x00080000; break; case EXCP_PRIV:
msr |= 0x00040000; break; case EXCP_TRAP:
msr |= 0x00020000; break; default:
break; } msr |= 0x00010000; goto store_current; case EXCP_NO_FP:
goto store_current; case EXCP_DECR:
if (msr_ee == 0) { do_raise_exception(EXCP_DECR); return; } goto store_next; case EXCP_SYSCALL:
#if defined (DEBUG_EXCEPTIONS)
if (msr_pr) { if (loglevel) { fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
VAR_0->gpr[0], VAR_0->gpr[3], VAR_0->gpr[4],
VAR_0->gpr[5], VAR_0->gpr[6]); } else { printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
VAR_0->gpr[0], VAR_0->nip, VAR_0->gpr[3], VAR_0->gpr[4],
VAR_0->gpr[5], VAR_0->gpr[6]); } } #endif
goto store_next; case EXCP_TRACE:
goto store_next; case EXCP_FP_ASSIST:
goto store_next; case EXCP_MTMSR:
return; case EXCP_BRANCH:
return; case EXCP_RFI:
tb_flush(VAR_0); #if defined (DEBUG_EXCEPTIONS)
if (msr_pr == 1)
printf("Return from exception => 0x%08x\n", (uint32_t)VAR_0->nip); #endif
return; store_current:
VAR_0->spr[SRR0] = (uint32_t)VAR_0->nip - 4; break; store_next:
VAR_0->spr[SRR0] = (uint32_t)VAR_0->nip; break; } VAR_0->spr[SRR1] = msr; msr_pow = 0; msr_ee = 0; msr_pr = 0; msr_fp = 0; msr_fe0 = 0; msr_se = 0; msr_be = 0; msr_fe1 = 0; msr_ir = 0; msr_dr = 0; msr_ri = 0; msr_le = msr_ile; VAR_0->nip = VAR_1 << 8; VAR_0->exception_index = EXCP_NONE; tlb_flush(VAR_0, 1); #ifdef __sparc__
tmp_T0 = 0; #else
T0 = 0; #endif
#endif
VAR_0->exception_index = -1; }