From f511005461e60afe0d4e240df813b5394344313b Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:29:59 -0700 Subject: [PATCH] More attempted fixes --- benchmark/bench1.cpp | 23 +++---- cpu/ppc/ppcemu.h | 3 + cpu/ppc/ppcexec.cpp | 141 +++++++++++++++++++++++++++----------- cpu/ppc/test/ppctests.cpp | 10 ++- 4 files changed, 117 insertions(+), 60 deletions(-) diff --git a/benchmark/bench1.cpp b/benchmark/bench1.cpp index 6be340e..de65f1b 100644 --- a/benchmark/bench1.cpp +++ b/benchmark/bench1.cpp @@ -34,19 +34,16 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) { #endif uint32_t cs_code[] = { - 0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002, - 0x41E2001C, 0xA0030004, 0x3884FFFE, 0x38630002, - 0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003, - 0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114, - 0x4200FFF8, 0x5486E13F, 0x41820050, 0x80030004, - 0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C, - 0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028, - 0x80030004, 0x7CA54114, 0x80C30008, 0x7CA50114, - 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914, - 0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, - 0xA0030004, 0x38630002, 0x7CA50114, 0x70800001, - 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114, - 0x7C650194, 0x4E800020}; + 0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002, 0x41E2001C, 0xA0030004, + 0x3884FFFE, 0x38630002, 0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003, + 0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114, 0x4200FFF8, 0x5486E13F, + 0x41820050, 0x80030004, 0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C, + 0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028, 0x80030004, 0x7CA54114, + 0x80C30008, 0x7CA50114, 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914, + 0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, 0xA0030004, 0x38630002, + 0x7CA50114, 0x70800001, 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114, + 0x7C650194, 0x4E800020 +}; constexpr uint32_t test_size = 0x8000; // 0x7FFFFFFC is the max constexpr uint32_t test_samples = 200; diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 177c0c6..a70d889 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -76,6 +76,8 @@ typedef struct struct_ppc_instr { uint8_t arg4; int32_t addr; int32_t mask; + uint8_t main_op; + uint16_t sub_op; union { int32_t i_simm; @@ -424,6 +426,7 @@ void ppc_assert_int(); void ppc_release_int(); void decode_instr(); +void exec_instr(); void initialize_ppc_opcode_tables(bool include_601); extern double fp_return_double(uint32_t reg); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index ae23cca..7a4c967 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -56,7 +56,6 @@ using namespace dppc_interpreter; MemCtrlBase* mem_ctrl_instance = 0; -void (*ref_instr)(); SetPRS ppc_state; SetInstr instr; @@ -233,80 +232,63 @@ void ppc_release_int() { /** Opcode decoding functions. */ static void ppc_opcode16() { - ref_instr = SubOpcode16Grabber[ppc_cur_instruction & 3]; + instr.sub_op = ppc_cur_instruction & 0x3; ppc_grab_branch(ppc_cur_instruction); } static void ppc_opcode18() { - ref_instr = SubOpcode18Grabber[ppc_cur_instruction & 3]; + instr.sub_op = ppc_cur_instruction & 0x3; ppc_grab_branch(ppc_cur_instruction); } template void ppc_opcode19() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FF; + instr.sub_op = ppc_cur_instruction & 0x7FF; - switch (subop_grab) { + switch (instr.sub_op) { case 0: - ref_instr = ppc_mcrf; ppc_grab_regs_crfds(ppc_cur_instruction); break; case 32: - ref_instr = ppc_bclr; ppc_grab_branch_cond(ppc_cur_instruction); break; case 33: - ref_instr = ppc_bclr; ppc_grab_branch_cond(ppc_cur_instruction); break; case 66: - ref_instr = ppc_crnor; ppc_grab_dab(ppc_cur_instruction); break; case 100: - ref_instr = ppc_rfi; break; case 258: - ref_instr = ppc_crandc; ppc_grab_dab(ppc_cur_instruction); break; case 300: - ref_instr = ppc_isync; break; case 386: - ref_instr = ppc_crxor; ppc_grab_dab(ppc_cur_instruction); break; case 450: - ref_instr = ppc_crnand; ppc_grab_dab(ppc_cur_instruction); break; case 514: - ref_instr = ppc_crand; ppc_grab_dab(ppc_cur_instruction); break; case 578: - ref_instr = ppc_creqv; ppc_grab_dab(ppc_cur_instruction); break; case 834: - ref_instr = ppc_crorc; ppc_grab_dab(ppc_cur_instruction); break; case 898: - ref_instr = ppc_cror; ppc_grab_dab(ppc_cur_instruction); break; case 1056: - ref_instr = ppc_bcctr; ppc_grab_branch_cond(ppc_cur_instruction); break; case 1057: - ref_instr = ppc_bcctr; ppc_grab_branch_cond(ppc_cur_instruction); break; - default: - ppc_illegalop(); } } @@ -314,10 +296,9 @@ template void ppc_opcode19(); template void ppc_opcode19(); static void ppc_opcode31() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; - ref_instr = SubOpcode31Grabber[subop_grab]; + instr.sub_op = ppc_cur_instruction & 0x7FFUL; - switch ((subop_grab >> 1)) { + switch ((instr.sub_op >> 1)) { case 0: case 32: ppc_grab_crfd_regsab(ppc_cur_instruction); @@ -344,16 +325,14 @@ static void ppc_opcode31() { } static void ppc_opcode59() { - uint16_t subop_grab = ppc_cur_instruction & 0x3FUL; - ref_instr = SubOpcode59Grabber[subop_grab]; + instr.sub_op = ppc_cur_instruction & 0x3FUL; ppc_grab_regsfpdabc(ppc_cur_instruction); } static void ppc_opcode63() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; - ref_instr = SubOpcode63Grabber[subop_grab]; + instr.sub_op = ppc_cur_instruction & 0x7FFUL; - switch ((subop_grab >> 1)) { + switch ((instr.sub_op >> 1)) { case 0: case 32: ppc_grab_regsfpsab(ppc_cur_instruction); @@ -376,10 +355,8 @@ static void ppc_opcode63() { /* Dispatch using main opcode */ static void ppc_main_opcode() { - uint32_t main_op = (ppc_cur_instruction >> 26) & 0x3F; - ref_instr = OpcodeGrabber[main_op]; - switch (main_op) { + switch (instr.main_op) { case 3: ppc_grab_twi(ppc_cur_instruction); break; @@ -409,8 +386,8 @@ static void ppc_main_opcode() { } void decode_instr() { - uint32_t main_op = (ppc_cur_instruction >> 26) & 0x3F; - switch (main_op) { + instr.main_op = (ppc_cur_instruction >> 26) & 0x3F; + switch (instr.main_op) { case 16: ppc_opcode16(); break; @@ -445,6 +422,87 @@ void decode_instr() { #endif } +template +inline static void exec_op19() { + switch (instr.sub_op) { + case 0: + ppc_mcrf(); + break; + case 32: + ppc_bclr(); + break; + case 33: + ppc_bclr(); + break; + case 66: + ppc_crnor(); + break; + case 100: + ppc_rfi(); + break; + case 258: + ppc_crandc(); + break; + case 300: + ppc_isync(); + break; + case 386: + ppc_crxor(); + break; + case 450: + ppc_crnand(); + break; + case 514: + ppc_crand(); + break; + case 578: + ppc_creqv(); + break; + case 834: + ppc_crorc(); + break; + case 898: + ppc_cror(); + break; + case 1056: + ppc_bcctr(); + break; + case 1057: + ppc_bcctr(); + break; + default: + ppc_illegalop(); + } +} + +void exec_instr() { + switch (instr.main_op) { + case 16: + SubOpcode16Grabber[instr.sub_op](); + break; + case 18: + SubOpcode18Grabber[instr.sub_op](); + break; + case 19: + if (is_601) + exec_op19(); + else + exec_op19(); + break; + case 31: + SubOpcode31Grabber[instr.sub_op](); + break; + case 59: + SubOpcode59Grabber[instr.sub_op](); + break; + case 63: + SubOpcode63Grabber[instr.sub_op](); + break; + default: + OpcodeGrabber[instr.main_op](); + } +} + static long long cpu_now_ns() { #ifdef __APPLE__ return ConvertHostTimeToNanos2(mach_absolute_time()); @@ -504,7 +562,7 @@ static void ppc_exec_inner() // interpret execution block while (power_on && ppc_state.pc < eb_end) { - ref_instr(); + exec_instr(); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -560,7 +618,8 @@ void ppc_exec_single() } mmu_translate_imem(ppc_state.pc); - ref_instr(); + decode_instr(); + exec_instr(); g_icycles++; process_events(); @@ -596,7 +655,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) // interpret execution block while (power_on && ppc_state.pc < eb_end) { - ref_instr(); + exec_instr(); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -630,7 +689,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) } // outer interpreter loop -void ppc_exec_until(volatile uint32_t goal_addr) +void ppc_exec_until(uint32_t goal_addr) { if (setjmp(exc_env)) { // process low-level exceptions @@ -668,7 +727,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) // interpret execution block while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size) && (ppc_state.pc < eb_end)) { - ref_instr(); + exec_instr(); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -699,7 +758,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) } // outer interpreter loop -void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size) +void ppc_exec_dbg(uint32_t start_addr, uint32_t size) { if (setjmp(exc_env)) { // process low-level exceptions diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp index 1f28c6b..c4efe4a 100644 --- a/cpu/ppc/test/ppctests.cpp +++ b/cpu/ppc/test/ppctests.cpp @@ -33,8 +33,6 @@ along with this program. If not, see . using namespace std; -void (*ref_instr)(); - int ntested; // number of tested instructions int nfailed; // number of failed instructions @@ -50,7 +48,7 @@ static void xer_ov_test(string mnem, uint32_t opcode) { ppc_state.spr[SPR::XER] = 0xFFFFFFFF; ppc_cur_instruction = opcode; decode_instr(); - ref_instr(); + exec_instr(); if (ppc_state.spr[SPR::XER] & 0x40000000UL) { cout << "Invalid " << mnem << " emulation! XER[OV] should not be set." << endl; nfailed++; @@ -155,9 +153,9 @@ static void read_test_data() { ppc_state.cr = 0; ppc_cur_instruction = opcode; - + decode_instr(); - ref_instr(); + exec_instr(); ntested++; @@ -302,7 +300,7 @@ static void read_test_float_data() { ppc_cur_instruction = opcode; decode_instr(); - ref_instr(); + exec_instr(); ntested++;