Clean up program exceptions.

This commit is contained in:
Maxim Poliakovski 2020-11-30 20:59:36 +01:00
parent acfa09af65
commit 6c6247b94f
4 changed files with 37 additions and 29 deletions

View File

@ -215,6 +215,14 @@ enum class Except_Type {
EXC_TRACE = 13
};
/** Programm Exception subclasses. */
enum Exc_Cause : uint32_t {
FPU_OFF = 1 << (31 - 11),
ILLEGAL_OP = 1 << (31 - 12),
NOT_ALLOWED = 1 << (31 - 13),
TRAP = 1 << (31 - 14),
};
// extern bool bb_end;
extern BB_end_kind bb_kind;

View File

@ -120,11 +120,11 @@ PPCOpcode SubOpcode63Grabber[1024] = { ppc_fpu_off };
/** Exception helpers. */
[[noreturn]] void ppc_illegalop() {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00080000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
[[noreturn]] void ppc_fpu_off() {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00100000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_OFF);
}
/** Opcode decoding functions. */

View File

@ -775,7 +775,7 @@ void dppc_interpreter::ppc_lfsu() {
ppc_store_dfpresult(true);
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -795,7 +795,7 @@ void dppc_interpreter::ppc_lfsux() {
ppc_store_dfpresult(true);
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -817,7 +817,7 @@ void dppc_interpreter::ppc_lfdu() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -837,7 +837,7 @@ void dppc_interpreter::ppc_lfdux() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -857,7 +857,7 @@ void dppc_interpreter::ppc_stfsu() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -875,7 +875,7 @@ void dppc_interpreter::ppc_stfsux() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -895,7 +895,7 @@ void dppc_interpreter::ppc_stfdu() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -913,7 +913,7 @@ void dppc_interpreter::ppc_stfdux() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}

View File

@ -811,7 +811,7 @@ void dppc_interpreter::ppc_mfmsr() {
supervisor_inst_num++;
#endif
if (ppc_state.msr & 0x4000) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
}
reg_d = (ppc_cur_instruction >> 21) & 31;
ppc_state.gpr[reg_d] = ppc_state.msr;
@ -822,7 +822,7 @@ void dppc_interpreter::ppc_mtmsr() {
supervisor_inst_num++;
#endif
if (ppc_state.msr & 0x4000) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
}
reg_s = (ppc_cur_instruction >> 21) & 31;
ppc_state.msr = ppc_state.gpr[reg_s];
@ -1293,7 +1293,7 @@ void dppc_interpreter::ppc_tw() {
(((int32_t)ppc_state.gpr[reg_a] == (int32_t)ppc_state.gpr[reg_b]) & (ppc_to & 0x04)) ||
((ppc_state.gpr[reg_a] < ppc_state.gpr[reg_b]) & (ppc_to & 0x02)) ||
((ppc_state.gpr[reg_a] > ppc_state.gpr[reg_b]) & (ppc_to & 0x01))) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::TRAP);
}
}
@ -1306,7 +1306,7 @@ void dppc_interpreter::ppc_twi() {
(((int32_t)ppc_state.gpr[reg_a] == simm) && (ppc_to & 0x04)) ||
((ppc_state.gpr[reg_a] < (uint32_t)simm) && (ppc_to & 0x02)) ||
((ppc_state.gpr[reg_a] > (uint32_t)simm) && (ppc_to & 0x01))) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::TRAP);
}
}
@ -1390,7 +1390,7 @@ void dppc_interpreter::ppc_stbu() {
mem_write_byte(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1401,7 +1401,7 @@ void dppc_interpreter::ppc_stbux() {
mem_write_byte(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1420,7 +1420,7 @@ void dppc_interpreter::ppc_sthu() {
mem_write_word(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1431,7 +1431,7 @@ void dppc_interpreter::ppc_sthux() {
mem_write_word(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1485,7 +1485,7 @@ void dppc_interpreter::ppc_stwu() {
mem_write_dword(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1496,7 +1496,7 @@ void dppc_interpreter::ppc_stwux() {
mem_write_dword(ppc_effective_address, ppc_result_d);
ppc_state.gpr[reg_a] = ppc_effective_address;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1541,7 +1541,7 @@ void dppc_interpreter::ppc_lbzu() {
ppc_store_result_regd();
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1561,7 +1561,7 @@ void dppc_interpreter::ppc_lbzux() {
ppc_store_result_regd();
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1584,7 +1584,7 @@ void dppc_interpreter::ppc_lhzu() {
ppc_store_result_regd();
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1604,7 +1604,7 @@ void dppc_interpreter::ppc_lhzux() {
ppc_store_result_regd();
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1636,7 +1636,7 @@ void dppc_interpreter::ppc_lhau() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1698,7 +1698,7 @@ void dppc_interpreter::ppc_lwzu() {
ppc_result_a = ppc_effective_address;
ppc_store_result_rega();
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
@ -1714,7 +1714,7 @@ void dppc_interpreter::ppc_lwzux() {
if ((reg_a != reg_d) || reg_a != 0) {
ppc_effective_address = ppc_result_a + ppc_result_b;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
ppc_result_d = mem_grab_dword(ppc_effective_address);
ppc_result_a = ppc_effective_address;
@ -1790,10 +1790,10 @@ void dppc_interpreter::ppc_lswx() {
ppc_grab_regsdab();
// Invalid instruction forms
if ((ppc_result_d == 0) && (ppc_result_a == 0)) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
if ((ppc_result_d == ppc_result_a) || (ppc_result_a == ppc_result_b)) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
grab_inb = ppc_state.spr[SPR::XER] & 127;