Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cpu/ppc/ppcexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ PPCOpcode* ppc_opcode_grabber = OpcodeGrabberNoFPU;
/** Exception helpers. */

void ppc_illegalop(uint32_t opcode) {
// Zero values are used as sentinels in the TNT ROM and are thus somewhat
// common, don't log them.
if (opcode) {
PPCDisasmContext ctx;
ctx.instr_code = opcode;
ctx.instr_addr = 0;
ctx.simplified = false;
auto op_name = disassemble_single(&ctx);
LOG_F(WARNING, "Illegal opcode exception raised for 0x%08x (decoded as %s). The PC was 0x%08x.", opcode, op_name.c_str(), ppc_state.pc);
}

ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}

Expand Down
16 changes: 8 additions & 8 deletions cpu/ppc/ppcfpopcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ void dppc_interpreter::ppc_lfsu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1046,7 +1046,7 @@ void dppc_interpreter::ppc_lfsux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
return;
}
}
Expand All @@ -1070,7 +1070,7 @@ void dppc_interpreter::ppc_lfdu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1091,7 +1091,7 @@ void dppc_interpreter::ppc_lfdux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1114,7 +1114,7 @@ void dppc_interpreter::ppc_stfsu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1135,7 +1135,7 @@ void dppc_interpreter::ppc_stfsux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1156,7 +1156,7 @@ void dppc_interpreter::ppc_stfdu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1175,7 +1175,7 @@ void dppc_interpreter::ppc_stfdux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down
2 changes: 1 addition & 1 deletion cpu/ppc/ppcmmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ static void mpc601_bat_update(uint32_t bat_reg)

static void mpc601_dbat_update(uint32_t /*bat_reg*/)
{
// ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
// ppc_illegalop(opcode);
}

static void ppc_ibat_update(uint32_t bat_reg)
Expand Down
44 changes: 24 additions & 20 deletions cpu/ppc/ppcopcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,14 +1002,14 @@ void dppc_interpreter::ppc_mfspr(uint32_t opcode) {
switch (ref_spr) {
case SPR::MQ:
if (!(is_601 || include_601)) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
return;
}
ppc_state.gpr[reg_d] = ppc_state.spr[ref_spr];
break;
case SPR::RTCL_U:
if (!is_601) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
return;
}
calc_rtcl_value();
Expand All @@ -1019,7 +1019,7 @@ void dppc_interpreter::ppc_mfspr(uint32_t opcode) {
break;
case SPR::RTCU_U:
if (!is_601) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
return;
}
calc_rtcl_value();
Expand All @@ -1029,7 +1029,7 @@ void dppc_interpreter::ppc_mfspr(uint32_t opcode) {
break;
case SPR::DEC_U:
if (!is_601) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
return;
}
// fallthrough
Expand Down Expand Up @@ -1093,13 +1093,13 @@ void dppc_interpreter::ppc_mtspr(uint32_t opcode) {
if (is_601 || include_601)
ppc_state.spr[ref_spr] = val;
else
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
break;
case SPR::RTCL_U:
case SPR::RTCU_U:
case SPR::DEC_U:
if (!is_601) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
break;
case SPR::XER:
Expand Down Expand Up @@ -1214,7 +1214,7 @@ void dppc_interpreter::ppc_mftb(uint32_t opcode) {
ppc_state.spr[TBL_S] = uint32_t(tbr_value);
break;
default:
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down Expand Up @@ -1700,14 +1700,16 @@ void dppc_interpreter::ppc_stu(uint32_t opcode) {
#endif
ppc_grab_regssa(opcode);

if (reg_a != 0) {
// MPC601 permits RA=0 for POWER compatibility and suppresses the update.
if (reg_a != 0 || is_601) {
uint32_t ea = int32_t(int16_t(opcode));
ea += ppc_result_a;
ea += reg_a ? ppc_result_a : 0;
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
ppc_state.gpr[reg_a] = ea;
if (reg_a != 0)
ppc_state.gpr[reg_a] = ea;
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}

}
Expand All @@ -1723,13 +1725,15 @@ void dppc_interpreter::ppc_stux(uint32_t opcode) {
#endif
ppc_grab_regssab(opcode);

if (reg_a != 0) {
uint32_t ea = ppc_result_a + ppc_result_b;
// MPC601 permits RA=0 for POWER compatibility and suppresses the update.
if (reg_a != 0 || is_601) {
uint32_t ea = (reg_a ? ppc_result_a : 0) + ppc_result_b;
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
ppc_state.gpr[reg_a] = ea;
if (reg_a != 0)
ppc_state.gpr[reg_a] = ea;
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down Expand Up @@ -1821,7 +1825,7 @@ void dppc_interpreter::ppc_lzu(uint32_t opcode) {
ppc_result_a = ea;
ppc_store_iresult_reg(reg_a, ppc_result_a);
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down Expand Up @@ -1857,7 +1861,7 @@ void dppc_interpreter::ppc_lzux(uint32_t opcode) {
ppc_result_a = ea;
ppc_store_iresult_reg(reg_a, ppc_result_a);
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down Expand Up @@ -1889,7 +1893,7 @@ void dppc_interpreter::ppc_lhau(uint32_t opcode) {
ppc_result_a = ea;
ppc_store_iresult_reg(reg_a, ppc_result_a);
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand All @@ -1906,7 +1910,7 @@ void dppc_interpreter::ppc_lhaux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
}

Expand Down Expand Up @@ -2014,7 +2018,7 @@ void dppc_interpreter::ppc_lswx(uint32_t opcode) {
if ((reg_d == 0 && reg_a == 0) || (reg_d == reg_a) || (reg_d == reg_b)) {
// UNTESTED! Does invalid form really cause exception?
// G4 doesn't do exception
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_illegalop(opcode);
}
*/

Expand Down
Loading