diff --git a/README.md b/README.md index 2903ea1000..b182360375 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ emulation. To build the tests, use the following terminal commands: ``` mkdir build cd build -cmake -DCMAKE_BUILD_TYPE=Release -DPPC_BUILD_PPC_TESTS=True .. +cmake -DCMAKE_BUILD_TYPE=Release -DDPPC_BUILD_PPC_TESTS=True .. make testppc ``` diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index 41ad84d385..95aff08fde 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -35,9 +35,9 @@ static inline uint32_t power_rot_mask(unsigned rot_mb, unsigned rot_me) { } template -void dppc_interpreter::power_abs() { +void dppc_interpreter::power_abs(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_regsda(ppc_cur_instruction); + ppc_grab_regsda(opcode); if (ppc_result_a == 0x80000000) { ppc_result_d = ppc_result_a; if (ov) @@ -54,14 +54,14 @@ void dppc_interpreter::power_abs() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::power_abs(); -template void dppc_interpreter::power_abs(); -template void dppc_interpreter::power_abs(); -template void dppc_interpreter::power_abs(); +template void dppc_interpreter::power_abs(uint32_t opcode); +template void dppc_interpreter::power_abs(uint32_t opcode); +template void dppc_interpreter::power_abs(uint32_t opcode); +template void dppc_interpreter::power_abs(uint32_t opcode); -void dppc_interpreter::power_clcs() { +void dppc_interpreter::power_clcs(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_da(ppc_cur_instruction); + ppc_grab_da(opcode); switch (reg_a) { case 12: //instruction cache line size case 13: //data cache line size @@ -84,9 +84,9 @@ void dppc_interpreter::power_clcs() { } template -void dppc_interpreter::power_div() { +void dppc_interpreter::power_div(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); int64_t dividend = (uint64_t(ppc_result_a) << 32) | ppc_state.spr[SPR::MQ]; int32_t divisor = ppc_result_b; @@ -123,16 +123,16 @@ void dppc_interpreter::power_div() { ppc_state.spr[SPR::MQ] = remainder; } -template void dppc_interpreter::power_div(); -template void dppc_interpreter::power_div(); -template void dppc_interpreter::power_div(); -template void dppc_interpreter::power_div(); +template void dppc_interpreter::power_div(uint32_t opcode); +template void dppc_interpreter::power_div(uint32_t opcode); +template void dppc_interpreter::power_div(uint32_t opcode); +template void dppc_interpreter::power_div(uint32_t opcode); template -void dppc_interpreter::power_divs() { +void dppc_interpreter::power_divs(uint32_t opcode) { uint32_t ppc_result_d; int32_t remainder; - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); if (!ppc_result_b) { // handle the "anything / 0" case ppc_result_d = -1; @@ -157,14 +157,14 @@ void dppc_interpreter::power_divs() { ppc_state.spr[SPR::MQ] = remainder; } -template void dppc_interpreter::power_divs(); -template void dppc_interpreter::power_divs(); -template void dppc_interpreter::power_divs(); -template void dppc_interpreter::power_divs(); +template void dppc_interpreter::power_divs(uint32_t opcode); +template void dppc_interpreter::power_divs(uint32_t opcode); +template void dppc_interpreter::power_divs(uint32_t opcode); +template void dppc_interpreter::power_divs(uint32_t opcode); template -void dppc_interpreter::power_doz() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::power_doz(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t ppc_result_d = (int32_t(ppc_result_a) < int32_t(ppc_result_b)) ? ppc_result_b - ppc_result_a : 0; @@ -181,14 +181,14 @@ void dppc_interpreter::power_doz() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::power_doz(); -template void dppc_interpreter::power_doz(); -template void dppc_interpreter::power_doz(); -template void dppc_interpreter::power_doz(); +template void dppc_interpreter::power_doz(uint32_t opcode); +template void dppc_interpreter::power_doz(uint32_t opcode); +template void dppc_interpreter::power_doz(uint32_t opcode); +template void dppc_interpreter::power_doz(uint32_t opcode); -void dppc_interpreter::power_dozi() { +void dppc_interpreter::power_dozi(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_regsdasimm(ppc_cur_instruction); + ppc_grab_regsdasimm(opcode); if (((int32_t)ppc_result_a) > simm) { ppc_result_d = 0; } else { @@ -198,8 +198,8 @@ void dppc_interpreter::power_dozi() { } template -void dppc_interpreter::power_lscbx() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::power_lscbx(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); uint32_t bytes_to_load = (ppc_state.spr[SPR::XER] & 0x7F); @@ -212,7 +212,7 @@ void dppc_interpreter::power_lscbx() { uint8_t shift_amount = 24; while (bytes_remaining > 0) { - uint8_t return_value = mmu_read_vmem(ea); + uint8_t return_value = mmu_read_vmem(opcode, ea); ppc_result_d |= return_value << shift_amount; if (!shift_amount) { @@ -248,12 +248,12 @@ void dppc_interpreter::power_lscbx() { } } -template void dppc_interpreter::power_lscbx(); -template void dppc_interpreter::power_lscbx(); +template void dppc_interpreter::power_lscbx(uint32_t opcode); +template void dppc_interpreter::power_lscbx(uint32_t opcode); template -void dppc_interpreter::power_maskg() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_maskg(uint32_t opcode) { + ppc_grab_regssab(opcode); uint32_t mask_start = ppc_result_d & 0x1F; uint32_t mask_end = ppc_result_b & 0x1F; uint32_t insert_mask = 0; @@ -276,12 +276,12 @@ void dppc_interpreter::power_maskg() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_maskg(); -template void dppc_interpreter::power_maskg(); +template void dppc_interpreter::power_maskg(uint32_t opcode); +template void dppc_interpreter::power_maskg(uint32_t opcode); template -void dppc_interpreter::power_maskir() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_maskir(uint32_t opcode) { + ppc_grab_regssab(opcode); ppc_result_a = (ppc_result_a & ~ppc_result_b) | (ppc_result_d & ppc_result_b); if (rec) @@ -290,12 +290,12 @@ void dppc_interpreter::power_maskir() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_maskir(); -template void dppc_interpreter::power_maskir(); +template void dppc_interpreter::power_maskir(uint32_t opcode); +template void dppc_interpreter::power_maskir(uint32_t opcode); template -void dppc_interpreter::power_mul() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::power_mul(uint32_t opcode) { + ppc_grab_regsdab(opcode); int64_t product = int64_t(int32_t(ppc_result_a)) * int32_t(ppc_result_b); uint32_t ppc_result_d = uint32_t(uint64_t(product) >> 32); ppc_state.spr[SPR::MQ] = uint32_t(product); @@ -312,14 +312,14 @@ void dppc_interpreter::power_mul() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::power_mul(); -template void dppc_interpreter::power_mul(); -template void dppc_interpreter::power_mul(); -template void dppc_interpreter::power_mul(); +template void dppc_interpreter::power_mul(uint32_t opcode); +template void dppc_interpreter::power_mul(uint32_t opcode); +template void dppc_interpreter::power_mul(uint32_t opcode); +template void dppc_interpreter::power_mul(uint32_t opcode); template -void dppc_interpreter::power_nabs() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::power_nabs(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t ppc_result_d = (int32_t(ppc_result_a) < 0) ? ppc_result_a : -ppc_result_a; if (ov) @@ -330,15 +330,15 @@ void dppc_interpreter::power_nabs() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::power_nabs(); -template void dppc_interpreter::power_nabs(); -template void dppc_interpreter::power_nabs(); -template void dppc_interpreter::power_nabs(); +template void dppc_interpreter::power_nabs(uint32_t opcode); +template void dppc_interpreter::power_nabs(uint32_t opcode); +template void dppc_interpreter::power_nabs(uint32_t opcode); +template void dppc_interpreter::power_nabs(uint32_t opcode); -void dppc_interpreter::power_rlmi() { - ppc_grab_regssab(ppc_cur_instruction); - unsigned rot_mb = (ppc_cur_instruction >> 6) & 0x1F; - unsigned rot_me = (ppc_cur_instruction >> 1) & 0x1F; +void dppc_interpreter::power_rlmi(uint32_t opcode) { + ppc_grab_regssab(opcode); + unsigned rot_mb = (opcode >> 6) & 0x1F; + unsigned rot_me = (opcode >> 1) & 0x1F; unsigned rot_sh = ppc_result_b & 0x1F; uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); @@ -346,15 +346,15 @@ void dppc_interpreter::power_rlmi() { ppc_result_a = ((r & mask) | (ppc_result_a & ~mask)); - if ((ppc_cur_instruction & 0x01) == 1) + if ((opcode & 0x01) == 1) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } template -void dppc_interpreter::power_rrib() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_rrib(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; if (int32_t(ppc_result_d) < 0) { @@ -369,12 +369,12 @@ void dppc_interpreter::power_rrib() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_rrib(); -template void dppc_interpreter::power_rrib(); +template void dppc_interpreter::power_rrib(uint32_t opcode); +template void dppc_interpreter::power_rrib(uint32_t opcode); template -void dppc_interpreter::power_sle() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sle(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; ppc_result_a = ppc_result_d << rot_sh; @@ -388,12 +388,12 @@ void dppc_interpreter::power_sle() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sle(); -template void dppc_interpreter::power_sle(); +template void dppc_interpreter::power_sle(uint32_t opcode); +template void dppc_interpreter::power_sle(uint32_t opcode); template -void dppc_interpreter::power_sleq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sleq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); uint32_t mask = power_rot_mask(0, 31 - rot_sh); @@ -407,12 +407,12 @@ void dppc_interpreter::power_sleq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sleq(); -template void dppc_interpreter::power_sleq(); +template void dppc_interpreter::power_sleq(uint32_t opcode); +template void dppc_interpreter::power_sleq(uint32_t opcode); template -void dppc_interpreter::power_sliq() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::power_sliq(uint32_t opcode) { + ppc_grab_regssash(opcode); ppc_result_a = ppc_result_d << rot_sh; ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); @@ -423,12 +423,12 @@ void dppc_interpreter::power_sliq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sliq(); -template void dppc_interpreter::power_sliq(); +template void dppc_interpreter::power_sliq(uint32_t opcode); +template void dppc_interpreter::power_sliq(uint32_t opcode); template -void dppc_interpreter::power_slliq() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::power_slliq(uint32_t opcode) { + ppc_grab_regssash(opcode); uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); uint32_t mask = power_rot_mask(0, 31 - rot_sh); @@ -441,12 +441,12 @@ void dppc_interpreter::power_slliq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_slliq(); -template void dppc_interpreter::power_slliq(); +template void dppc_interpreter::power_slliq(uint32_t opcode); +template void dppc_interpreter::power_slliq(uint32_t opcode); template -void dppc_interpreter::power_sllq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sllq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; if (ppc_result_b & 0x20) { @@ -461,12 +461,12 @@ void dppc_interpreter::power_sllq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sllq(); -template void dppc_interpreter::power_sllq(); +template void dppc_interpreter::power_sllq(uint32_t opcode); +template void dppc_interpreter::power_sllq(uint32_t opcode); template -void dppc_interpreter::power_slq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_slq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; if (ppc_result_b & 0x20) { @@ -482,12 +482,12 @@ void dppc_interpreter::power_slq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_slq(); -template void dppc_interpreter::power_slq(); +template void dppc_interpreter::power_slq(uint32_t opcode); +template void dppc_interpreter::power_slq(uint32_t opcode); template -void dppc_interpreter::power_sraiq() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::power_sraiq(uint32_t opcode) { + ppc_grab_regssash(opcode); uint32_t mask = (1 << rot_sh) - 1; ppc_result_a = (int32_t)ppc_result_d >> rot_sh; ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); @@ -504,12 +504,12 @@ void dppc_interpreter::power_sraiq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sraiq(); -template void dppc_interpreter::power_sraiq(); +template void dppc_interpreter::power_sraiq(uint32_t opcode); +template void dppc_interpreter::power_sraiq(uint32_t opcode); template -void dppc_interpreter::power_sraq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sraq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; uint32_t mask = (ppc_result_b & 0x20) ? -1 : (1 << rot_sh) - 1; ppc_result_a = (int32_t)ppc_result_d >> ((ppc_result_b & 0x20) ? 31 : rot_sh); @@ -529,12 +529,12 @@ void dppc_interpreter::power_sraq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sraq(); -template void dppc_interpreter::power_sraq(); +template void dppc_interpreter::power_sraq(uint32_t opcode); +template void dppc_interpreter::power_sraq(uint32_t opcode); template -void dppc_interpreter::power_sre() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sre(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; ppc_result_a = ppc_result_d >> rot_sh; @@ -547,12 +547,12 @@ void dppc_interpreter::power_sre() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sre(); -template void dppc_interpreter::power_sre(); +template void dppc_interpreter::power_sre(uint32_t opcode); +template void dppc_interpreter::power_sre(uint32_t opcode); template -void dppc_interpreter::power_srea() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_srea(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; ppc_result_a = (int32_t)ppc_result_d >> rot_sh; uint32_t r = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))); @@ -571,12 +571,12 @@ void dppc_interpreter::power_srea() { ppc_state.spr[SPR::MQ] = r; } -template void dppc_interpreter::power_srea(); -template void dppc_interpreter::power_srea(); +template void dppc_interpreter::power_srea(uint32_t opcode); +template void dppc_interpreter::power_srea(uint32_t opcode); template -void dppc_interpreter::power_sreq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_sreq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; uint32_t mask = -1U >> rot_sh; @@ -589,12 +589,12 @@ void dppc_interpreter::power_sreq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sreq(); -template void dppc_interpreter::power_sreq(); +template void dppc_interpreter::power_sreq(uint32_t opcode); +template void dppc_interpreter::power_sreq(uint32_t opcode); template -void dppc_interpreter::power_sriq() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::power_sriq(uint32_t opcode) { + ppc_grab_regssash(opcode); ppc_result_a = ppc_result_d >> rot_sh; ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); @@ -604,12 +604,12 @@ void dppc_interpreter::power_sriq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_sriq(); -template void dppc_interpreter::power_sriq(); +template void dppc_interpreter::power_sriq(uint32_t opcode); +template void dppc_interpreter::power_sriq(uint32_t opcode); template -void dppc_interpreter::power_srliq() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::power_srliq(uint32_t opcode) { + ppc_grab_regssash(opcode); uint32_t r = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); unsigned mask = power_rot_mask(rot_sh, 31); @@ -622,12 +622,12 @@ void dppc_interpreter::power_srliq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_srliq(); -template void dppc_interpreter::power_srliq(); +template void dppc_interpreter::power_srliq(uint32_t opcode); +template void dppc_interpreter::power_srliq(uint32_t opcode); template -void dppc_interpreter::power_srlq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_srlq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; uint32_t r = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); unsigned mask = power_rot_mask(rot_sh, 31); @@ -644,12 +644,12 @@ void dppc_interpreter::power_srlq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_srlq(); -template void dppc_interpreter::power_srlq(); +template void dppc_interpreter::power_srlq(uint32_t opcode); +template void dppc_interpreter::power_srlq(uint32_t opcode); template -void dppc_interpreter::power_srq() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::power_srq(uint32_t opcode) { + ppc_grab_regssab(opcode); unsigned rot_sh = ppc_result_b & 0x1F; if (ppc_result_b & 0x20) { @@ -666,5 +666,5 @@ void dppc_interpreter::power_srq() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::power_srq(); -template void dppc_interpreter::power_srq(); +template void dppc_interpreter::power_srq(uint32_t opcode); +template void dppc_interpreter::power_srq(uint32_t opcode); diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index f98e77ea18..059eeadfac 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -47,7 +47,7 @@ enum EXEC_MODE:uint32_t { enum endian_switch { big_end = 0, little_end = 1 }; -typedef void (*PPCOpcode)(void); +typedef void (*PPCOpcode)(uint32_t opcode); union FPR_storage { double dbl64_r; // double floating-point representation @@ -333,11 +333,10 @@ extern bool is_64bit; // For PowerPC G5 Emulation extern bool is_deterministic; // Important Addressing Integers -extern uint32_t ppc_cur_instruction; extern uint32_t ppc_next_instruction_address; -inline void ppc_set_cur_instruction(const uint8_t* ptr) { - ppc_cur_instruction = READ_DWORD_BE_A(ptr); +inline uint32_t ppc_read_instruction(const uint8_t* ptr) { + return READ_DWORD_BE_A(ptr); } // Profiling Stats @@ -405,24 +404,12 @@ typedef enum { extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601, uint64_t tb_freq); extern void ppc_mmu_init(); -void ppc_illegalop(); -void ppc_fpu_off(); +void ppc_illegalop(uint32_t opcode); void ppc_assert_int(); void ppc_release_int(); -//void ppc_opcode4(); -void ppc_opcode16(); -void ppc_opcode18(); -template void ppc_opcode19(); -void ppc_opcode31(); -void ppc_opcode59(); -void ppc_opcode63(); - void initialize_ppc_opcode_tables(); -extern double fp_return_double(uint32_t reg); -extern uint64_t fp_return_uint64(uint32_t reg); - void ppc_changecrf0(uint32_t set_result); void set_host_rounding_mode(uint8_t mode); void update_fpscr(uint32_t new_fpscr); @@ -430,8 +417,8 @@ void update_fpscr(uint32_t new_fpscr); /* Exception handlers. */ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits); [[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits); -void ppc_floating_point_exception(); -void ppc_alignment_exception(uint32_t ea); +void ppc_floating_point_exception(uint32_t opcode); +void ppc_alignment_exception(uint32_t opcode, uint32_t ea); // MEMORY DECLARATIONS extern MemCtrlBase* mem_ctrl_instance; @@ -442,203 +429,203 @@ extern void do_ctx_sync(void); // The functions used by the PowerPC processor namespace dppc_interpreter { -template extern void ppc_bcctr(); -template extern void ppc_bclr(); -extern void ppc_crand(); -extern void ppc_crandc(); -extern void ppc_creqv(); -extern void ppc_crnand(); -extern void ppc_crnor(); -extern void ppc_cror(); -extern void ppc_crorc(); -extern void ppc_crxor(); -extern void ppc_isync(); - -template extern void ppc_logical(); - -template extern void ppc_add(); -template extern void ppc_adde(); -template extern void ppc_addme(); -template extern void ppc_addze(); -extern void ppc_cmp(); -extern void ppc_cmpl(); -template extern void ppc_cntlzw(); -extern void ppc_dcbf(); -extern void ppc_dcbi(); -extern void ppc_dcbst(); -extern void ppc_dcbt(); -extern void ppc_dcbtst(); -extern void ppc_dcbz(); -template extern void ppc_divw(); -template extern void ppc_divwu(); -extern void ppc_eciwx(); -extern void ppc_ecowx(); -extern void ppc_eieio(); -template extern void ppc_exts(); -extern void ppc_icbi(); -extern void ppc_mftb(); -extern void ppc_lhaux(); -extern void ppc_lhax(); -extern void ppc_lhbrx(); -extern void ppc_lwarx(); -extern void ppc_lwbrx(); -template extern void ppc_lzx(); -template extern void ppc_lzux(); -extern void ppc_mcrxr(); -extern void ppc_mfcr(); -template extern void ppc_mulhwu(); -template extern void ppc_mulhw(); -template extern void ppc_mullw(); -template extern void ppc_neg(); -template extern void ppc_shift(); -template extern void ppc_sraw(); -template extern void ppc_srawi(); -template extern void ppc_stx(); -template extern void ppc_stux(); -extern void ppc_stfiwx(); -extern void ppc_sthbrx(); -extern void ppc_stwcx(); -extern void ppc_stwbrx(); -template extern void ppc_subf(); -template extern void ppc_subfe(); -template extern void ppc_subfme(); -template extern void ppc_subfze(); -extern void ppc_sync(); -extern void ppc_tlbia(); -extern void ppc_tlbie(); -extern void ppc_tlbli(); -extern void ppc_tlbld(); -extern void ppc_tlbsync(); -extern void ppc_tw(); - -extern void ppc_lswi(); -extern void ppc_lswx(); -extern void ppc_stswi(); -extern void ppc_stswx(); - -extern void ppc_mfsr(); -extern void ppc_mfsrin(); -extern void ppc_mtsr(); -extern void ppc_mtsrin(); - -extern void ppc_mcrf(); -extern void ppc_mtcrf(); -extern void ppc_mfmsr(); -extern void ppc_mfspr(); -extern void ppc_mtmsr(); -extern void ppc_mtspr(); - -template extern void ppc_mtfsb0(); -template extern void ppc_mtfsb1(); -extern void ppc_mcrfs(); -template extern void ppc_fmr(); -template extern void ppc_mffs(); -template extern void ppc_mtfsf(); -template extern void ppc_mtfsfi(); - -template extern void ppc_addi(); -template extern void ppc_addic(); -template extern void ppc_andirc(); -template extern void ppc_b(); -template extern void ppc_bc(); -extern void ppc_cmpi(); -extern void ppc_cmpli(); -template extern void ppc_lz(); -template extern void ppc_lzu(); -extern void ppc_lha(); -extern void ppc_lhau(); -extern void ppc_lmw(); -extern void ppc_mulli(); -template extern void ppc_ori(); -extern void ppc_rfi(); -extern void ppc_rlwimi(); -extern void ppc_rlwinm(); -extern void ppc_rlwnm(); -extern void ppc_sc(); -template extern void ppc_st(); -template extern void ppc_stu(); -extern void ppc_stmw(); -extern void ppc_subfic(); -extern void ppc_twi(); -template extern void ppc_xori(); - -extern void ppc_lfs(); -extern void ppc_lfsu(); -extern void ppc_lfsx(); -extern void ppc_lfsux(); -extern void ppc_lfd(); -extern void ppc_lfdu(); -extern void ppc_lfdx(); -extern void ppc_lfdux(); -extern void ppc_stfs(); -extern void ppc_stfsu(); -extern void ppc_stfsx(); -extern void ppc_stfsux(); -extern void ppc_stfd(); -extern void ppc_stfdu(); -extern void ppc_stfdx(); -extern void ppc_stfdux(); - -template extern void ppc_fadd(); -template extern void ppc_fsub(); -template extern void ppc_fmul(); -template extern void ppc_fdiv(); -template extern void ppc_fadds(); -template extern void ppc_fsubs(); -template extern void ppc_fmuls(); -template extern void ppc_fdivs(); -template extern void ppc_fmadd(); -template extern void ppc_fmsub(); -template extern void ppc_fnmadd(); -template extern void ppc_fnmsub(); -template extern void ppc_fmadds(); -template extern void ppc_fmsubs(); -template extern void ppc_fnmadds(); -template extern void ppc_fnmsubs(); -template extern void ppc_fabs(); -template extern void ppc_fnabs(); -template extern void ppc_fneg(); -template extern void ppc_fsel(); -template extern void ppc_fres(); -template extern void ppc_fsqrts(); -template extern void ppc_fsqrt(); -template extern void ppc_frsqrte(); -template extern void ppc_frsp(); -template extern void ppc_fctiw(); -template extern void ppc_fctiwz(); - -extern void ppc_fcmpo(); -extern void ppc_fcmpu(); +template extern void ppc_bcctr(uint32_t opcode); +template extern void ppc_bclr(uint32_t opcode); +extern void ppc_crand(uint32_t opcode); +extern void ppc_crandc(uint32_t opcode); +extern void ppc_creqv(uint32_t opcode); +extern void ppc_crnand(uint32_t opcode); +extern void ppc_crnor(uint32_t opcode); +extern void ppc_cror(uint32_t opcode); +extern void ppc_crorc(uint32_t opcode); +extern void ppc_crxor(uint32_t opcode); +extern void ppc_isync(uint32_t opcode); + +template extern void ppc_logical(uint32_t opcode); + +template extern void ppc_add(uint32_t opcode); +template extern void ppc_adde(uint32_t opcode); +template extern void ppc_addme(uint32_t opcode); +template extern void ppc_addze(uint32_t opcode); +extern void ppc_cmp(uint32_t opcode); +extern void ppc_cmpl(uint32_t opcode); +template extern void ppc_cntlzw(uint32_t opcode); +extern void ppc_dcbf(uint32_t opcode); +extern void ppc_dcbi(uint32_t opcode); +extern void ppc_dcbst(uint32_t opcode); +extern void ppc_dcbt(uint32_t opcode); +extern void ppc_dcbtst(uint32_t opcode); +extern void ppc_dcbz(uint32_t opcode); +template extern void ppc_divw(uint32_t opcode); +template extern void ppc_divwu(uint32_t opcode); +extern void ppc_eciwx(uint32_t opcode); +extern void ppc_ecowx(uint32_t opcode); +extern void ppc_eieio(uint32_t opcode); +template extern void ppc_exts(uint32_t opcode); +extern void ppc_icbi(uint32_t opcode); +extern void ppc_mftb(uint32_t opcode); +extern void ppc_lhaux(uint32_t opcode); +extern void ppc_lhax(uint32_t opcode); +extern void ppc_lhbrx(uint32_t opcode); +extern void ppc_lwarx(uint32_t opcode); +extern void ppc_lwbrx(uint32_t opcode); +template extern void ppc_lzx(uint32_t opcode); +template extern void ppc_lzux(uint32_t opcode); +extern void ppc_mcrxr(uint32_t opcode); +extern void ppc_mfcr(uint32_t opcode); +template extern void ppc_mulhwu(uint32_t opcode); +template extern void ppc_mulhw(uint32_t opcode); +template extern void ppc_mullw(uint32_t opcode); +template extern void ppc_neg(uint32_t opcode); +template extern void ppc_shift(uint32_t opcode); +template extern void ppc_sraw(uint32_t opcode); +template extern void ppc_srawi(uint32_t opcode); +template extern void ppc_stx(uint32_t opcode); +template extern void ppc_stux(uint32_t opcode); +extern void ppc_stfiwx(uint32_t opcode); +extern void ppc_sthbrx(uint32_t opcode); +extern void ppc_stwcx(uint32_t opcode); +extern void ppc_stwbrx(uint32_t opcode); +template extern void ppc_subf(uint32_t opcode); +template extern void ppc_subfe(uint32_t opcode); +template extern void ppc_subfme(uint32_t opcode); +template extern void ppc_subfze(uint32_t opcode); +extern void ppc_sync(uint32_t opcode); +extern void ppc_tlbia(uint32_t opcode); +extern void ppc_tlbie(uint32_t opcode); +extern void ppc_tlbli(uint32_t opcode); +extern void ppc_tlbld(uint32_t opcode); +extern void ppc_tlbsync(uint32_t opcode); +extern void ppc_tw(uint32_t opcode); + +extern void ppc_lswi(uint32_t opcode); +extern void ppc_lswx(uint32_t opcode); +extern void ppc_stswi(uint32_t opcode); +extern void ppc_stswx(uint32_t opcode); + +extern void ppc_mfsr(uint32_t opcode); +extern void ppc_mfsrin(uint32_t opcode); +extern void ppc_mtsr(uint32_t opcode); +extern void ppc_mtsrin(uint32_t opcode); + +extern void ppc_mcrf(uint32_t opcode); +extern void ppc_mtcrf(uint32_t opcode); +extern void ppc_mfmsr(uint32_t opcode); +extern void ppc_mfspr(uint32_t opcode); +extern void ppc_mtmsr(uint32_t opcode); +extern void ppc_mtspr(uint32_t opcode); + +template extern void ppc_mtfsb0(uint32_t opcode); +template extern void ppc_mtfsb1(uint32_t opcode); +extern void ppc_mcrfs(uint32_t opcode); +template extern void ppc_fmr(uint32_t opcode); +template extern void ppc_mffs(uint32_t opcode); +template extern void ppc_mtfsf(uint32_t opcode); +template extern void ppc_mtfsfi(uint32_t opcode); + +template extern void ppc_addi(uint32_t opcode); +template extern void ppc_addic(uint32_t opcode); +template extern void ppc_andirc(uint32_t opcode); +template extern void ppc_b(uint32_t opcode); +template extern void ppc_bc(uint32_t opcode); +extern void ppc_cmpi(uint32_t opcode); +extern void ppc_cmpli(uint32_t opcode); +template extern void ppc_lz(uint32_t opcode); +template extern void ppc_lzu(uint32_t opcode); +extern void ppc_lha(uint32_t opcode); +extern void ppc_lhau(uint32_t opcode); +extern void ppc_lmw(uint32_t opcode); +extern void ppc_mulli(uint32_t opcode); +template extern void ppc_ori(uint32_t opcode); +extern void ppc_rfi(uint32_t opcode); +extern void ppc_rlwimi(uint32_t opcode); +extern void ppc_rlwinm(uint32_t opcode); +extern void ppc_rlwnm(uint32_t opcode); +extern void ppc_sc(uint32_t opcode); +template extern void ppc_st(uint32_t opcode); +template extern void ppc_stu(uint32_t opcode); +extern void ppc_stmw(uint32_t opcode); +extern void ppc_subfic(uint32_t opcode); +extern void ppc_twi(uint32_t opcode); +template extern void ppc_xori(uint32_t opcode); + +extern void ppc_lfs(uint32_t opcode); +extern void ppc_lfsu(uint32_t opcode); +extern void ppc_lfsx(uint32_t opcode); +extern void ppc_lfsux(uint32_t opcode); +extern void ppc_lfd(uint32_t opcode); +extern void ppc_lfdu(uint32_t opcode); +extern void ppc_lfdx(uint32_t opcode); +extern void ppc_lfdux(uint32_t opcode); +extern void ppc_stfs(uint32_t opcode); +extern void ppc_stfsu(uint32_t opcode); +extern void ppc_stfsx(uint32_t opcode); +extern void ppc_stfsux(uint32_t opcode); +extern void ppc_stfd(uint32_t opcode); +extern void ppc_stfdu(uint32_t opcode); +extern void ppc_stfdx(uint32_t opcode); +extern void ppc_stfdux(uint32_t opcode); + +template extern void ppc_fadd(uint32_t opcode); +template extern void ppc_fsub(uint32_t opcode); +template extern void ppc_fmul(uint32_t opcode); +template extern void ppc_fdiv(uint32_t opcode); +template extern void ppc_fadds(uint32_t opcode); +template extern void ppc_fsubs(uint32_t opcode); +template extern void ppc_fmuls(uint32_t opcode); +template extern void ppc_fdivs(uint32_t opcode); +template extern void ppc_fmadd(uint32_t opcode); +template extern void ppc_fmsub(uint32_t opcode); +template extern void ppc_fnmadd(uint32_t opcode); +template extern void ppc_fnmsub(uint32_t opcode); +template extern void ppc_fmadds(uint32_t opcode); +template extern void ppc_fmsubs(uint32_t opcode); +template extern void ppc_fnmadds(uint32_t opcode); +template extern void ppc_fnmsubs(uint32_t opcode); +template extern void ppc_fabs(uint32_t opcode); +template extern void ppc_fnabs(uint32_t opcode); +template extern void ppc_fneg(uint32_t opcode); +template extern void ppc_fsel(uint32_t opcode); +template extern void ppc_fres(uint32_t opcode); +template extern void ppc_fsqrts(uint32_t opcode); +template extern void ppc_fsqrt(uint32_t opcode); +template extern void ppc_frsqrte(uint32_t opcode); +template extern void ppc_frsp(uint32_t opcode); +template extern void ppc_fctiw(uint32_t opcode); +template extern void ppc_fctiwz(uint32_t opcode); + +extern void ppc_fcmpo(uint32_t opcode); +extern void ppc_fcmpu(uint32_t opcode); // Power-specific instructions -template extern void power_abs(); -extern void power_clcs(); -template extern void power_div(); -template extern void power_divs(); -template extern void power_doz(); -extern void power_dozi(); -template extern void power_lscbx(); -template extern void power_maskg(); -template extern void power_maskir(); -template extern void power_mul(); -template extern void power_nabs(); -extern void power_rlmi(); -template extern void power_rrib(); -template extern void power_sle(); -template extern void power_sleq(); -template extern void power_sliq(); -template extern void power_slliq(); -template extern void power_sllq(); -template extern void power_slq(); -template extern void power_sraiq(); -template extern void power_sraq(); -template extern void power_sre(); -template extern void power_srea(); -template extern void power_sreq(); -template extern void power_sriq(); -template extern void power_srliq(); -template extern void power_srlq(); -template extern void power_srq(); +template extern void power_abs(uint32_t opcode); +extern void power_clcs(uint32_t opcode); +template extern void power_div(uint32_t opcode); +template extern void power_divs(uint32_t opcode); +template extern void power_doz(uint32_t opcode); +extern void power_dozi(uint32_t opcode); +template extern void power_lscbx(uint32_t opcode); +template extern void power_maskg(uint32_t opcode); +template extern void power_maskir(uint32_t opcode); +template extern void power_mul(uint32_t opcode); +template extern void power_nabs(uint32_t opcode); +extern void power_rlmi(uint32_t opcode); +template extern void power_rrib(uint32_t opcode); +template extern void power_sle(uint32_t opcode); +template extern void power_sleq(uint32_t opcode); +template extern void power_sliq(uint32_t opcode); +template extern void power_slliq(uint32_t opcode); +template extern void power_sllq(uint32_t opcode); +template extern void power_slq(uint32_t opcode); +template extern void power_sraiq(uint32_t opcode); +template extern void power_sraq(uint32_t opcode); +template extern void power_sre(uint32_t opcode); +template extern void power_srea(uint32_t opcode); +template extern void power_sreq(uint32_t opcode); +template extern void power_sriq(uint32_t opcode); +template extern void power_srliq(uint32_t opcode); +template extern void power_srlq(uint32_t opcode); +template extern void power_srq(uint32_t opcode); } // namespace dppc_interpreter // AltiVec instructions @@ -649,7 +636,7 @@ template extern void power_srq(); extern uint64_t get_virt_time_ns(void); -extern void ppc_main_opcode(void); +extern void ppc_main_opcode(uint32_t opcode); extern void ppc_exec(void); extern void ppc_exec_single(void); extern void ppc_exec_until(uint32_t goal_addr); diff --git a/cpu/ppc/ppcexceptions.cpp b/cpu/ppc/ppcexceptions.cpp index e93f9cfc2b..a5921ac416 100644 --- a/cpu/ppc/ppcexceptions.cpp +++ b/cpu/ppc/ppcexceptions.cpp @@ -196,17 +196,17 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) { throw std::invalid_argument(exc_descriptor); } -void ppc_floating_point_exception() { +void ppc_floating_point_exception(uint32_t opcode) { LOG_F(ERROR, "Floating point exception at 0x%08x for instruction 0x%08x", - ppc_state.pc, ppc_cur_instruction); + ppc_state.pc, opcode); // mmu_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_EXCEPTION); } -void ppc_alignment_exception(uint32_t ea) +void ppc_alignment_exception(uint32_t opcode, uint32_t ea) { uint32_t dsisr; - switch (ppc_cur_instruction & 0xfc000000) { + switch (opcode & 0xfc000000) { case 0x80000000: // lwz case 0x90000000: // stw case 0xa0000000: // lhz @@ -228,11 +228,11 @@ void ppc_alignment_exception(uint32_t ea) case 0xd4000000: // stfsu case 0xdc000000: // stfdu // indirect with immediate index - dsisr = ((ppc_cur_instruction >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction. - | ((ppc_cur_instruction >> 17) & 0x00003c00); // bits 18–21 - set to bits 1–4 of the instruction. + dsisr = ((opcode >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction. + | ((opcode >> 17) & 0x00003c00); // bits 18–21 - set to bits 1–4 of the instruction. break; case 0x7c000000: - switch (ppc_cur_instruction & 0xfc0007ff) { + switch (opcode & 0xfc0007ff) { case 0x7c000028: // lwarx (invalid form - bits 15-21 of DSISR are identical to those of lwz) case 0x7c0002aa: // lwax (64-bit only) case 0x7c00042a: // lswx @@ -266,12 +266,12 @@ void ppc_alignment_exception(uint32_t ea) case 0x7c00056e: // stfsux case 0x7c0005ee: // stfdux indirect_with_index: - dsisr = ((ppc_cur_instruction << 14) & 0x00018000) // bits 15–16 - set to bits 29–30 of the instruction. - | ((ppc_cur_instruction << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction. - | ((ppc_cur_instruction << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 of the instruction. + dsisr = ((opcode << 14) & 0x00018000) // bits 15–16 - set to bits 29–30 of the instruction. + | ((opcode << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction. + | ((opcode << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 of the instruction. break; case 0x7c0007ec: - if ((ppc_cur_instruction & 0xffe007ff) == 0x7c0007ec) // dcbz + if ((opcode & 0xffe007ff) == 0x7c0007ec) // dcbz goto indirect_with_index; /* fallthrough */ default: @@ -282,31 +282,31 @@ void ppc_alignment_exception(uint32_t ea) unexpected_instruction: dsisr = 0; LOG_F(ERROR, "Alignment exception from unexpected instruction 0x%08x", - ppc_cur_instruction); + opcode); } // bits 22–26 - Set to bits 6–10 (source or destination) of the instruction. // Undefined for dcbz. - dsisr |= ((ppc_cur_instruction >> 16) & 0x000003e0); + dsisr |= ((opcode >> 16) & 0x000003e0); - if ((ppc_cur_instruction & 0xfc000000) == 0xb8000000) { // lmw + if ((opcode & 0xfc000000) == 0xb8000000) { // lmw LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lmw). " - "What to set DSISR bits 27-31?", ppc_cur_instruction); - // dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31 + "What to set DSISR bits 27-31?", opcode); + // dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31 } - else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c0004aa) { // lswi + else if ((opcode & 0xfc0007ff) == 0x7c0004aa) { // lswi LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswi). " - "What to set DSISR bits 27-31?", ppc_cur_instruction); - // dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31 + "What to set DSISR bits 27-31?", opcode); + // dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31 } - else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c00042a) { // lswx + else if ((opcode & 0xfc0007ff) == 0x7c00042a) { // lswx LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswx). " - "What to set DSISR bits 27-31?", ppc_cur_instruction); - // dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31 + "What to set DSISR bits 27-31?", opcode); + // dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31 } else { // bits 27–31 - Set to bits 11–15 of the instruction (rA) - dsisr |= ((ppc_cur_instruction >> 16) & 0x0000001f); + dsisr |= ((opcode >> 16) & 0x0000001f); } ppc_state.spr[SPR::DSISR] = dsisr; diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 84d605995c..f6265bd95f 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -65,7 +65,6 @@ Po_Cause power_off_reason = po_enter_debugger; SetPRS ppc_state; -uint32_t ppc_cur_instruction; // Current instruction for the PPC uint32_t ppc_next_instruction_address; // Used for branching, setting up the NIA unsigned exec_flags; // execution control flags @@ -208,14 +207,10 @@ static PPCOpcode SubOpcode63Grabber[2048]; /** Exception helpers. */ -void ppc_illegalop() { +void ppc_illegalop(uint32_t opcode) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } -void ppc_fpu_off() { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_OFF); -} - void ppc_assert_int() { int_pin = true; if (ppc_state.msr & MSR::EE) { @@ -232,97 +227,97 @@ void ppc_release_int() { /** Opcode decoding functions. */ -void ppc_opcode16() { - SubOpcode16Grabber[ppc_cur_instruction & 3](); +static void ppc_opcode16(uint32_t opcode) { + SubOpcode16Grabber[opcode & 3](opcode); } -void ppc_opcode18() { - SubOpcode18Grabber[ppc_cur_instruction & 3](); +static void ppc_opcode18(uint32_t opcode) { + SubOpcode18Grabber[opcode & 3](opcode); } template -void ppc_opcode19() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FF; +static void ppc_opcode19(uint32_t opcode) { + uint16_t subop_grab = opcode & 0x7FF; switch (subop_grab) { case 0: - ppc_mcrf(); + ppc_mcrf(opcode); break; case 32: - ppc_bclr(); + ppc_bclr(opcode); break; case 33: - ppc_bclr(); + ppc_bclr(opcode); break; case 66: - ppc_crnor(); + ppc_crnor(opcode); break; case 100: - ppc_rfi(); + ppc_rfi(opcode); break; case 258: - ppc_crandc(); + ppc_crandc(opcode); break; case 300: - ppc_isync(); + ppc_isync(opcode); break; case 386: - ppc_crxor(); + ppc_crxor(opcode); break; case 450: - ppc_crnand(); + ppc_crnand(opcode); break; case 514: - ppc_crand(); + ppc_crand(opcode); break; case 578: - ppc_creqv(); + ppc_creqv(opcode); break; case 834: - ppc_crorc(); + ppc_crorc(opcode); break; case 898: - ppc_cror(); + ppc_cror(opcode); break; case 1056: - ppc_bcctr(); + ppc_bcctr(opcode); break; case 1057: - ppc_bcctr(); + ppc_bcctr(opcode); break; default: - ppc_illegalop(); + ppc_illegalop(opcode); } } -template void ppc_opcode19(); -template void ppc_opcode19(); +template void ppc_opcode19(uint32_t opcode); +template void ppc_opcode19(uint32_t opcode); -void ppc_opcode31() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; - SubOpcode31Grabber[subop_grab](); +static void ppc_opcode31(uint32_t opcode) { + uint16_t subop_grab = opcode & 0x7FFUL; + SubOpcode31Grabber[subop_grab](opcode); } -void ppc_opcode59() { - uint16_t subop_grab = ppc_cur_instruction & 0x3FUL; - SubOpcode59Grabber[subop_grab](); +static void ppc_opcode59(uint32_t opcode) { + uint16_t subop_grab = opcode & 0x3FUL; + SubOpcode59Grabber[subop_grab](opcode); } -void ppc_opcode63() { - uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; - SubOpcode63Grabber[subop_grab](); +static void ppc_opcode63(uint32_t opcode) { + uint16_t subop_grab = opcode & 0x7FFUL; + SubOpcode63Grabber[subop_grab](opcode); } /* Dispatch using main opcode */ -void ppc_main_opcode() +void ppc_main_opcode(uint32_t opcode) { #ifdef CPU_PROFILING num_executed_instrs++; #if defined(CPU_PROFILING_OPS) - num_opcodes[ppc_cur_instruction]++; + num_opcodes[opcode]++; #endif #endif - OpcodeGrabber[(ppc_cur_instruction >> 26) & 0x3F](); + OpcodeGrabber[(opcode >> 26) & 0x3F](opcode); } static long long cpu_now_ns() { @@ -367,6 +362,7 @@ static void ppc_exec_inner() { uint64_t max_cycles; uint32_t page_start, eb_start, eb_end; + uint32_t opcode; uint8_t* pc_real; max_cycles = 0; @@ -380,10 +376,11 @@ static void ppc_exec_inner() exec_flags = 0; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); // interpret execution block while (power_on && ppc_state.pc < eb_end) { - ppc_main_opcode(); + ppc_main_opcode(opcode); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -393,18 +390,19 @@ static void ppc_exec_inner() eb_start = ppc_next_instruction_address; if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } else { page_start = eb_start & PPC_PAGE_MASK; eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); } ppc_state.pc = eb_start; exec_flags = 0; } else { ppc_state.pc += 4; pc_real += 4; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } } } @@ -435,8 +433,9 @@ void ppc_exec_single() return; } - mmu_translate_imem(ppc_state.pc); - ppc_main_opcode(); + uint8_t* pc_real = mmu_translate_imem(ppc_state.pc); + uint32_t opcode = ppc_read_instruction(pc_real); + ppc_main_opcode(opcode); g_icycles++; process_events(); @@ -456,6 +455,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) uint64_t max_cycles; uint32_t page_start, eb_start, eb_end; uint8_t* pc_real; + uint32_t opcode; max_cycles = 0; @@ -468,10 +468,11 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) exec_flags = 0; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); // interpret execution block while (power_on && ppc_state.pc < eb_end) { - ppc_main_opcode(); + ppc_main_opcode(opcode); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -481,18 +482,19 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) eb_start = ppc_next_instruction_address; if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } else { page_start = eb_start & PPC_PAGE_MASK; eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); } ppc_state.pc = eb_start; exec_flags = 0; } else { ppc_state.pc += 4; pc_real += 4; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } if (ppc_state.pc == goal_addr) @@ -523,6 +525,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) uint64_t max_cycles; uint32_t page_start, eb_start, eb_end; uint8_t* pc_real; + uint32_t opcode; max_cycles = 0; @@ -535,11 +538,12 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) exec_flags = 0; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); // interpret execution block while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size) && (ppc_state.pc < eb_end)) { - ppc_main_opcode(); + ppc_main_opcode(opcode); if (g_icycles++ >= max_cycles || exec_timer) { max_cycles = process_events(); } @@ -549,18 +553,19 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) eb_start = ppc_next_instruction_address; if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } else { page_start = eb_start & PPC_PAGE_MASK; eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); + opcode = ppc_read_instruction(pc_real); } ppc_state.pc = eb_start; exec_flags = 0; } else { ppc_state.pc += 4; pc_real += 4; - ppc_set_cur_instruction(pc_real); + opcode = ppc_read_instruction(pc_real); } } } diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index a12caafa39..edd7f09773 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -30,16 +30,6 @@ along with this program. If not, see . #include #include -// Storage and register retrieval functions for the floating point functions. - -double fp_return_double(uint32_t reg) { - return ppc_state.fpr[reg].dbl64_r; -} - -uint64_t fp_return_uint64(uint32_t reg) { - return ppc_state.fpr[reg].int64_r; -} - inline static void ppc_update_cr1() { // copy FPSCR[FX|FEX|VX|OX] to CR1 ppc_state.cr = (ppc_state.cr & ~CR_select::CR1_field) | @@ -137,7 +127,7 @@ static void fpresult_update(double set_result) { } else { ppc_state.fpscr |= FPCC_ZERO; } - + if (std::fetestexcept(FE_OVERFLOW)) { ppc_state.fpscr |= (OX + FX); } @@ -175,8 +165,8 @@ static void ppc_update_fex() { // Floating Point Arithmetic template -void dppc_interpreter::ppc_fadd() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fadd(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); max_double_check(val_reg_a, val_reg_b); @@ -189,12 +179,12 @@ void dppc_interpreter::ppc_fadd() { if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } - } + } if (snan_double_check(reg_a, reg_b)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); - } + } else { ppc_store_fpresult_flt(reg_d, ppc_dblresult64_d); } @@ -205,12 +195,12 @@ void dppc_interpreter::ppc_fadd() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fadd(); -template void dppc_interpreter::ppc_fadd(); +template void dppc_interpreter::ppc_fadd(uint32_t opcode); +template void dppc_interpreter::ppc_fadd(uint32_t opcode); template -void dppc_interpreter::ppc_fsub() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fsub(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); double ppc_dblresult64_d = val_reg_a - val_reg_b; @@ -235,12 +225,12 @@ void dppc_interpreter::ppc_fsub() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fsub(); -template void dppc_interpreter::ppc_fsub(); +template void dppc_interpreter::ppc_fsub(uint32_t opcode); +template void dppc_interpreter::ppc_fsub(uint32_t opcode); template -void dppc_interpreter::ppc_fdiv() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fdiv(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); double ppc_dblresult64_d = val_reg_a / val_reg_b; @@ -259,11 +249,11 @@ void dppc_interpreter::ppc_fdiv() { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } - + if (snan_double_check(reg_a, reg_b)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); - } + } else { ppc_store_fpresult_flt(reg_d, ppc_dblresult64_d); } @@ -274,12 +264,12 @@ void dppc_interpreter::ppc_fdiv() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fdiv(); -template void dppc_interpreter::ppc_fdiv(); +template void dppc_interpreter::ppc_fdiv(uint32_t opcode); +template void dppc_interpreter::ppc_fdiv(uint32_t opcode); template -void dppc_interpreter::ppc_fmul() { - ppc_grab_regsfpdac(ppc_cur_instruction); +void dppc_interpreter::ppc_fmul(uint32_t opcode) { + ppc_grab_regsfpdac(opcode); double ppc_dblresult64_d = val_reg_a * val_reg_c; @@ -293,8 +283,8 @@ void dppc_interpreter::ppc_fmul() { if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); - } - + } + if (snan_double_check(reg_a, reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -309,12 +299,12 @@ void dppc_interpreter::ppc_fmul() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmul(); -template void dppc_interpreter::ppc_fmul(); +template void dppc_interpreter::ppc_fmul(uint32_t opcode); +template void dppc_interpreter::ppc_fmul(uint32_t opcode); template -void dppc_interpreter::ppc_fmadd() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fmadd(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b); @@ -349,12 +339,12 @@ void dppc_interpreter::ppc_fmadd() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmadd(); -template void dppc_interpreter::ppc_fmadd(); +template void dppc_interpreter::ppc_fmadd(uint32_t opcode); +template void dppc_interpreter::ppc_fmadd(uint32_t opcode); template -void dppc_interpreter::ppc_fmsub() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fmsub(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, -val_reg_b); @@ -391,12 +381,12 @@ void dppc_interpreter::ppc_fmsub() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmsub(); -template void dppc_interpreter::ppc_fmsub(); +template void dppc_interpreter::ppc_fmsub(uint32_t opcode); +template void dppc_interpreter::ppc_fmsub(uint32_t opcode); template -void dppc_interpreter::ppc_fnmadd() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fnmadd(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b); @@ -419,7 +409,7 @@ void dppc_interpreter::ppc_fnmadd() { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } - + if (snan_single_check(reg_a) || snan_single_check(reg_b) || snan_single_check(reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -436,12 +426,12 @@ void dppc_interpreter::ppc_fnmadd() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fnmadd(); -template void dppc_interpreter::ppc_fnmadd(); +template void dppc_interpreter::ppc_fnmadd(uint32_t opcode); +template void dppc_interpreter::ppc_fnmadd(uint32_t opcode); template -void dppc_interpreter::ppc_fnmsub() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fnmsub(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, -val_reg_b); @@ -460,7 +450,7 @@ void dppc_interpreter::ppc_fnmsub() { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } - + if (snan_single_check(reg_a) || snan_single_check(reg_b) || snan_single_check(reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -474,17 +464,17 @@ void dppc_interpreter::ppc_fnmsub() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fnmsub(); -template void dppc_interpreter::ppc_fnmsub(); +template void dppc_interpreter::ppc_fnmsub(uint32_t opcode); +template void dppc_interpreter::ppc_fnmsub(uint32_t opcode); template -void dppc_interpreter::ppc_fadds() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fadds(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); max_double_check(val_reg_a, val_reg_b); double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b); - + double inf = std::numeric_limits::infinity(); if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) { ppc_state.fpscr |= VXISI; @@ -506,17 +496,17 @@ void dppc_interpreter::ppc_fadds() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fadds(); -template void dppc_interpreter::ppc_fadds(); +template void dppc_interpreter::ppc_fadds(uint32_t opcode); +template void dppc_interpreter::ppc_fadds(uint32_t opcode); template -void dppc_interpreter::ppc_fsubs() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fsubs(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b); double inf = std::numeric_limits::infinity(); - if (((val_reg_a == inf) && (val_reg_b == inf)) || + if (((val_reg_a == inf) && (val_reg_b == inf)) || ((val_reg_a == -inf) && (val_reg_b == -inf))) { ppc_state.fpscr |= VXISI; if (std::isnan(ppc_dblresult64_d)) { @@ -537,12 +527,12 @@ void dppc_interpreter::ppc_fsubs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fsubs(); -template void dppc_interpreter::ppc_fsubs(); +template void dppc_interpreter::ppc_fsubs(uint32_t opcode); +template void dppc_interpreter::ppc_fsubs(uint32_t opcode); template -void dppc_interpreter::ppc_fdivs() { - ppc_grab_regsfpdab(ppc_cur_instruction); +void dppc_interpreter::ppc_fdivs(uint32_t opcode) { + ppc_grab_regsfpdab(opcode); double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b); if (val_reg_b == 0.0) { @@ -578,12 +568,12 @@ void dppc_interpreter::ppc_fdivs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fdivs(); -template void dppc_interpreter::ppc_fdivs(); +template void dppc_interpreter::ppc_fdivs(uint32_t opcode); +template void dppc_interpreter::ppc_fdivs(uint32_t opcode); template -void dppc_interpreter::ppc_fmuls() { - ppc_grab_regsfpdac(ppc_cur_instruction); +void dppc_interpreter::ppc_fmuls(uint32_t opcode) { + ppc_grab_regsfpdac(opcode); double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c); @@ -597,8 +587,8 @@ void dppc_interpreter::ppc_fmuls() { if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); - } - + } + if (snan_double_check(reg_a, reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -613,12 +603,12 @@ void dppc_interpreter::ppc_fmuls() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmuls(); -template void dppc_interpreter::ppc_fmuls(); +template void dppc_interpreter::ppc_fmuls(uint32_t opcode); +template void dppc_interpreter::ppc_fmuls(uint32_t opcode); template -void dppc_interpreter::ppc_fmadds() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fmadds(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, val_reg_b); @@ -633,7 +623,7 @@ void dppc_interpreter::ppc_fmadds() { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } - + if (snan_single_check(reg_a) || snan_single_check(reg_b) || snan_single_check(reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -648,15 +638,15 @@ void dppc_interpreter::ppc_fmadds() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmadds(); -template void dppc_interpreter::ppc_fmadds(); +template void dppc_interpreter::ppc_fmadds(uint32_t opcode); +template void dppc_interpreter::ppc_fmadds(uint32_t opcode); template -void dppc_interpreter::ppc_fmsubs() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fmsubs(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b); - + if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { ppc_state.fpscr |= VXIMZ; @@ -668,7 +658,7 @@ void dppc_interpreter::ppc_fmsubs() { double inf = std::numeric_limits::infinity(); if ((val_reg_a == inf) && (val_reg_b == inf)) ppc_state.fpscr |= VXISI; - + if (snan_single_check(reg_a) || snan_single_check(reg_b) || snan_single_check(reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -682,12 +672,12 @@ void dppc_interpreter::ppc_fmsubs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmsubs(); -template void dppc_interpreter::ppc_fmsubs(); +template void dppc_interpreter::ppc_fmsubs(uint32_t opcode); +template void dppc_interpreter::ppc_fmsubs(uint32_t opcode); template -void dppc_interpreter::ppc_fnmadds() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fnmadds(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b); if (std::isnan(ppc_dblresult64_d)) { @@ -719,12 +709,12 @@ void dppc_interpreter::ppc_fnmadds() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fnmadds(); -template void dppc_interpreter::ppc_fnmadds(); +template void dppc_interpreter::ppc_fnmadds(uint32_t opcode); +template void dppc_interpreter::ppc_fnmadds(uint32_t opcode); template -void dppc_interpreter::ppc_fnmsubs() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fnmsubs(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); snan_double_check(reg_a, reg_c); snan_single_check(reg_b); @@ -745,8 +735,8 @@ void dppc_interpreter::ppc_fnmsubs() { if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); - } - + } + if (snan_single_check(reg_a) || snan_single_check(reg_b) || snan_single_check(reg_c)) { uint64_t qnan = 0x7FFC000000000000; ppc_store_fpresult_int(reg_d, qnan); @@ -760,12 +750,12 @@ void dppc_interpreter::ppc_fnmsubs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fnmsubs(); -template void dppc_interpreter::ppc_fnmsubs(); +template void dppc_interpreter::ppc_fnmsubs(uint32_t opcode); +template void dppc_interpreter::ppc_fnmsubs(uint32_t opcode); template -void dppc_interpreter::ppc_fabs() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fabs(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); uint64_t ppc_result64_d = FPR_INT(reg_b) & ~0x8000000000000000U; @@ -777,12 +767,12 @@ void dppc_interpreter::ppc_fabs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fabs(); -template void dppc_interpreter::ppc_fabs(); +template void dppc_interpreter::ppc_fabs(uint32_t opcode); +template void dppc_interpreter::ppc_fabs(uint32_t opcode); template -void dppc_interpreter::ppc_fnabs() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fnabs(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); uint64_t ppc_result64_d = FPR_INT(reg_b) | 0x8000000000000000U; @@ -794,12 +784,12 @@ void dppc_interpreter::ppc_fnabs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fnabs(); -template void dppc_interpreter::ppc_fnabs(); +template void dppc_interpreter::ppc_fnabs(uint32_t opcode); +template void dppc_interpreter::ppc_fnabs(uint32_t opcode); template -void dppc_interpreter::ppc_fneg() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fneg(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); uint64_t ppc_result64_d = FPR_INT(reg_b) ^ 0x8000000000000000U; @@ -811,12 +801,12 @@ void dppc_interpreter::ppc_fneg() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fneg(); -template void dppc_interpreter::ppc_fneg(); +template void dppc_interpreter::ppc_fneg(uint32_t opcode); +template void dppc_interpreter::ppc_fneg(uint32_t opcode); template -void dppc_interpreter::ppc_fsel() { - ppc_grab_regsfpdabc(ppc_cur_instruction); +void dppc_interpreter::ppc_fsel(uint32_t opcode) { + ppc_grab_regsfpdabc(opcode); double ppc_dblresult64_d = (val_reg_a >= -0.0) ? val_reg_c : val_reg_b; @@ -826,12 +816,12 @@ void dppc_interpreter::ppc_fsel() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fsel(); -template void dppc_interpreter::ppc_fsel(); +template void dppc_interpreter::ppc_fsel(uint32_t opcode); +template void dppc_interpreter::ppc_fsel(uint32_t opcode); template -void dppc_interpreter::ppc_fsqrt() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fsqrt(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = std::sqrt(testd2); @@ -847,12 +837,12 @@ void dppc_interpreter::ppc_fsqrt() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fsqrt(); -template void dppc_interpreter::ppc_fsqrt(); +template void dppc_interpreter::ppc_fsqrt(uint32_t opcode); +template void dppc_interpreter::ppc_fsqrt(uint32_t opcode); template -void dppc_interpreter::ppc_fsqrts() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fsqrts(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = (float)std::sqrt(testd2); @@ -868,12 +858,12 @@ void dppc_interpreter::ppc_fsqrts() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fsqrts(); -template void dppc_interpreter::ppc_fsqrts(); +template void dppc_interpreter::ppc_fsqrts(uint32_t opcode); +template void dppc_interpreter::ppc_fsqrts(uint32_t opcode); template -void dppc_interpreter::ppc_frsqrte() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_frsqrte(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = 1.0 / sqrt(testd2); @@ -889,12 +879,12 @@ void dppc_interpreter::ppc_frsqrte() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_frsqrte(); -template void dppc_interpreter::ppc_frsqrte(); +template void dppc_interpreter::ppc_frsqrte(uint32_t opcode); +template void dppc_interpreter::ppc_frsqrte(uint32_t opcode); template -void dppc_interpreter::ppc_frsp() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_frsp(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); double ppc_dblresult64_d = (float)(GET_FPR(reg_b)); @@ -909,12 +899,12 @@ void dppc_interpreter::ppc_frsp() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_frsp(); -template void dppc_interpreter::ppc_frsp(); +template void dppc_interpreter::ppc_frsp(uint32_t opcode); +template void dppc_interpreter::ppc_frsp(uint32_t opcode); template -void dppc_interpreter::ppc_fres() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fres(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); double start_num = GET_FPR(reg_b); double ppc_dblresult64_d = (float)(1.0 / start_num); @@ -941,11 +931,11 @@ void dppc_interpreter::ppc_fres() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fres(); -template void dppc_interpreter::ppc_fres(); +template void dppc_interpreter::ppc_fres(uint32_t opcode); +template void dppc_interpreter::ppc_fres(uint32_t opcode); -static void round_to_int(const uint8_t mode, field_rc rec) { - ppc_grab_regsfpdb(ppc_cur_instruction); +static void round_to_int(uint32_t opcode, const uint8_t mode, field_rc rec) { + ppc_grab_regsfpdb(opcode); double val_reg_b = GET_FPR(reg_b); if (std::isnan(val_reg_b)) { @@ -957,7 +947,7 @@ static void round_to_int(const uint8_t mode, field_rc rec) { if (ppc_state.fpscr & FPSCR::VE) { ppc_state.fpscr |= FPSCR::FEX; // VX=1 and VE=1 cause FEX to be set - ppc_floating_point_exception(); + ppc_floating_point_exception(opcode); } else { ppc_state.fpr[reg_d].int64_r = 0xFFF8000080000000ULL; } @@ -968,7 +958,7 @@ static void round_to_int(const uint8_t mode, field_rc rec) { if (ppc_state.fpscr & FPSCR::VE) { ppc_state.fpscr |= FPSCR::FEX; // VX=1 and VE=1 cause FEX to be set - ppc_floating_point_exception(); + ppc_floating_point_exception(opcode); } else { if (val_reg_b >= 0.0f) ppc_state.fpr[reg_d].int64_r = 0xFFF800007FFFFFFFULL; @@ -1002,37 +992,37 @@ static void round_to_int(const uint8_t mode, field_rc rec) { } template -void dppc_interpreter::ppc_fctiw() { - round_to_int(ppc_state.fpscr & 0x3, rec); +void dppc_interpreter::ppc_fctiw(uint32_t opcode) { + round_to_int(opcode, ppc_state.fpscr & 0x3, rec); } -template void dppc_interpreter::ppc_fctiw(); -template void dppc_interpreter::ppc_fctiw(); +template void dppc_interpreter::ppc_fctiw(uint32_t opcode); +template void dppc_interpreter::ppc_fctiw(uint32_t opcode); template -void dppc_interpreter::ppc_fctiwz() { - round_to_int(1, rec); +void dppc_interpreter::ppc_fctiwz(uint32_t opcode) { + round_to_int(opcode, 1, rec); } -template void dppc_interpreter::ppc_fctiwz(); -template void dppc_interpreter::ppc_fctiwz(); +template void dppc_interpreter::ppc_fctiwz(uint32_t opcode); +template void dppc_interpreter::ppc_fctiwz(uint32_t opcode); // Floating Point Store and Load -void dppc_interpreter::ppc_lfs() { - ppc_grab_regsfpdia(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); +void dppc_interpreter::ppc_lfs(uint32_t opcode) { + ppc_grab_regsfpdia(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a) ? val_reg_a : 0; - uint32_t result = mmu_read_vmem(ea); + uint32_t result = mmu_read_vmem(opcode, ea); ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result); } -void dppc_interpreter::ppc_lfsu() { - ppc_grab_regsfpdia(ppc_cur_instruction); +void dppc_interpreter::ppc_lfsu(uint32_t opcode) { + ppc_grab_regsfpdia(opcode); if (reg_a) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a) ? val_reg_a : 0; - uint32_t result = mmu_read_vmem(ea); + uint32_t result = mmu_read_vmem(opcode, ea); ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result); ppc_state.gpr[reg_a] = ea; } else { @@ -1040,18 +1030,18 @@ void dppc_interpreter::ppc_lfsu() { } } -void dppc_interpreter::ppc_lfsx() { - ppc_grab_regsfpdiab(ppc_cur_instruction); +void dppc_interpreter::ppc_lfsx(uint32_t opcode) { + ppc_grab_regsfpdiab(opcode); uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0); - uint32_t result = mmu_read_vmem(ea); + uint32_t result = mmu_read_vmem(opcode, ea); ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result); } -void dppc_interpreter::ppc_lfsux() { - ppc_grab_regsfpdiab(ppc_cur_instruction); +void dppc_interpreter::ppc_lfsux(uint32_t opcode) { + ppc_grab_regsfpdiab(opcode); if (reg_a) { uint32_t ea = val_reg_a + val_reg_b; - uint32_t result = mmu_read_vmem(ea); + uint32_t result = mmu_read_vmem(opcode, ea); ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result); ppc_state.gpr[reg_a] = ea; } else { @@ -1059,20 +1049,20 @@ void dppc_interpreter::ppc_lfsux() { } } -void dppc_interpreter::ppc_lfd() { - ppc_grab_regsfpdia(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); +void dppc_interpreter::ppc_lfd(uint32_t opcode) { + ppc_grab_regsfpdia(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a) ? val_reg_a : 0; - uint64_t ppc_result64_d = mmu_read_vmem(ea); + uint64_t ppc_result64_d = mmu_read_vmem(opcode, ea); ppc_store_fpresult_int(reg_d, ppc_result64_d); } -void dppc_interpreter::ppc_lfdu() { - ppc_grab_regsfpdia(ppc_cur_instruction); +void dppc_interpreter::ppc_lfdu(uint32_t opcode) { + ppc_grab_regsfpdia(opcode); if (reg_a != 0) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += val_reg_a; - uint64_t ppc_result64_d = mmu_read_vmem(ea); + uint64_t ppc_result64_d = mmu_read_vmem(opcode, ea); ppc_store_fpresult_int(reg_d, ppc_result64_d); ppc_state.gpr[reg_a] = ea; } else { @@ -1080,18 +1070,18 @@ void dppc_interpreter::ppc_lfdu() { } } -void dppc_interpreter::ppc_lfdx() { - ppc_grab_regsfpdiab(ppc_cur_instruction); +void dppc_interpreter::ppc_lfdx(uint32_t opcode) { + ppc_grab_regsfpdiab(opcode); uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0); - uint64_t ppc_result64_d = mmu_read_vmem(ea); + uint64_t ppc_result64_d = mmu_read_vmem(opcode, ea); ppc_store_fpresult_int(reg_d, ppc_result64_d); } -void dppc_interpreter::ppc_lfdux() { - ppc_grab_regsfpdiab(ppc_cur_instruction); +void dppc_interpreter::ppc_lfdux(uint32_t opcode) { + ppc_grab_regsfpdiab(opcode); if (reg_a) { uint32_t ea = val_reg_a + val_reg_b; - uint64_t ppc_result64_d = mmu_read_vmem(ea); + uint64_t ppc_result64_d = mmu_read_vmem(opcode, ea); ppc_store_fpresult_int(reg_d, ppc_result64_d); ppc_state.gpr[reg_a] = ea; } else { @@ -1099,105 +1089,105 @@ void dppc_interpreter::ppc_lfdux() { } } -void dppc_interpreter::ppc_stfs() { - ppc_grab_regsfpsia(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); +void dppc_interpreter::ppc_stfs(uint32_t opcode) { + ppc_grab_regsfpsia(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a) ? val_reg_a : 0; float result = float(ppc_state.fpr[reg_s].dbl64_r); - mmu_write_vmem(ea, *(uint32_t*)(&result)); + mmu_write_vmem(opcode, ea, *(uint32_t*)(&result)); } -void dppc_interpreter::ppc_stfsu() { - ppc_grab_regsfpsia(ppc_cur_instruction); +void dppc_interpreter::ppc_stfsu(uint32_t opcode) { + ppc_grab_regsfpsia(opcode); if (reg_a != 0) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += val_reg_a; float result = float(ppc_state.fpr[reg_s].dbl64_r); - mmu_write_vmem(ea, *(uint32_t*)(&result)); + mmu_write_vmem(opcode, ea, *(uint32_t*)(&result)); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_stfsx() { - ppc_grab_regsfpsiab(ppc_cur_instruction); +void dppc_interpreter::ppc_stfsx(uint32_t opcode) { + ppc_grab_regsfpsiab(opcode); uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0); float result = float(ppc_state.fpr[reg_s].dbl64_r); - mmu_write_vmem(ea, *(uint32_t*)(&result)); + mmu_write_vmem(opcode, ea, *(uint32_t*)(&result)); } -void dppc_interpreter::ppc_stfsux() { - ppc_grab_regsfpsiab(ppc_cur_instruction); +void dppc_interpreter::ppc_stfsux(uint32_t opcode) { + ppc_grab_regsfpsiab(opcode); if (reg_a) { uint32_t ea = val_reg_a + val_reg_b; float result = float(ppc_state.fpr[reg_s].dbl64_r); - mmu_write_vmem(ea, *(uint32_t*)(&result)); + mmu_write_vmem(opcode, ea, *(uint32_t*)(&result)); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_stfd() { - ppc_grab_regsfpsia(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); +void dppc_interpreter::ppc_stfd(uint32_t opcode) { + ppc_grab_regsfpsia(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += reg_a ? val_reg_a : 0; - mmu_write_vmem(ea, ppc_state.fpr[reg_s].int64_r); + mmu_write_vmem(opcode, ea, ppc_state.fpr[reg_s].int64_r); } -void dppc_interpreter::ppc_stfdu() { - ppc_grab_regsfpsia(ppc_cur_instruction); +void dppc_interpreter::ppc_stfdu(uint32_t opcode) { + ppc_grab_regsfpsia(opcode); if (reg_a != 0) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += val_reg_a; - mmu_write_vmem(ea, ppc_state.fpr[reg_s].int64_r); + mmu_write_vmem(opcode, ea, ppc_state.fpr[reg_s].int64_r); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_stfdx() { - ppc_grab_regsfpsiab(ppc_cur_instruction); +void dppc_interpreter::ppc_stfdx(uint32_t opcode) { + ppc_grab_regsfpsiab(opcode); uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0); - mmu_write_vmem(ea, ppc_state.fpr[reg_s].int64_r); + mmu_write_vmem(opcode, ea, ppc_state.fpr[reg_s].int64_r); } -void dppc_interpreter::ppc_stfdux() { - ppc_grab_regsfpsiab(ppc_cur_instruction); +void dppc_interpreter::ppc_stfdux(uint32_t opcode) { + ppc_grab_regsfpsiab(opcode); if (reg_a != 0) { uint32_t ea = val_reg_a + val_reg_b; - mmu_write_vmem(ea, ppc_state.fpr[reg_s].int64_r); + mmu_write_vmem(opcode, ea, ppc_state.fpr[reg_s].int64_r); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_stfiwx() { - ppc_grab_regsfpsiab(ppc_cur_instruction); +void dppc_interpreter::ppc_stfiwx(uint32_t opcode) { + ppc_grab_regsfpsiab(opcode); uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0); - mmu_write_vmem(ea, uint32_t(ppc_state.fpr[reg_s].int64_r)); + mmu_write_vmem(opcode, ea, uint32_t(ppc_state.fpr[reg_s].int64_r)); } // Floating Point Register Transfer template -void dppc_interpreter::ppc_fmr() { - ppc_grab_regsfpdb(ppc_cur_instruction); +void dppc_interpreter::ppc_fmr(uint32_t opcode) { + ppc_grab_regsfpdb(opcode); ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r; if (rec) ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmr(); -template void dppc_interpreter::ppc_fmr(); +template void dppc_interpreter::ppc_fmr(uint32_t opcode); +template void dppc_interpreter::ppc_fmr(uint32_t opcode); template -void dppc_interpreter::ppc_mffs() { - int reg_d = (ppc_cur_instruction >> 21) & 31; +void dppc_interpreter::ppc_mffs(uint32_t opcode) { + int reg_d = (opcode >> 21) & 31; ppc_state.fpr[reg_d].int64_r = uint64_t(ppc_state.fpscr) | (for601 ? 0xFFFFFFFF00000000ULL : 0xFFF8000000000000ULL); @@ -1205,15 +1195,15 @@ void dppc_interpreter::ppc_mffs() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_mffs(); -template void dppc_interpreter::ppc_mffs(); -template void dppc_interpreter::ppc_mffs(); -template void dppc_interpreter::ppc_mffs(); +template void dppc_interpreter::ppc_mffs(uint32_t opcode); +template void dppc_interpreter::ppc_mffs(uint32_t opcode); +template void dppc_interpreter::ppc_mffs(uint32_t opcode); +template void dppc_interpreter::ppc_mffs(uint32_t opcode); template -void dppc_interpreter::ppc_mtfsf() { - int reg_b = (ppc_cur_instruction >> 11) & 0x1F; - uint8_t fm = (ppc_cur_instruction >> 17) & 0xFF; +void dppc_interpreter::ppc_mtfsf(uint32_t opcode) { + int reg_b = (opcode >> 11) & 0x1F; + uint8_t fm = (opcode >> 17) & 0xFF; uint32_t cr_mask = 0; @@ -1240,13 +1230,13 @@ void dppc_interpreter::ppc_mtfsf() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_mtfsf(); -template void dppc_interpreter::ppc_mtfsf(); +template void dppc_interpreter::ppc_mtfsf(uint32_t opcode); +template void dppc_interpreter::ppc_mtfsf(uint32_t opcode); template -void dppc_interpreter::ppc_mtfsfi() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - uint32_t imm = (ppc_cur_instruction << 16) & 0xF0000000UL; +void dppc_interpreter::ppc_mtfsfi(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1C; + uint32_t imm = (opcode << 16) & 0xF0000000UL; // prepare field mask and ensure that neither FEX nor VX will be changed uint32_t mask = (0xF0000000UL >> crf_d) & ~(FPSCR::FEX | FPSCR::VX); @@ -1262,12 +1252,12 @@ void dppc_interpreter::ppc_mtfsfi() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_mtfsfi(); -template void dppc_interpreter::ppc_mtfsfi(); +template void dppc_interpreter::ppc_mtfsfi(uint32_t opcode); +template void dppc_interpreter::ppc_mtfsfi(uint32_t opcode); template -void dppc_interpreter::ppc_mtfsb0() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1F; +void dppc_interpreter::ppc_mtfsb0(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1F; if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly cleared ppc_state.fpscr &= ~(0x80000000UL >> crf_d); } @@ -1276,12 +1266,12 @@ void dppc_interpreter::ppc_mtfsb0() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_mtfsb0(); -template void dppc_interpreter::ppc_mtfsb0(); +template void dppc_interpreter::ppc_mtfsb0(uint32_t opcode); +template void dppc_interpreter::ppc_mtfsb0(uint32_t opcode); template -void dppc_interpreter::ppc_mtfsb1() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1F; +void dppc_interpreter::ppc_mtfsb1(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1F; if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly set ppc_state.fpscr |= (0x80000000UL >> crf_d); } @@ -1290,12 +1280,12 @@ void dppc_interpreter::ppc_mtfsb1() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_mtfsb1(); -template void dppc_interpreter::ppc_mtfsb1(); +template void dppc_interpreter::ppc_mtfsb1(uint32_t opcode); +template void dppc_interpreter::ppc_mtfsb1(uint32_t opcode); -void dppc_interpreter::ppc_mcrfs() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - int crf_s = (ppc_cur_instruction >> 16) & 0x1C; +void dppc_interpreter::ppc_mcrfs(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1C; + int crf_s = (opcode >> 16) & 0x1C; ppc_state.cr = ( (ppc_state.cr & ~(0xF0000000UL >> crf_d)) | (((ppc_state.fpscr << crf_s) & 0xF0000000UL) >> crf_d) @@ -1312,8 +1302,8 @@ void dppc_interpreter::ppc_mcrfs() { // Floating Point Comparisons -void dppc_interpreter::ppc_fcmpo() { - ppc_grab_regsfpsab(ppc_cur_instruction); +void dppc_interpreter::ppc_fcmpo(uint32_t opcode) { + ppc_grab_regsfpsab(opcode); uint32_t cmp_c = 0; @@ -1343,8 +1333,8 @@ void dppc_interpreter::ppc_fcmpo() { } -void dppc_interpreter::ppc_fcmpu() { - ppc_grab_regsfpsab(ppc_cur_instruction); +void dppc_interpreter::ppc_fcmpu(uint32_t opcode) { + ppc_grab_regsfpsab(opcode); uint32_t cmp_c = 0; diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 20ba67cfa1..3cbbdea1bb 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -741,7 +741,6 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr) host_va = (uint8_t *)(tlb1_entry->host_va_offs_r + vaddr); } - ppc_set_cur_instruction(host_va); if (paddr) *paddr = tlb1_entry->phys_tag | (vaddr & 0xFFFUL); @@ -985,12 +984,12 @@ void mmu_pat_ctx_changed() // Forward declarations. template -static T read_unaligned(uint32_t guest_va, uint8_t *host_va); +static T read_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va); template -static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value); +static void write_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va, T value); template -inline T mmu_read_vmem(uint32_t guest_va) +inline T mmu_read_vmem(uint32_t opcode, uint32_t guest_va) { TLBEntry *tlb1_entry, *tlb2_entry; uint8_t *host_va; @@ -1034,7 +1033,7 @@ inline T mmu_read_vmem(uint32_t guest_va) #endif if (sizeof(T) == 8) { if (guest_va & 3) - ppc_alignment_exception(guest_va); + ppc_alignment_exception(opcode, guest_va); return ( ((T)tlb2_entry->rgn_desc->devobj->read(tlb2_entry->rgn_desc->start, @@ -1061,7 +1060,7 @@ inline T mmu_read_vmem(uint32_t guest_va) // handle unaligned memory accesses if (sizeof(T) > 1 && (guest_va & (sizeof(T) - 1))) { - return read_unaligned(guest_va, host_va); + return read_unaligned(opcode, guest_va, host_va); } // handle aligned memory accesses @@ -1078,13 +1077,13 @@ inline T mmu_read_vmem(uint32_t guest_va) } // explicitely instantiate all required mmu_read_vmem variants -template uint8_t mmu_read_vmem(uint32_t guest_va); -template uint16_t mmu_read_vmem(uint32_t guest_va); -template uint32_t mmu_read_vmem(uint32_t guest_va); -template uint64_t mmu_read_vmem(uint32_t guest_va); +template uint8_t mmu_read_vmem(uint32_t opcode, uint32_t guest_va); +template uint16_t mmu_read_vmem(uint32_t opcode, uint32_t guest_va); +template uint32_t mmu_read_vmem(uint32_t opcode, uint32_t guest_va); +template uint64_t mmu_read_vmem(uint32_t opcode, uint32_t guest_va); template -inline void mmu_write_vmem(uint32_t guest_va, T value) +inline void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, T value) { TLBEntry *tlb1_entry, *tlb2_entry; uint8_t *host_va; @@ -1156,7 +1155,7 @@ inline void mmu_write_vmem(uint32_t guest_va, T value) #endif if (sizeof(T) == 8) { if (guest_va & 3) - ppc_alignment_exception(guest_va); + ppc_alignment_exception(opcode, guest_va); tlb2_entry->rgn_desc->devobj->write(tlb2_entry->rgn_desc->start, static_cast(guest_va - tlb2_entry->dev_base_va), @@ -1179,7 +1178,7 @@ inline void mmu_write_vmem(uint32_t guest_va, T value) // handle unaligned memory accesses if (sizeof(T) > 1 && (guest_va & (sizeof(T) - 1))) { - write_unaligned(guest_va, host_va, value); + write_unaligned(opcode, guest_va, host_va, value); return; } @@ -1201,17 +1200,17 @@ inline void mmu_write_vmem(uint32_t guest_va, T value) } // explicitely instantiate all required mmu_write_vmem variants -template void mmu_write_vmem(uint32_t guest_va, uint8_t value); -template void mmu_write_vmem(uint32_t guest_va, uint16_t value); -template void mmu_write_vmem(uint32_t guest_va, uint32_t value); -template void mmu_write_vmem(uint32_t guest_va, uint64_t value); +template void mmu_write_vmem (uint32_t opcode, uint32_t guest_va, uint8_t value); +template void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, uint16_t value); +template void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, uint32_t value); +template void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, uint64_t value); template -static T read_unaligned(uint32_t guest_va, uint8_t *host_va) +static T read_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va) { if ((sizeof(T) == 8) && (guest_va & 3)) { #ifndef PPC_TESTS - ppc_alignment_exception(guest_va); + ppc_alignment_exception(opcode, guest_va); #endif } @@ -1226,7 +1225,7 @@ static T read_unaligned(uint32_t guest_va, uint8_t *host_va) // Because such accesses suffer a performance penalty, they will be // presumably very rare so don't waste time optimizing the code below. for (int i = 0; i < sizeof(T); guest_va++, i++) { - result = (result << 8) | mmu_read_vmem(guest_va); + result = (result << 8) | mmu_read_vmem(opcode, guest_va); } } else { #ifdef MMU_PROFILING @@ -1247,16 +1246,16 @@ static T read_unaligned(uint32_t guest_va, uint8_t *host_va) } // explicitely instantiate all required read_unaligned variants -template uint16_t read_unaligned(uint32_t guest_va, uint8_t *host_va); -template uint32_t read_unaligned(uint32_t guest_va, uint8_t *host_va); -template uint64_t read_unaligned(uint32_t guest_va, uint8_t *host_va); +template uint16_t read_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va); +template uint32_t read_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va); +template uint64_t read_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va); template -static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value) +static void write_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va, T value) { if ((sizeof(T) == 8) && (guest_va & 3)) { #ifndef PPC_TESTS - ppc_alignment_exception(guest_va); + ppc_alignment_exception(opcode, guest_va); #endif } @@ -1272,7 +1271,7 @@ static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value) uint32_t shift = (sizeof(T) - 1) * 8; for (int i = 0; i < sizeof(T); shift -= 8, guest_va++, i++) { - mmu_write_vmem(guest_va, (value >> shift) & 0xFF); + mmu_write_vmem(opcode, guest_va, (value >> shift) & 0xFF); } } else { #ifdef MMU_PROFILING @@ -1296,9 +1295,9 @@ static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value) } // explicitely instantiate all required write_unaligned variants -template void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint16_t value); -template void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint32_t value); -template void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint64_t value); +template void write_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va, uint16_t value); +template void write_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va, uint32_t value); +template void write_unaligned(uint32_t opcode, uint32_t guest_va, uint8_t *host_va, uint64_t value); /* MMU profiling. */ @@ -1426,7 +1425,7 @@ class TLBProfile : public BaseProfile { }; #endif -uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t size) { +uint64_t mem_read_dbg(uint32_t opcode, uint32_t virt_addr, uint32_t size) { uint32_t save_dsisr, save_dar; uint64_t ret_val; @@ -1438,19 +1437,19 @@ uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t size) { try { switch (size) { case 1: - ret_val = mmu_read_vmem(virt_addr); + ret_val = mmu_read_vmem(opcode, virt_addr); break; case 2: - ret_val = mmu_read_vmem(virt_addr); + ret_val = mmu_read_vmem(opcode, virt_addr); break; case 4: - ret_val = mmu_read_vmem(virt_addr); + ret_val = mmu_read_vmem(opcode, virt_addr); break; case 8: - ret_val = mmu_read_vmem(virt_addr); + ret_val = mmu_read_vmem(opcode, virt_addr); break; default: - ret_val = mmu_read_vmem(virt_addr); + ret_val = mmu_read_vmem(opcode, virt_addr); } } catch (std::invalid_argument& exc) { /* restore MMU-related CPU state */ diff --git a/cpu/ppc/ppcmmu.h b/cpu/ppc/ppcmmu.h index d4d9c8eb4a..da2cf73bdd 100644 --- a/cpu/ppc/ppcmmu.h +++ b/cpu/ppc/ppcmmu.h @@ -125,13 +125,13 @@ extern void mmu_change_mode(void); extern void mmu_pat_ctx_changed(); extern void tlb_flush_entry(uint32_t ea); -extern uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t size); +extern uint64_t mem_read_dbg(uint32_t opcode, uint32_t virt_addr, uint32_t size); uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr = nullptr); bool mmu_translate_dbg(uint32_t guest_va, uint32_t &guest_pa); template -extern T mmu_read_vmem(uint32_t guest_va); +extern T mmu_read_vmem(uint32_t opcode, uint32_t guest_va); template -extern void mmu_write_vmem(uint32_t guest_va, T value); +extern void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, T value); #endif // PPCMMU_H diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index d3f111fcb3..a3f193c22e 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -96,20 +96,20 @@ function (theoretically). **/ template -void dppc_interpreter::ppc_addi() { - ppc_grab_regsdasimm(ppc_cur_instruction); +void dppc_interpreter::ppc_addi(uint32_t opcode) { + ppc_grab_regsdasimm(opcode); if (shift) ppc_state.gpr[reg_d] = (reg_a == 0) ? (simm << 16) : (ppc_result_a + (simm << 16)); else ppc_state.gpr[reg_d] = (reg_a == 0) ? simm : (ppc_result_a + simm); } -template void dppc_interpreter::ppc_addi(); -template void dppc_interpreter::ppc_addi(); +template void dppc_interpreter::ppc_addi(uint32_t opcode); +template void dppc_interpreter::ppc_addi(uint32_t opcode); template -void dppc_interpreter::ppc_addic() { - ppc_grab_regsdasimm(ppc_cur_instruction); +void dppc_interpreter::ppc_addic(uint32_t opcode) { + ppc_grab_regsdasimm(opcode); uint32_t ppc_result_d = (ppc_result_a + simm); ppc_carry(ppc_result_a, ppc_result_d); if (rec) @@ -117,12 +117,12 @@ void dppc_interpreter::ppc_addic() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_addic(); -template void dppc_interpreter::ppc_addic(); +template void dppc_interpreter::ppc_addic(uint32_t opcode); +template void dppc_interpreter::ppc_addic(uint32_t opcode); template -void dppc_interpreter::ppc_add() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_add(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t ppc_result_d = ppc_result_a + ppc_result_b; if (carry) @@ -134,18 +134,18 @@ void dppc_interpreter::ppc_add() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); -template void dppc_interpreter::ppc_add(); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); +template void dppc_interpreter::ppc_add(uint32_t opcode); template -void dppc_interpreter::ppc_adde() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_adde(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; @@ -163,14 +163,14 @@ void dppc_interpreter::ppc_adde() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_adde(); -template void dppc_interpreter::ppc_adde(); -template void dppc_interpreter::ppc_adde(); -template void dppc_interpreter::ppc_adde(); +template void dppc_interpreter::ppc_adde(uint32_t opcode); +template void dppc_interpreter::ppc_adde(uint32_t opcode); +template void dppc_interpreter::ppc_adde(uint32_t opcode); +template void dppc_interpreter::ppc_adde(uint32_t opcode); template -void dppc_interpreter::ppc_addme() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::ppc_addme(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ppc_result_a + xer_ca - 1; @@ -188,14 +188,14 @@ void dppc_interpreter::ppc_addme() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_addme(); -template void dppc_interpreter::ppc_addme(); -template void dppc_interpreter::ppc_addme(); -template void dppc_interpreter::ppc_addme(); +template void dppc_interpreter::ppc_addme(uint32_t opcode); +template void dppc_interpreter::ppc_addme(uint32_t opcode); +template void dppc_interpreter::ppc_addme(uint32_t opcode); +template void dppc_interpreter::ppc_addme(uint32_t opcode); template -void dppc_interpreter::ppc_addze() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::ppc_addze(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ppc_result_a + grab_xer; @@ -213,13 +213,13 @@ void dppc_interpreter::ppc_addze() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_addze(); -template void dppc_interpreter::ppc_addze(); -template void dppc_interpreter::ppc_addze(); -template void dppc_interpreter::ppc_addze(); +template void dppc_interpreter::ppc_addze(uint32_t opcode); +template void dppc_interpreter::ppc_addze(uint32_t opcode); +template void dppc_interpreter::ppc_addze(uint32_t opcode); +template void dppc_interpreter::ppc_addze(uint32_t opcode); -void dppc_interpreter::ppc_subfic() { - ppc_grab_regsdasimm(ppc_cur_instruction); +void dppc_interpreter::ppc_subfic(uint32_t opcode) { + ppc_grab_regsdasimm(opcode); uint32_t ppc_result_d = simm - ppc_result_a; if (simm == -1) ppc_state.spr[SPR::XER] |= XER::CA; @@ -229,8 +229,8 @@ void dppc_interpreter::ppc_subfic() { } template -void dppc_interpreter::ppc_subf() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_subf(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t ppc_result_d = ppc_result_b - ppc_result_a; if (carry) @@ -243,18 +243,18 @@ void dppc_interpreter::ppc_subf() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); -template void dppc_interpreter::ppc_subf(); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); +template void dppc_interpreter::ppc_subf(uint32_t opcode); template -void dppc_interpreter::ppc_subfe() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_subfe(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ~ppc_result_a + ppc_result_b + grab_ca; if (grab_ca && ppc_result_b == 0xFFFFFFFFUL) @@ -270,14 +270,14 @@ void dppc_interpreter::ppc_subfe() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_subfe(); -template void dppc_interpreter::ppc_subfe(); -template void dppc_interpreter::ppc_subfe(); -template void dppc_interpreter::ppc_subfe(); +template void dppc_interpreter::ppc_subfe(uint32_t opcode); +template void dppc_interpreter::ppc_subfe(uint32_t opcode); +template void dppc_interpreter::ppc_subfe(uint32_t opcode); +template void dppc_interpreter::ppc_subfe(uint32_t opcode); template -void dppc_interpreter::ppc_subfme() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::ppc_subfme(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ~ppc_result_a + grab_ca - 1; @@ -299,14 +299,14 @@ void dppc_interpreter::ppc_subfme() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_subfme(); -template void dppc_interpreter::ppc_subfme(); -template void dppc_interpreter::ppc_subfme(); -template void dppc_interpreter::ppc_subfme(); +template void dppc_interpreter::ppc_subfme(uint32_t opcode); +template void dppc_interpreter::ppc_subfme(uint32_t opcode); +template void dppc_interpreter::ppc_subfme(uint32_t opcode); +template void dppc_interpreter::ppc_subfme(uint32_t opcode); template -void dppc_interpreter::ppc_subfze() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::ppc_subfze(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); uint32_t ppc_result_d = ~ppc_result_a + grab_ca; @@ -328,45 +328,45 @@ void dppc_interpreter::ppc_subfze() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_subfze(); -template void dppc_interpreter::ppc_subfze(); -template void dppc_interpreter::ppc_subfze(); -template void dppc_interpreter::ppc_subfze(); +template void dppc_interpreter::ppc_subfze(uint32_t opcode); +template void dppc_interpreter::ppc_subfze(uint32_t opcode); +template void dppc_interpreter::ppc_subfze(uint32_t opcode); +template void dppc_interpreter::ppc_subfze(uint32_t opcode); template -void dppc_interpreter::ppc_andirc() { - ppc_grab_regssauimm(ppc_cur_instruction); +void dppc_interpreter::ppc_andirc(uint32_t opcode) { + ppc_grab_regssauimm(opcode); ppc_result_a = shift ? (ppc_result_d & (uimm << 16)) : (ppc_result_d & uimm); ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_andirc(); -template void dppc_interpreter::ppc_andirc(); +template void dppc_interpreter::ppc_andirc(uint32_t opcode); +template void dppc_interpreter::ppc_andirc(uint32_t opcode); template -void dppc_interpreter::ppc_ori() { - ppc_grab_regssauimm(ppc_cur_instruction); +void dppc_interpreter::ppc_ori(uint32_t opcode) { + ppc_grab_regssauimm(opcode); ppc_result_a = shift ? (ppc_result_d | (uimm << 16)) : (ppc_result_d | uimm); ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_ori(); -template void dppc_interpreter::ppc_ori(); +template void dppc_interpreter::ppc_ori(uint32_t opcode); +template void dppc_interpreter::ppc_ori(uint32_t opcode); template -void dppc_interpreter::ppc_xori() { - ppc_grab_regssauimm(ppc_cur_instruction); +void dppc_interpreter::ppc_xori(uint32_t opcode) { + ppc_grab_regssauimm(opcode); ppc_result_a = shift ? (ppc_result_d ^ (uimm << 16)) : (ppc_result_d ^ uimm); ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_xori(); -template void dppc_interpreter::ppc_xori(); +template void dppc_interpreter::ppc_xori(uint32_t opcode); +template void dppc_interpreter::ppc_xori(uint32_t opcode); template -void dppc_interpreter::ppc_logical() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::ppc_logical(uint32_t opcode) { + ppc_grab_regssab(opcode); if (logical_op == logical_fun::ppc_and) ppc_result_a = ppc_result_d & ppc_result_b; else if (logical_op == logical_fun::ppc_andc) @@ -390,26 +390,26 @@ void dppc_interpreter::ppc_logical() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); -template void dppc_interpreter::ppc_logical(); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); +template void dppc_interpreter::ppc_logical(uint32_t opcode); template -void dppc_interpreter::ppc_neg() { - ppc_grab_regsda(ppc_cur_instruction); +void dppc_interpreter::ppc_neg(uint32_t opcode) { + ppc_grab_regsda(opcode); uint32_t ppc_result_d = ~(ppc_result_a) + 1; if (ov) { @@ -425,14 +425,14 @@ void dppc_interpreter::ppc_neg() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_neg(); -template void dppc_interpreter::ppc_neg(); -template void dppc_interpreter::ppc_neg(); -template void dppc_interpreter::ppc_neg(); +template void dppc_interpreter::ppc_neg(uint32_t opcode); +template void dppc_interpreter::ppc_neg(uint32_t opcode); +template void dppc_interpreter::ppc_neg(uint32_t opcode); +template void dppc_interpreter::ppc_neg(uint32_t opcode); template -void dppc_interpreter::ppc_cntlzw() { - ppc_grab_regssa(ppc_cur_instruction); +void dppc_interpreter::ppc_cntlzw(uint32_t opcode) { + ppc_grab_regssa(opcode); uint32_t bit_check = ppc_result_d; @@ -457,12 +457,12 @@ void dppc_interpreter::ppc_cntlzw() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_cntlzw(); -template void dppc_interpreter::ppc_cntlzw(); +template void dppc_interpreter::ppc_cntlzw(uint32_t opcode); +template void dppc_interpreter::ppc_cntlzw(uint32_t opcode); template -void dppc_interpreter::ppc_mulhwu() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_mulhwu(uint32_t opcode) { + ppc_grab_regsdab(opcode); uint64_t product = uint64_t(ppc_result_a) * uint64_t(ppc_result_b); uint32_t ppc_result_d = uint32_t(product >> 32); @@ -472,12 +472,12 @@ void dppc_interpreter::ppc_mulhwu() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_mulhwu(); -template void dppc_interpreter::ppc_mulhwu(); +template void dppc_interpreter::ppc_mulhwu(uint32_t opcode); +template void dppc_interpreter::ppc_mulhwu(uint32_t opcode); template -void dppc_interpreter::ppc_mulhw() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_mulhw(uint32_t opcode) { + ppc_grab_regsdab(opcode); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(ppc_result_b)); uint32_t ppc_result_d = product >> 32; @@ -487,12 +487,12 @@ void dppc_interpreter::ppc_mulhw() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_mulhw(); -template void dppc_interpreter::ppc_mulhw(); +template void dppc_interpreter::ppc_mulhw(uint32_t opcode); +template void dppc_interpreter::ppc_mulhw(uint32_t opcode); template -void dppc_interpreter::ppc_mullw() { - ppc_grab_regsdab(ppc_cur_instruction); +void dppc_interpreter::ppc_mullw(uint32_t opcode) { + ppc_grab_regsdab(opcode); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(ppc_result_b)); if (ov) { @@ -511,22 +511,22 @@ void dppc_interpreter::ppc_mullw() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_mullw(); -template void dppc_interpreter::ppc_mullw(); -template void dppc_interpreter::ppc_mullw(); -template void dppc_interpreter::ppc_mullw(); +template void dppc_interpreter::ppc_mullw(uint32_t opcode); +template void dppc_interpreter::ppc_mullw(uint32_t opcode); +template void dppc_interpreter::ppc_mullw(uint32_t opcode); +template void dppc_interpreter::ppc_mullw(uint32_t opcode); -void dppc_interpreter::ppc_mulli() { - ppc_grab_regsdasimm(ppc_cur_instruction); +void dppc_interpreter::ppc_mulli(uint32_t opcode) { + ppc_grab_regsdasimm(opcode); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(simm)); uint32_t ppc_result_d = uint32_t(product); ppc_store_iresult_reg(reg_d, ppc_result_d); } template -void dppc_interpreter::ppc_divw() { +void dppc_interpreter::ppc_divw(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); if (!ppc_result_b) { // handle the "anything / 0" case ppc_result_d = 0; // tested on G4 in Mac OS X 10.4 and Open Firmware. @@ -554,15 +554,15 @@ void dppc_interpreter::ppc_divw() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_divw(); -template void dppc_interpreter::ppc_divw(); -template void dppc_interpreter::ppc_divw(); -template void dppc_interpreter::ppc_divw(); +template void dppc_interpreter::ppc_divw(uint32_t opcode); +template void dppc_interpreter::ppc_divw(uint32_t opcode); +template void dppc_interpreter::ppc_divw(uint32_t opcode); +template void dppc_interpreter::ppc_divw(uint32_t opcode); template -void dppc_interpreter::ppc_divwu() { +void dppc_interpreter::ppc_divwu(uint32_t opcode) { uint32_t ppc_result_d; - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); if (!ppc_result_b) { // division by zero ppc_result_d = 0; @@ -585,16 +585,16 @@ void dppc_interpreter::ppc_divwu() { ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_divwu(); -template void dppc_interpreter::ppc_divwu(); -template void dppc_interpreter::ppc_divwu(); -template void dppc_interpreter::ppc_divwu(); +template void dppc_interpreter::ppc_divwu(uint32_t opcode); +template void dppc_interpreter::ppc_divwu(uint32_t opcode); +template void dppc_interpreter::ppc_divwu(uint32_t opcode); +template void dppc_interpreter::ppc_divwu(uint32_t opcode); // Value shifting template -void dppc_interpreter::ppc_shift() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::ppc_shift(uint32_t opcode) { + ppc_grab_regssab(opcode); if (ppc_result_b & 0x20) { ppc_result_a = 0; } @@ -609,14 +609,14 @@ void dppc_interpreter::ppc_shift() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_shift(); -template void dppc_interpreter::ppc_shift(); -template void dppc_interpreter::ppc_shift(); -template void dppc_interpreter::ppc_shift(); +template void dppc_interpreter::ppc_shift(uint32_t opcode); +template void dppc_interpreter::ppc_shift(uint32_t opcode); +template void dppc_interpreter::ppc_shift(uint32_t opcode); +template void dppc_interpreter::ppc_shift(uint32_t opcode); template -void dppc_interpreter::ppc_sraw() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::ppc_sraw(uint32_t opcode) { + ppc_grab_regssab(opcode); // clear XER[CA] by default ppc_state.spr[SPR::XER] &= ~XER::CA; @@ -639,12 +639,12 @@ void dppc_interpreter::ppc_sraw() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_sraw(); -template void dppc_interpreter::ppc_sraw(); +template void dppc_interpreter::ppc_sraw(uint32_t opcode); +template void dppc_interpreter::ppc_sraw(uint32_t opcode); template -void dppc_interpreter::ppc_srawi() { - ppc_grab_regssash(ppc_cur_instruction); +void dppc_interpreter::ppc_srawi(uint32_t opcode) { + ppc_grab_regssash(opcode); // clear XER[CA] by default ppc_state.spr[SPR::XER] &= ~XER::CA; @@ -660,8 +660,8 @@ void dppc_interpreter::ppc_srawi() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_srawi(); -template void dppc_interpreter::ppc_srawi(); +template void dppc_interpreter::ppc_srawi(uint32_t opcode); +template void dppc_interpreter::ppc_srawi(uint32_t opcode); /** mask generator for rotate and shift instructions (§ 4.2.1.4 PowerpC PEM) */ static inline uint32_t rot_mask(unsigned rot_mb, unsigned rot_me) { @@ -670,78 +670,78 @@ static inline uint32_t rot_mask(unsigned rot_mb, unsigned rot_me) { return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2); } -void dppc_interpreter::ppc_rlwimi() { - ppc_grab_regssash(ppc_cur_instruction); - unsigned rot_mb = (ppc_cur_instruction >> 6) & 0x1F; - unsigned rot_me = (ppc_cur_instruction >> 1) & 0x1F; +void dppc_interpreter::ppc_rlwimi(uint32_t opcode) { + ppc_grab_regssash(opcode); + unsigned rot_mb = (opcode >> 6) & 0x1F; + unsigned rot_me = (opcode >> 1) & 0x1F; uint32_t mask = rot_mask(rot_mb, rot_me); uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d; ppc_result_a = (ppc_result_a & ~mask) | (r & mask); - if ((ppc_cur_instruction & 0x01) == 1) { + if ((opcode & 0x01) == 1) { ppc_changecrf0(ppc_result_a); } ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_rlwinm() { - ppc_grab_regssash(ppc_cur_instruction); - unsigned rot_mb = (ppc_cur_instruction >> 6) & 0x1F; - unsigned rot_me = (ppc_cur_instruction >> 1) & 0x1F; +void dppc_interpreter::ppc_rlwinm(uint32_t opcode) { + ppc_grab_regssash(opcode); + unsigned rot_mb = (opcode >> 6) & 0x1F; + unsigned rot_me = (opcode >> 1) & 0x1F; uint32_t mask = rot_mask(rot_mb, rot_me); uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d; ppc_result_a = r & mask; - if ((ppc_cur_instruction & 0x01) == 1) { + if ((opcode & 0x01) == 1) { ppc_changecrf0(ppc_result_a); } ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_rlwnm() { - ppc_grab_regssab(ppc_cur_instruction); +void dppc_interpreter::ppc_rlwnm(uint32_t opcode) { + ppc_grab_regssab(opcode); ppc_result_b &= 0x1F; - unsigned rot_mb = (ppc_cur_instruction >> 6) & 0x1F; - unsigned rot_me = (ppc_cur_instruction >> 1) & 0x1F; + unsigned rot_mb = (opcode >> 6) & 0x1F; + unsigned rot_me = (opcode >> 1) & 0x1F; uint32_t mask = rot_mask(rot_mb, rot_me); uint32_t rot = ppc_result_b & 0x1F; uint32_t r = rot ? ((ppc_result_d << rot) | (ppc_result_d >> (32 - rot))) : ppc_result_d; ppc_result_a = r & mask; - if ((ppc_cur_instruction & 0x01) == 1) { + if ((opcode & 0x01) == 1) { ppc_changecrf0(ppc_result_a); } ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_mfcr() { - int reg_d = (ppc_cur_instruction >> 21) & 0x1F; +void dppc_interpreter::ppc_mfcr(uint32_t opcode) { + int reg_d = (opcode >> 21) & 0x1F; ppc_state.gpr[reg_d] = ppc_state.cr; } -void dppc_interpreter::ppc_mtsr() { +void dppc_interpreter::ppc_mtsr(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - int reg_s = (ppc_cur_instruction >> 21) & 0x1F; - uint32_t grab_sr = (ppc_cur_instruction >> 16) & 0x0F; + int reg_s = (opcode >> 21) & 0x1F; + uint32_t grab_sr = (opcode >> 16) & 0x0F; if (ppc_state.sr[grab_sr] != ppc_state.gpr[reg_s]) { ppc_state.sr[grab_sr] = ppc_state.gpr[reg_s]; mmu_pat_ctx_changed(); } } -void dppc_interpreter::ppc_mtsrin() { +void dppc_interpreter::ppc_mtsrin(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - ppc_grab_regssb(ppc_cur_instruction); + ppc_grab_regssb(opcode); uint32_t grab_sr = ppc_result_b >> 28; if (ppc_state.sr[grab_sr] != ppc_result_d) { ppc_state.sr[grab_sr] = ppc_result_d; @@ -749,49 +749,49 @@ void dppc_interpreter::ppc_mtsrin() { } } -void dppc_interpreter::ppc_mfsr() { +void dppc_interpreter::ppc_mfsr(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - int reg_d = (ppc_cur_instruction >> 21) & 0x1F; - uint32_t grab_sr = (ppc_cur_instruction >> 16) & 0x0F; + int reg_d = (opcode >> 21) & 0x1F; + uint32_t grab_sr = (opcode >> 16) & 0x0F; ppc_state.gpr[reg_d] = ppc_state.sr[grab_sr]; } -void dppc_interpreter::ppc_mfsrin() { +void dppc_interpreter::ppc_mfsrin(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - ppc_grab_regsdb(ppc_cur_instruction); + ppc_grab_regsdb(opcode); uint32_t grab_sr = ppc_result_b >> 28; ppc_state.gpr[reg_d] = ppc_state.sr[grab_sr]; } -void dppc_interpreter::ppc_mfmsr() { +void dppc_interpreter::ppc_mfmsr(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - uint32_t reg_d = (ppc_cur_instruction >> 21) & 0x1F; + uint32_t reg_d = (opcode >> 21) & 0x1F; ppc_state.gpr[reg_d] = ppc_state.msr; } -void dppc_interpreter::ppc_mtmsr() { +void dppc_interpreter::ppc_mtmsr(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif if (ppc_state.msr & MSR::PR) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } - uint32_t reg_s = (ppc_cur_instruction >> 21) & 0x1F; + uint32_t reg_s = (opcode >> 21) & 0x1F; ppc_state.msr = ppc_state.gpr[reg_s]; // generate External Interrupt Exception @@ -888,8 +888,8 @@ static void update_decrementer(uint32_t val) { ); } -void dppc_interpreter::ppc_mfspr() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_mfspr(uint32_t opcode) { + ppc_grab_dab(opcode); uint32_t ref_spr = (reg_b << 5) | reg_a; if (ref_spr & 0x10) { @@ -940,8 +940,8 @@ void dppc_interpreter::ppc_mfspr() { } } -void dppc_interpreter::ppc_mtspr() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_mtspr(uint32_t opcode) { + ppc_grab_dab(opcode); uint32_t ref_spr = (reg_b << 5) | reg_a; if (ref_spr & 0x10) { @@ -1031,8 +1031,8 @@ void dppc_interpreter::ppc_mtspr() { } } -void dppc_interpreter::ppc_mftb() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_mftb(uint32_t opcode) { + ppc_grab_dab(opcode); uint32_t ref_spr = (reg_b << 5) | reg_a; uint64_t tbr_value = calc_tbr_value(); @@ -1053,9 +1053,9 @@ void dppc_interpreter::ppc_mftb() { } } -void dppc_interpreter::ppc_mtcrf() { - ppc_grab_s(ppc_cur_instruction); - uint8_t crm = (ppc_cur_instruction >> 12) & 0xFFU; +void dppc_interpreter::ppc_mtcrf(uint32_t opcode) { + ppc_grab_s(opcode); + uint8_t crm = (opcode >> 12) & 0xFFU; uint32_t cr_mask = 0; @@ -1074,16 +1074,16 @@ void dppc_interpreter::ppc_mtcrf() { ppc_state.cr = (ppc_state.cr & ~cr_mask) | (ppc_result_d & cr_mask); } -void dppc_interpreter::ppc_mcrxr() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; +void dppc_interpreter::ppc_mcrxr(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1C; ppc_state.cr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) | ((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d); ppc_state.spr[SPR::XER] &= 0x0FFFFFFF; } template -void dppc_interpreter::ppc_exts() { - ppc_grab_regssa(ppc_cur_instruction); +void dppc_interpreter::ppc_exts(uint32_t opcode) { + ppc_grab_regssa(opcode); ppc_result_a = int32_t(T(ppc_result_d)); if (rec) @@ -1092,16 +1092,16 @@ void dppc_interpreter::ppc_exts() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_exts(); -template void dppc_interpreter::ppc_exts(); -template void dppc_interpreter::ppc_exts(); -template void dppc_interpreter::ppc_exts(); +template void dppc_interpreter::ppc_exts(uint32_t opcode); +template void dppc_interpreter::ppc_exts(uint32_t opcode); +template void dppc_interpreter::ppc_exts(uint32_t opcode); +template void dppc_interpreter::ppc_exts(uint32_t opcode); // Branching Instructions template -void dppc_interpreter::ppc_b() { - int32_t adr_li = int32_t((ppc_cur_instruction & ~3UL) << 6) >> 6; +void dppc_interpreter::ppc_b(uint32_t opcode) { + int32_t adr_li = int32_t((opcode & ~3UL) << 6) >> 6; if (a) ppc_next_instruction_address = adr_li; @@ -1114,18 +1114,18 @@ void dppc_interpreter::ppc_b() { exec_flags = EXEF_BRANCH; } -template void dppc_interpreter::ppc_b(); -template void dppc_interpreter::ppc_b(); -template void dppc_interpreter::ppc_b(); -template void dppc_interpreter::ppc_b(); +template void dppc_interpreter::ppc_b(uint32_t opcode); +template void dppc_interpreter::ppc_b(uint32_t opcode); +template void dppc_interpreter::ppc_b(uint32_t opcode); +template void dppc_interpreter::ppc_b(uint32_t opcode); template -void dppc_interpreter::ppc_bc() { +void dppc_interpreter::ppc_bc(uint32_t opcode) { uint32_t ctr_ok; uint32_t cnd_ok; - uint32_t br_bo = (ppc_cur_instruction >> 21) & 0x1F; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 0x1F; - int32_t br_bd = int32_t(int16_t(ppc_cur_instruction & ~3UL)); + uint32_t br_bo = (opcode >> 21) & 0x1F; + uint32_t br_bi = (opcode >> 16) & 0x1F; + int32_t br_bd = int32_t(int16_t(opcode & ~3UL)); if (!(br_bo & 0x04)) { (ppc_state.spr[SPR::CTR])--; /* decrement CTR */ @@ -1145,17 +1145,17 @@ void dppc_interpreter::ppc_bc() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -template void dppc_interpreter::ppc_bc(); -template void dppc_interpreter::ppc_bc(); -template void dppc_interpreter::ppc_bc(); -template void dppc_interpreter::ppc_bc(); +template void dppc_interpreter::ppc_bc(uint32_t opcode); +template void dppc_interpreter::ppc_bc(uint32_t opcode); +template void dppc_interpreter::ppc_bc(uint32_t opcode); +template void dppc_interpreter::ppc_bc(uint32_t opcode); template -void dppc_interpreter::ppc_bcctr() { +void dppc_interpreter::ppc_bcctr(uint32_t opcode) { uint32_t ctr_ok; uint32_t cnd_ok; - uint32_t br_bo = (ppc_cur_instruction >> 21) & 0x1F; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 0x1F; + uint32_t br_bo = (opcode >> 21) & 0x1F; + uint32_t br_bi = (opcode >> 16) & 0x1F; uint32_t ctr = ppc_state.spr[SPR::CTR]; uint32_t new_ctr; @@ -1180,15 +1180,15 @@ void dppc_interpreter::ppc_bcctr() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -template void dppc_interpreter::ppc_bcctr(); -template void dppc_interpreter::ppc_bcctr(); -template void dppc_interpreter::ppc_bcctr(); -template void dppc_interpreter::ppc_bcctr(); +template void dppc_interpreter::ppc_bcctr(uint32_t opcode); +template void dppc_interpreter::ppc_bcctr(uint32_t opcode); +template void dppc_interpreter::ppc_bcctr(uint32_t opcode); +template void dppc_interpreter::ppc_bcctr(uint32_t opcode); template -void dppc_interpreter::ppc_bclr() { - uint32_t br_bo = (ppc_cur_instruction >> 21) & 0x1F; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 0x1F; +void dppc_interpreter::ppc_bclr(uint32_t opcode) { + uint32_t br_bo = (opcode >> 21) & 0x1F; + uint32_t br_bi = (opcode >> 16) & 0x1F; uint32_t ctr_ok; uint32_t cnd_ok; @@ -1207,67 +1207,67 @@ void dppc_interpreter::ppc_bclr() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -template void dppc_interpreter::ppc_bclr(); -template void dppc_interpreter::ppc_bclr(); +template void dppc_interpreter::ppc_bclr(uint32_t opcode); +template void dppc_interpreter::ppc_bclr(uint32_t opcode); // Compare Instructions -void dppc_interpreter::ppc_cmp() { +void dppc_interpreter::ppc_cmp(uint32_t opcode) { #ifdef CHECK_INVALID - if (ppc_cur_instruction & 0x200000) { + if (opcode & 0x200000) { LOG_F(WARNING, "Invalid CMP instruction form (L=1)!"); return; } #endif - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - ppc_grab_regsab(ppc_cur_instruction); + int crf_d = (opcode >> 21) & 0x1C; + ppc_grab_regsab(opcode); uint32_t xercon = (ppc_state.spr[SPR::XER] & XER::SO) >> 3; uint32_t cmp_c = (int32_t(ppc_result_a) == int32_t(ppc_result_b)) ? 0x20000000UL : \ (int32_t(ppc_result_a) > int32_t(ppc_result_b)) ? 0x40000000UL : 0x80000000UL; ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void dppc_interpreter::ppc_cmpi() { +void dppc_interpreter::ppc_cmpi(uint32_t opcode) { #ifdef CHECK_INVALID - if (ppc_cur_instruction & 0x200000) { + if (opcode & 0x200000) { LOG_F(WARNING, "Invalid CMPI instruction form (L=1)!"); return; } #endif - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - ppc_grab_regsasimm(ppc_cur_instruction); + int crf_d = (opcode >> 21) & 0x1C; + ppc_grab_regsasimm(opcode); uint32_t xercon = (ppc_state.spr[SPR::XER] & XER::SO) >> 3; uint32_t cmp_c = (int32_t(ppc_result_a) == simm) ? 0x20000000UL : \ (int32_t(ppc_result_a) > simm) ? 0x40000000UL : 0x80000000UL; ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void dppc_interpreter::ppc_cmpl() { +void dppc_interpreter::ppc_cmpl(uint32_t opcode) { #ifdef CHECK_INVALID - if (ppc_cur_instruction & 0x200000) { + if (opcode & 0x200000) { LOG_F(WARNING, "Invalid CMPL instruction form (L=1)!"); return; } #endif - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - ppc_grab_regsab(ppc_cur_instruction); + int crf_d = (opcode >> 21) & 0x1C; + ppc_grab_regsab(opcode); uint32_t xercon = (ppc_state.spr[SPR::XER] & XER::SO) >> 3; uint32_t cmp_c = (ppc_result_a == ppc_result_b) ? 0x20000000UL : \ (ppc_result_a > ppc_result_b) ? 0x40000000UL : 0x80000000UL; ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void dppc_interpreter::ppc_cmpli() { +void dppc_interpreter::ppc_cmpli(uint32_t opcode) { #ifdef CHECK_INVALID - if (ppc_cur_instruction & 0x200000) { + if (opcode & 0x200000) { LOG_F(WARNING, "Invalid CMPLI instruction form (L=1)!"); return; } #endif - ppc_grab_crfd_regsauimm(ppc_cur_instruction); + ppc_grab_crfd_regsauimm(opcode); uint32_t xercon = (ppc_state.spr[SPR::XER] & XER::SO) >> 3; uint32_t cmp_c = (ppc_result_a == uimm) ? 0x20000000UL : \ (ppc_result_a > uimm) ? 0x40000000UL : 0x80000000UL; @@ -1276,9 +1276,9 @@ void dppc_interpreter::ppc_cmpli() { // Condition Register Changes -void dppc_interpreter::ppc_mcrf() { - int crf_d = (ppc_cur_instruction >> 21) & 0x1C; - int crf_s = (ppc_cur_instruction >> 16) & 0x1C; +void dppc_interpreter::ppc_mcrf(uint32_t opcode) { + int crf_d = (opcode >> 21) & 0x1C; + int crf_s = (opcode >> 16) & 0x1C; // extract and right justify source flags field uint32_t grab_s = (ppc_state.cr >> (28 - crf_s)) & 0xF; @@ -1286,8 +1286,8 @@ void dppc_interpreter::ppc_mcrf() { ppc_state.cr = (ppc_state.cr & ~(0xf0000000UL >> crf_d)) | (grab_s << (28 - crf_d)); } -void dppc_interpreter::ppc_crand() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crand(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) & (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1296,16 +1296,16 @@ void dppc_interpreter::ppc_crand() { } } -void dppc_interpreter::ppc_crandc() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crandc(uint32_t opcode) { + ppc_grab_dab(opcode); if ((ppc_state.cr & (0x80000000UL >> reg_a)) && !(ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); } else { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void dppc_interpreter::ppc_creqv() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_creqv(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) ^ (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { // compliment is implemented by swapping the following if/else bodies ppc_state.cr &= ~(0x80000000UL >> reg_d); @@ -1313,8 +1313,8 @@ void dppc_interpreter::ppc_creqv() { ppc_state.cr |= (0x80000000UL >> reg_d); } } -void dppc_interpreter::ppc_crnand() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crnand(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) & (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { ppc_state.cr &= ~(0x80000000UL >> reg_d); @@ -1323,8 +1323,8 @@ void dppc_interpreter::ppc_crnand() { } } -void dppc_interpreter::ppc_crnor() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crnor(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) | (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { ppc_state.cr &= ~(0x80000000UL >> reg_d); @@ -1333,8 +1333,8 @@ void dppc_interpreter::ppc_crnor() { } } -void dppc_interpreter::ppc_cror() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_cror(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) | (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1343,16 +1343,16 @@ void dppc_interpreter::ppc_cror() { } } -void dppc_interpreter::ppc_crorc() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crorc(uint32_t opcode) { + ppc_grab_dab(opcode); if ((ppc_state.cr & (0x80000000UL >> reg_a)) || !(ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); } else { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void dppc_interpreter::ppc_crxor() { - ppc_grab_dab(ppc_cur_instruction); +void dppc_interpreter::ppc_crxor(uint32_t opcode) { + ppc_grab_dab(opcode); uint8_t ir = (ppc_state.cr >> (31 - reg_a)) ^ (ppc_state.cr >> (31 - reg_b)); if (ir & 1) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1363,7 +1363,7 @@ void dppc_interpreter::ppc_crxor() { // Processor MGMT Fns. -void dppc_interpreter::ppc_rfi() { +void dppc_interpreter::ppc_rfi(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif @@ -1398,15 +1398,15 @@ void dppc_interpreter::ppc_rfi() { exec_flags = EXEF_RFI; } -void dppc_interpreter::ppc_sc() { +void dppc_interpreter::ppc_sc(uint32_t opcode) { do_ctx_sync(); // SC is context synchronizing! ppc_exception_handler(Except_Type::EXC_SYSCALL, 0x20000); } -void dppc_interpreter::ppc_tw() { - uint32_t reg_a = (ppc_cur_instruction >> 11) & 0x1F; - uint32_t reg_b = (ppc_cur_instruction >> 16) & 0x1F; - uint32_t ppc_to = (ppc_cur_instruction >> 21) & 0x1F; +void dppc_interpreter::ppc_tw(uint32_t opcode) { + uint32_t reg_a = (opcode >> 11) & 0x1F; + uint32_t reg_b = (opcode >> 16) & 0x1F; + uint32_t ppc_to = (opcode >> 21) & 0x1F; if (((int32_t(ppc_state.gpr[reg_a]) < int32_t(ppc_state.gpr[reg_b])) && (ppc_to & 0x10)) || ((int32_t(ppc_state.gpr[reg_a]) > int32_t(ppc_state.gpr[reg_b])) && (ppc_to & 0x08)) || ((int32_t(ppc_state.gpr[reg_a]) == int32_t(ppc_state.gpr[reg_b])) && (ppc_to & 0x04)) || @@ -1416,10 +1416,10 @@ void dppc_interpreter::ppc_tw() { } } -void dppc_interpreter::ppc_twi() { - int32_t simm = int32_t(int16_t(ppc_cur_instruction)); - uint32_t reg_a = (ppc_cur_instruction >> 16) & 0x1F; - uint32_t ppc_to = (ppc_cur_instruction >> 21) & 0x1F; +void dppc_interpreter::ppc_twi(uint32_t opcode) { + int32_t simm = int32_t(int16_t(opcode)); + uint32_t reg_a = (opcode >> 16) & 0x1F; + uint32_t ppc_to = (opcode >> 21) & 0x1F; if (((int32_t(ppc_state.gpr[reg_a]) < simm) && (ppc_to & 0x10)) || ((int32_t(ppc_state.gpr[reg_a]) > simm) && (ppc_to & 0x08)) || ((int32_t(ppc_state.gpr[reg_a]) == simm) && (ppc_to & 0x04)) || @@ -1429,212 +1429,212 @@ void dppc_interpreter::ppc_twi() { } } -void dppc_interpreter::ppc_eieio() { +void dppc_interpreter::ppc_eieio(uint32_t opcode) { /* placeholder */ } -void dppc_interpreter::ppc_isync() { +void dppc_interpreter::ppc_isync(uint32_t opcode) { do_ctx_sync(); } -void dppc_interpreter::ppc_sync() { +void dppc_interpreter::ppc_sync(uint32_t opcode) { /* placeholder */ } -void dppc_interpreter::ppc_icbi() { +void dppc_interpreter::ppc_icbi(uint32_t opcode) { /* placeholder */ } -void dppc_interpreter::ppc_dcbf() { +void dppc_interpreter::ppc_dcbf(uint32_t opcode) { /* placeholder */ } -void dppc_interpreter::ppc_dcbi() { +void dppc_interpreter::ppc_dcbi(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif /* placeholder */ } -void dppc_interpreter::ppc_dcbst() { +void dppc_interpreter::ppc_dcbst(uint32_t opcode) { /* placeholder */ } -void dppc_interpreter::ppc_dcbt() { +void dppc_interpreter::ppc_dcbt(uint32_t opcode) { // Not needed, the HDI reg is touched to no-op this instruction. return; } -void dppc_interpreter::ppc_dcbtst() { +void dppc_interpreter::ppc_dcbtst(uint32_t opcode) { // Not needed, the HDI reg is touched to no-op this instruction. return; } -void dppc_interpreter::ppc_dcbz() { - ppc_grab_regsab(ppc_cur_instruction); +void dppc_interpreter::ppc_dcbz(uint32_t opcode) { + ppc_grab_regsab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); ea &= 0xFFFFFFE0UL; // align EA on a 32-byte boundary // the following is not especially efficient but necessary // to make BlockZero under Mac OS 8.x and later to work - mmu_write_vmem(ea + 0, 0); - mmu_write_vmem(ea + 8, 0); - mmu_write_vmem(ea + 16, 0); - mmu_write_vmem(ea + 24, 0); + mmu_write_vmem(opcode, ea + 0, 0); + mmu_write_vmem(opcode, ea + 8, 0); + mmu_write_vmem(opcode, ea + 16, 0); + mmu_write_vmem(opcode, ea + 24, 0); } // Integer Load and Store Functions template -void dppc_interpreter::ppc_st() { +void dppc_interpreter::ppc_st(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssa(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regssa(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += reg_a ? ppc_result_a : 0; - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); } -template void dppc_interpreter::ppc_st(); -template void dppc_interpreter::ppc_st(); -template void dppc_interpreter::ppc_st(); +template void dppc_interpreter::ppc_st(uint32_t opcode); +template void dppc_interpreter::ppc_st(uint32_t opcode); +template void dppc_interpreter::ppc_st(uint32_t opcode); template -void dppc_interpreter::ppc_stx() { +void dppc_interpreter::ppc_stx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); } -template void dppc_interpreter::ppc_stx(); -template void dppc_interpreter::ppc_stx(); -template void dppc_interpreter::ppc_stx(); +template void dppc_interpreter::ppc_stx(uint32_t opcode); +template void dppc_interpreter::ppc_stx(uint32_t opcode); +template void dppc_interpreter::ppc_stx(uint32_t opcode); template -void dppc_interpreter::ppc_stu() { +void dppc_interpreter::ppc_stu(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssa(ppc_cur_instruction); + ppc_grab_regssa(opcode); if (reg_a != 0) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += ppc_result_a; - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -template void dppc_interpreter::ppc_stu(); -template void dppc_interpreter::ppc_stu(); -template void dppc_interpreter::ppc_stu(); +template void dppc_interpreter::ppc_stu(uint32_t opcode); +template void dppc_interpreter::ppc_stu(uint32_t opcode); +template void dppc_interpreter::ppc_stu(uint32_t opcode); template -void dppc_interpreter::ppc_stux() { +void dppc_interpreter::ppc_stux(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); if (reg_a != 0) { uint32_t ea = ppc_result_a + ppc_result_b; - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); ppc_state.gpr[reg_a] = ea; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -template void dppc_interpreter::ppc_stux(); -template void dppc_interpreter::ppc_stux(); -template void dppc_interpreter::ppc_stux(); +template void dppc_interpreter::ppc_stux(uint32_t opcode); +template void dppc_interpreter::ppc_stux(uint32_t opcode); +template void dppc_interpreter::ppc_stux(uint32_t opcode); -void dppc_interpreter::ppc_sthbrx() { +void dppc_interpreter::ppc_sthbrx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_result_d = uint32_t(BYTESWAP_16(uint16_t(ppc_result_d))); - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); } -void dppc_interpreter::ppc_stwcx() { +void dppc_interpreter::ppc_stwcx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); uint32_t ea = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_state.cr &= 0x0FFFFFFFUL; // clear CR0 ppc_state.cr |= (ppc_state.spr[SPR::XER] & XER::SO) >> 3; // copy XER[SO] to CR0[SO] if (ppc_state.reserve) { - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); ppc_state.reserve = false; ppc_state.cr |= 0x20000000UL; // set CR0[EQ] } } -void dppc_interpreter::ppc_stwbrx() { +void dppc_interpreter::ppc_stwbrx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_result_d = BYTESWAP_32(ppc_result_d); - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); } -void dppc_interpreter::ppc_stmw() { +void dppc_interpreter::ppc_stmw(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssa_stmw(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regssa_stmw(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += reg_a ? ppc_result_a : 0; /* what should we do if EA is unaligned? */ if (ea & 3) { - ppc_alignment_exception(ea); + ppc_alignment_exception(opcode, ea); } for (; reg_s <= 31; reg_s++) { - mmu_write_vmem(ea, ppc_state.gpr[reg_s]); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s]); ea += 4; } } template -void dppc_interpreter::ppc_lz() { +void dppc_interpreter::ppc_lz(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regsda(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += reg_a ? ppc_result_a : 0; - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_lz(); -template void dppc_interpreter::ppc_lz(); -template void dppc_interpreter::ppc_lz(); +template void dppc_interpreter::ppc_lz(uint32_t opcode); +template void dppc_interpreter::ppc_lz(uint32_t opcode); +template void dppc_interpreter::ppc_lz(uint32_t opcode); template -void dppc_interpreter::ppc_lzu() { +void dppc_interpreter::ppc_lzu(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regsda(opcode); + uint32_t ea = int32_t(int16_t(opcode)); if ((reg_a != reg_d) && reg_a != 0) { ea += ppc_result_a; - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); uint32_t ppc_result_a = ea; ppc_store_iresult_reg(reg_d, ppc_result_d); ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1643,34 +1643,34 @@ void dppc_interpreter::ppc_lzu() { } } -template void dppc_interpreter::ppc_lzu(); -template void dppc_interpreter::ppc_lzu(); -template void dppc_interpreter::ppc_lzu(); +template void dppc_interpreter::ppc_lzu(uint32_t opcode); +template void dppc_interpreter::ppc_lzu(uint32_t opcode); +template void dppc_interpreter::ppc_lzu(uint32_t opcode); template -void dppc_interpreter::ppc_lzx() { +void dppc_interpreter::ppc_lzx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, ppc_result_d); } -template void dppc_interpreter::ppc_lzx(void); -template void dppc_interpreter::ppc_lzx(void); -template void dppc_interpreter::ppc_lzx(void); +template void dppc_interpreter::ppc_lzx(uint32_t opcode); +template void dppc_interpreter::ppc_lzx(uint32_t opcode); +template void dppc_interpreter::ppc_lzx(uint32_t opcode); template -void dppc_interpreter::ppc_lzux() { +void dppc_interpreter::ppc_lzux(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); if ((reg_a != reg_d) && reg_a != 0) { uint32_t ea = ppc_result_a + ppc_result_b; - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); ppc_result_a = ea; ppc_store_iresult_reg(reg_d, ppc_result_d); ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1679,30 +1679,30 @@ void dppc_interpreter::ppc_lzux() { } } -template void dppc_interpreter::ppc_lzux(void); -template void dppc_interpreter::ppc_lzux(void); -template void dppc_interpreter::ppc_lzux(void); +template void dppc_interpreter::ppc_lzux(uint32_t opcode); +template void dppc_interpreter::ppc_lzux(uint32_t opcode); +template void dppc_interpreter::ppc_lzux(uint32_t opcode); -void dppc_interpreter::ppc_lha() { +void dppc_interpreter::ppc_lha(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regsda(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a ? ppc_result_a : 0); - int16_t val = mmu_read_vmem(ea); + int16_t val = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, int32_t(val)); } -void dppc_interpreter::ppc_lhau() { +void dppc_interpreter::ppc_lhau(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); + ppc_grab_regsda(opcode); if ((reg_a != reg_d) && reg_a != 0) { - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + uint32_t ea = int32_t(int16_t(opcode)); ea += ppc_result_a; - int16_t val = mmu_read_vmem(ea); + int16_t val = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, int32_t(val)); uint32_t ppc_result_a = ea; ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1711,14 +1711,14 @@ void dppc_interpreter::ppc_lhau() { } } -void dppc_interpreter::ppc_lhaux() { +void dppc_interpreter::ppc_lhaux(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); if ((reg_a != reg_d) && reg_a != 0) { uint32_t ea = ppc_result_a + ppc_result_b; - int16_t val = mmu_read_vmem(ea); + int16_t val = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, int32_t(val)); uint32_t ppc_result_a = ea; ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1728,74 +1728,74 @@ void dppc_interpreter::ppc_lhaux() { } } -void dppc_interpreter::ppc_lhax() { +void dppc_interpreter::ppc_lhax(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); - int16_t val = mmu_read_vmem(ea); + int16_t val = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, int32_t(val)); } -void dppc_interpreter::ppc_lhbrx() { +void dppc_interpreter::ppc_lhbrx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); - uint32_t ppc_result_d = uint32_t(BYTESWAP_16(mmu_read_vmem(ea))); + uint32_t ppc_result_d = uint32_t(BYTESWAP_16(mmu_read_vmem(opcode, ea))); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lwbrx() { +void dppc_interpreter::ppc_lwbrx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); - uint32_t ppc_result_d = BYTESWAP_32(mmu_read_vmem(ea)); + uint32_t ppc_result_d = BYTESWAP_32(mmu_read_vmem(opcode, ea)); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lwarx() { +void dppc_interpreter::ppc_lwarx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif // Placeholder - Get the reservation of memory implemented! - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_state.reserve = true; - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lmw() { +void dppc_interpreter::ppc_lmw(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); - uint32_t ea = int32_t(int16_t(ppc_cur_instruction)); + ppc_grab_regsda(opcode); + uint32_t ea = int32_t(int16_t(opcode)); ea += (reg_a ? ppc_result_a : 0); // How many words to load in memory - using a do-while for this do { - ppc_state.gpr[reg_d] = mmu_read_vmem(ea); + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea); ea += 4; reg_d++; } while (reg_d < 32); } -void dppc_interpreter::ppc_lswi() { +void dppc_interpreter::ppc_lswi(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsda(ppc_cur_instruction); + ppc_grab_regsda(opcode); uint32_t ea = reg_a ? ppc_result_a : 0; - uint32_t grab_inb = (ppc_cur_instruction >> 11) & 0x1F; + uint32_t grab_inb = (opcode >> 11) & 0x1F; grab_inb = grab_inb ? grab_inb : 32; while (grab_inb >= 4) { - ppc_state.gpr[reg_d] = mmu_read_vmem(ea); + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea); reg_d++; if (reg_d >= 32) { // wrap around through GPR0 reg_d = 0; @@ -1807,25 +1807,25 @@ void dppc_interpreter::ppc_lswi() { // handle remaining bytes switch (grab_inb) { case 1: - ppc_state.gpr[reg_d] = mmu_read_vmem(ea) << 24; + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea) << 24; break; case 2: - ppc_state.gpr[reg_d] = mmu_read_vmem(ea) << 16; + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea) << 16; break; case 3: - ppc_state.gpr[reg_d] = mmu_read_vmem(ea) << 16; - ppc_state.gpr[reg_d] += mmu_read_vmem(ea + 2) << 8; + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea) << 16; + ppc_state.gpr[reg_d] += mmu_read_vmem(opcode, ea + 2) << 8; break; default: break; } } -void dppc_interpreter::ppc_lswx() { +void dppc_interpreter::ppc_lswx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_loads++; #endif - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); /* // Invalid instruction forms @@ -1848,33 +1848,33 @@ void dppc_interpreter::ppc_lswx() { case 0: return; case 1: - ppc_state.gpr[reg_d] = mmu_read_vmem(ea) << 24; + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea) << 24; return; case 2: - ppc_state.gpr[reg_d] = mmu_read_vmem(ea) << 16; + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea) << 16; return; case 3: - ppc_state.gpr[reg_d] = (mmu_read_vmem(ea) << 16) - | (mmu_read_vmem(ea + 2) << 8); + ppc_state.gpr[reg_d] = (mmu_read_vmem(opcode, ea) << 16) + | (mmu_read_vmem(opcode, ea + 2) << 8); return; } - ppc_state.gpr[reg_d] = mmu_read_vmem(ea); + ppc_state.gpr[reg_d] = mmu_read_vmem(opcode, ea); reg_d = (reg_d + 1) & 0x1F; // wrap around through GPR0 ea += 4; grab_inb -= 4; } } -void dppc_interpreter::ppc_stswi() { +void dppc_interpreter::ppc_stswi(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssash_stswi(ppc_cur_instruction); + ppc_grab_regssash_stswi(opcode); uint32_t ea = reg_a ? ppc_result_a : 0; uint32_t grab_inb = rot_sh ? rot_sh : 32; while (grab_inb >= 4) { - mmu_write_vmem(ea, ppc_state.gpr[reg_s]); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s]); reg_s++; if (reg_s >= 32) { // wrap around through GPR0 reg_s = 0; @@ -1886,30 +1886,30 @@ void dppc_interpreter::ppc_stswi() { // handle remaining bytes switch (grab_inb) { case 1: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 24); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 24); break; case 2: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 16); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 16); break; case 3: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 16); - mmu_write_vmem(ea + 2, (ppc_state.gpr[reg_s] >> 8) & 0xFF); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 16); + mmu_write_vmem(opcode, ea + 2, (ppc_state.gpr[reg_s] >> 8) & 0xFF); break; default: break; } } -void dppc_interpreter::ppc_stswx() { +void dppc_interpreter::ppc_stswx(uint32_t opcode) { #ifdef CPU_PROFILING num_int_stores++; #endif - ppc_grab_regssab_stswx(ppc_cur_instruction); + ppc_grab_regssab_stswx(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); uint32_t grab_inb = ppc_state.spr[SPR::XER] & 127; while (grab_inb >= 4) { - mmu_write_vmem(ea, ppc_state.gpr[reg_s]); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s]); reg_s++; if (reg_s >= 32) { // wrap around through GPR0 reg_s = 0; @@ -1921,21 +1921,21 @@ void dppc_interpreter::ppc_stswx() { // handle remaining bytes switch (grab_inb) { case 1: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 24); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 24); break; case 2: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 16); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 16); break; case 3: - mmu_write_vmem(ea, ppc_state.gpr[reg_s] >> 16); - mmu_write_vmem(ea + 2, (ppc_state.gpr[reg_s] >> 8) & 0xFF); + mmu_write_vmem(opcode, ea, ppc_state.gpr[reg_s] >> 16); + mmu_write_vmem(opcode, ea + 2, (ppc_state.gpr[reg_s] >> 8) & 0xFF); break; default: break; } } -void dppc_interpreter::ppc_eciwx() { +void dppc_interpreter::ppc_eciwx(uint32_t opcode) { uint32_t ear_enable = 0x80000000; // error if EAR[E] != 1 @@ -1943,19 +1943,19 @@ void dppc_interpreter::ppc_eciwx() { ppc_exception_handler(Except_Type::EXC_DSI, 0x0); } - ppc_grab_regsdab(ppc_cur_instruction); + ppc_grab_regsdab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); if (ea & 0x3) { - ppc_alignment_exception(ea); + ppc_alignment_exception(opcode, ea); } - uint32_t ppc_result_d = mmu_read_vmem(ea); + uint32_t ppc_result_d = mmu_read_vmem(opcode, ea); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_ecowx() { +void dppc_interpreter::ppc_ecowx(uint32_t opcode) { uint32_t ear_enable = 0x80000000; // error if EAR[E] != 1 @@ -1963,48 +1963,48 @@ void dppc_interpreter::ppc_ecowx() { ppc_exception_handler(Except_Type::EXC_DSI, 0x0); } - ppc_grab_regssab(ppc_cur_instruction); + ppc_grab_regssab(opcode); uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0); if (ea & 0x3) { - ppc_alignment_exception(ea); + ppc_alignment_exception(opcode, ea); } - mmu_write_vmem(ea, ppc_result_d); + mmu_write_vmem(opcode, ea, ppc_result_d); } // TLB Instructions -void dppc_interpreter::ppc_tlbie() { +void dppc_interpreter::ppc_tlbie(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif - tlb_flush_entry(ppc_state.gpr[(ppc_cur_instruction >> 11) & 0x1F]); + tlb_flush_entry(ppc_state.gpr[(opcode >> 11) & 0x1F]); } -void dppc_interpreter::ppc_tlbia() { +void dppc_interpreter::ppc_tlbia(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif /* placeholder */ } -void dppc_interpreter::ppc_tlbld() { +void dppc_interpreter::ppc_tlbld(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif /* placeholder */ } -void dppc_interpreter::ppc_tlbli() { +void dppc_interpreter::ppc_tlbli(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif /* placeholder */ } -void dppc_interpreter::ppc_tlbsync() { +void dppc_interpreter::ppc_tlbsync(uint32_t opcode) { #ifdef CPU_PROFILING num_supervisor_instrs++; #endif diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp index 5e014ea2fd..b925d58dd8 100644 --- a/cpu/ppc/test/ppctests.cpp +++ b/cpu/ppc/test/ppctests.cpp @@ -46,8 +46,7 @@ void xer_ov_test(string mnem, uint32_t opcode) { ppc_state.gpr[3] = 2; ppc_state.gpr[4] = 2; ppc_state.spr[SPR::XER] = 0xFFFFFFFF; - ppc_cur_instruction = opcode; - ppc_main_opcode(); + ppc_main_opcode(opcode); if (ppc_state.spr[SPR::XER] & 0x40000000UL) { cout << "Invalid " << mnem << " emulation! XER[OV] should not be set." << endl; nfailed++; @@ -151,9 +150,7 @@ static void read_test_data() { ppc_state.spr[SPR::XER] = 0; ppc_state.cr = 0; - ppc_cur_instruction = opcode; - - ppc_main_opcode(); + ppc_main_opcode(opcode); ntested++; @@ -295,9 +292,7 @@ static void read_test_float_data() { ppc_state.cr = 0; - ppc_cur_instruction = opcode; - - ppc_main_opcode(); + ppc_main_opcode(opcode); ntested++; diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index d8884b48af..61ae96a1fa 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -124,7 +124,7 @@ static uint32_t disasm_68k(uint32_t count, uint32_t address) { for (; power_on && count > 0; count--) { /* prefetch opcode bytes (a 68k instruction can occupy 2...10 bytes) */ for (int i = 0; i < sizeof(code); i++) { - code[i] = mem_read_dbg(address + i, 1); + code[i] = mem_read_dbg(0, address + i, 1); } const uint8_t *code_ptr = code; @@ -174,7 +174,7 @@ void exec_single_68k() /* calculate address of the current opcode table entry as follows: get_word(68k_PC) * entry_size + table_base */ - cur_instr_tab_entry = mmu_read_vmem(cur_68k_pc) * 8 + emu_table_virt; + cur_instr_tab_entry = mmu_read_vmem(0, cur_68k_pc) * 8 + emu_table_virt; /* grab the PPC PC too */ ppc_pc = get_reg(string("PC")); @@ -314,7 +314,7 @@ static void dump_mem(string& params) { cout << endl; chars_per_line = 0; } - val = mem_read_dbg(addr, cell_size); + val = mem_read_dbg(0, addr, cell_size); if (is_char) { cout << (char)val; chars_per_line += cell_size; diff --git a/main.cpp b/main.cpp index 39e2459152..7fdb708eb5 100644 --- a/main.cpp +++ b/main.cpp @@ -24,8 +24,9 @@ along with this program. If not, see . #include #include -#include #include +#include +#include #include #include #include @@ -253,10 +254,10 @@ void run_machine(std::string machine_str, std::string bootrom_path, uint32_t exe EventManager::get_instance()->disable_input_handlers(); // Log the PC and instruction every second to make it easier to validate // that execution is the same every time. - deterministic_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(100), [] { + deterministic_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(1000), [] { PPCDisasmContext ctx; - ctx.instr_code = ppc_cur_instruction; - ctx.instr_addr = 0; + ctx.instr_code = ppc_read_instruction(mmu_translate_imem(ppc_state.pc)); + ctx.instr_addr = ppc_state.pc; ctx.simplified = false; auto op_name = disassemble_single(&ctx); LOG_F(INFO, "TS=%016llu PC=0x%08x executing %s", get_virt_time_ns(), ppc_state.pc, op_name.c_str());