Line 137... |
Line 137... |
case EXCEPT_IPF:
|
case EXCEPT_IPF:
|
#if DYNAMIC_EXECUTION
|
#if DYNAMIC_EXECUTION
|
/* In immu_translate except_handle is called with except_handle(..., virtaddr) */
|
/* In immu_translate except_handle is called with except_handle(..., virtaddr) */
|
/* Add the immu miss delay to the cycle counter */
|
/* Add the immu miss delay to the cycle counter */
|
if(!immu_ex_from_insn) {
|
if(!immu_ex_from_insn) {
|
mtspr(SPR_EPCR_BASE, get_pc() - (cpu_state.delay_insn ? 4 : 0));
|
cpu_state.sprs[SPR_EPCR_BASE] = get_pc() - (cpu_state.delay_insn ? 4 : 0);
|
} else
|
} else
|
/* This exception came from an l.mtspr instruction in which case the pc
|
/* This exception came from an l.mtspr instruction in which case the pc
|
* points to the l.mtspr instruction when in acutal fact, it is the next
|
* points to the l.mtspr instruction when in acutal fact, it is the next
|
* instruction that would have faulted/missed. ea is used instead of
|
* instruction that would have faulted/missed. ea is used instead of
|
* cpu_state.pc + 4 because in the event that the l.mtspr instruction is
|
* cpu_state.pc + 4 because in the event that the l.mtspr instruction is
|
* in the delay slot of a page local jump the fault must happen on the
|
* in the delay slot of a page local jump the fault must happen on the
|
* instruction that was jumped to. This is handled in recheck_immu. */
|
* instruction that was jumped to. This is handled in recheck_immu. */
|
mtspr(SPR_EPCR_BASE, ea);
|
cpu_state.sprs[SPR_EPCR_BASE] = ea;
|
run_sched_out_of_line(immu_ex_from_insn);
|
run_sched_out_of_line(immu_ex_from_insn);
|
/* Save the registers that are in the temporaries */
|
/* Save the registers that are in the temporaries */
|
if(!cpu_state.ts_current)
|
if(!cpu_state.ts_current)
|
upd_reg_from_t(cpu_state.pc, !immu_ex_from_insn);
|
upd_reg_from_t(cpu_state.pc, !immu_ex_from_insn);
|
immu_ex_from_insn = 0;
|
immu_ex_from_insn = 0;
|
Line 175... |
Line 175... |
upd_reg_from_t(cpu_state.pc - 4, 0);
|
upd_reg_from_t(cpu_state.pc - 4, 0);
|
else
|
else
|
upd_reg_from_t(cpu_state.pc, 0);
|
upd_reg_from_t(cpu_state.pc, 0);
|
}
|
}
|
#endif
|
#endif
|
mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
|
cpu_state.sprs[SPR_EPCR_BASE] = cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
|
break;
|
break;
|
/* EPCR is loaded with address of next not-yet-executed instruction */
|
/* EPCR is loaded with address of next not-yet-executed instruction */
|
case EXCEPT_SYSCALL:
|
case EXCEPT_SYSCALL:
|
mtspr(SPR_EPCR_BASE, (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0));
|
cpu_state.sprs[SPR_EPCR_BASE] = (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0);
|
break;
|
break;
|
/* These exceptions happen AFTER (or before) an instruction has been
|
/* These exceptions happen AFTER (or before) an instruction has been
|
* simulated, therefore the pc already points to the *next* instruction */
|
* simulated, therefore the pc already points to the *next* instruction */
|
case EXCEPT_TICK:
|
case EXCEPT_TICK:
|
case EXCEPT_INT:
|
case EXCEPT_INT:
|
mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
|
cpu_state.sprs[SPR_EPCR_BASE] = cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
|
#if !(DYNAMIC_EXECUTION)
|
#if !(DYNAMIC_EXECUTION)
|
/* If we don't update the pc now, then it will only happen *after* the next
|
/* If we don't update the pc now, then it will only happen *after* the next
|
* instruction (There would be serious problems if the next instruction just
|
* instruction (There would be serious problems if the next instruction just
|
* happens to be a branch), when it should happen NOW. */
|
* happens to be a branch), when it should happen NOW. */
|
cpu_state.pc = pcnext;
|
cpu_state.pc = pcnext;
|