From c281b272206168abf1757a5d998f95098088ac34 Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 24 Mar 2024 12:21:19 -0700 Subject: [PATCH 1/9] Attempted templating for interpreter --- cpu/ppc/poweropcodes.cpp | 176 +++++++-- cpu/ppc/ppcemu.h | 247 ++++++------ cpu/ppc/ppcexec.cpp | 514 ++++++++++++++++--------- cpu/ppc/ppcfpopcodes.cpp | 264 +++++++++---- cpu/ppc/ppcopcodes.cpp | 798 +++++++++++++++------------------------ 5 files changed, 1104 insertions(+), 895 deletions(-) diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index 0a4ef57..08be487 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -44,24 +44,30 @@ static inline uint32_t power_rot_mask(unsigned rot_mb, unsigned rot_me) { return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2); } +template void dppc_interpreter::power_abs() { uint32_t ppc_result_d; ppc_grab_regsda(ppc_cur_instruction); if (ppc_result_a == 0x80000000) { ppc_result_d = ppc_result_a; - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] |= 0xC0000000; } else { ppc_result_d = ppc_result_a & 0x7FFFFFFF; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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(); + void dppc_interpreter::power_clcs() { uint32_t ppc_result_d; ppc_grab_regsda(ppc_cur_instruction); @@ -79,6 +85,7 @@ void dppc_interpreter::power_clcs() { ppc_store_iresult_reg(reg_d, ppc_result_d); } +template void dppc_interpreter::power_div() { uint32_t ppc_result_d; ppc_grab_regsdab(ppc_cur_instruction); @@ -94,40 +101,57 @@ void dppc_interpreter::power_div() { ppc_state.spr[SPR::MQ] = dividend % divisor; } - if (oe_flag) + if (ov) power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } +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_divs() { ppc_grab_regsdab(ppc_cur_instruction); uint32_t ppc_result_d = ppc_result_a / ppc_result_b; ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); - if (oe_flag) + if (ov) power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } +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_doz() { ppc_grab_regsdab(ppc_cur_instruction); uint32_t ppc_result_d = (int32_t(ppc_result_a) >= int32_t(ppc_result_b))\ ? 0 : ppc_result_b - ppc_result_a; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); - if (oe_flag) + if (ov) power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d); 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(); + void dppc_interpreter::power_dozi() { uint32_t ppc_result_d; ppc_grab_regsdasimm(ppc_cur_instruction); @@ -139,6 +163,7 @@ void dppc_interpreter::power_dozi() { ppc_store_iresult_reg(reg_d, ppc_result_d); } +template void dppc_interpreter::power_lscbx() { ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); @@ -182,10 +207,14 @@ void dppc_interpreter::power_lscbx() { ppc_state.spr[SPR::XER] = (ppc_state.spr[SPR::XER] & ~0x7F) | bytes_copied; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); } +template void dppc_interpreter::power_lscbx(); +template void dppc_interpreter::power_lscbx(); + +template void dppc_interpreter::power_maskg() { ppc_grab_regssab(ppc_cur_instruction); uint32_t mask_start = ppc_result_d & 31; @@ -204,22 +233,30 @@ void dppc_interpreter::power_maskg() { ppc_result_a = insert_mask; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_maskir() { ppc_grab_regssab(ppc_cur_instruction); ppc_result_a = (ppc_result_a & ~ppc_result_b) | (ppc_result_d & ppc_result_b); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_mul() { ppc_grab_regsdab(ppc_cur_instruction); uint64_t product; @@ -228,22 +265,37 @@ void dppc_interpreter::power_mul() { uint32_t ppc_result_d = ((uint32_t)(product >> 32)); ppc_state.spr[SPR::MQ] = ((uint32_t)(product)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); + if (ov) + power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d); 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_nabs() { ppc_grab_regsda(ppc_cur_instruction); uint32_t ppc_result_d = ppc_result_a & 0x80000000 ? ppc_result_a : -ppc_result_a; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); + if (ov) + ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; 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(); + void dppc_interpreter::power_rlmi() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; @@ -255,12 +307,13 @@ void dppc_interpreter::power_rlmi() { ppc_result_a = ((r & mask) | (ppc_result_a & ~mask)); - if (rc_flag) + if ((ppc_cur_instruction & 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); @@ -270,12 +323,16 @@ void dppc_interpreter::power_rrib() { ppc_result_a &= ~((ppc_result_d & 0x80000000) >> ppc_result_b); } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sle() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -285,12 +342,16 @@ void dppc_interpreter::power_sle() { ppc_store_iresult_reg(reg_a, ppc_result_a); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sleq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -300,12 +361,16 @@ void dppc_interpreter::power_sleq() { ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); ppc_state.spr[SPR::MQ] = r; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sliq() { ppc_grab_regssa(ppc_cur_instruction); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -313,12 +378,16 @@ void dppc_interpreter::power_sliq() { ppc_result_a = ppc_result_d << rot_sh; ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_slliq() { ppc_grab_regssa(ppc_cur_instruction); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -328,12 +397,16 @@ void dppc_interpreter::power_slliq() { ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); ppc_state.spr[SPR::MQ] = r; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sllq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -347,12 +420,16 @@ void dppc_interpreter::power_sllq() { ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_slq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -363,12 +440,16 @@ void dppc_interpreter::power_slq() { ppc_result_a = 0; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); } +template void dppc_interpreter::power_slq(); +template void dppc_interpreter::power_slq(); + +template void dppc_interpreter::power_sraiq() { ppc_grab_regssa(ppc_cur_instruction); unsigned rot_sh = (ppc_cur_instruction >> 11) & 0x1F; @@ -382,12 +463,16 @@ void dppc_interpreter::power_sraiq() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sraq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 0x1F; @@ -403,12 +488,16 @@ void dppc_interpreter::power_sraq() { ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sre() { ppc_grab_regssab(ppc_cur_instruction); @@ -417,12 +506,16 @@ void dppc_interpreter::power_sre() { ppc_result_a = ppc_result_d >> rot_sh; ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_srea() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 0x1F; @@ -435,12 +528,16 @@ void dppc_interpreter::power_srea() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } +template void dppc_interpreter::power_srea(); +template void dppc_interpreter::power_srea(); + +template void dppc_interpreter::power_sreq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -449,24 +546,32 @@ void dppc_interpreter::power_sreq() { ppc_result_a = ((rot_sh & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); ppc_state.spr[SPR::MQ] = rot_sh; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_sriq() { ppc_grab_regssa(ppc_cur_instruction); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; ppc_result_a = ppc_result_d >> rot_sh; ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_srliq() { ppc_grab_regssa(ppc_cur_instruction); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -477,12 +582,16 @@ void dppc_interpreter::power_srliq() { ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); ppc_state.spr[SPR::MQ] = r; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_srlq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -496,12 +605,16 @@ void dppc_interpreter::power_srlq() { ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask)); } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_srq() { ppc_grab_regssab(ppc_cur_instruction); unsigned rot_sh = ppc_result_b & 31; @@ -514,8 +627,11 @@ void dppc_interpreter::power_srq() { ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } + +template void dppc_interpreter::power_srq(); +template void dppc_interpreter::power_srq(); \ No newline at end of file diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index e4be4cc..a9b1d6c 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -331,9 +331,6 @@ extern bool is_601; // For PowerPC 601 Emulation extern bool is_altivec; // For Altivec Emulation extern bool is_64bit; // For PowerPC G5 Emulation -extern bool rc_flag; // Record flag -extern bool oe_flag; // Overflow flag - // Important Addressing Integers extern uint32_t ppc_cur_instruction; extern uint32_t ppc_effective_address; @@ -391,6 +388,35 @@ extern void add_ctx_sync_action(const std::function &); extern void do_ctx_sync(void); // The functions used by the PowerPC processor + +enum bool_fun { + bool_and = 1, + bool_andc = 2, + bool_eqv = 3, + bool_nand = 4, + bool_nor = 5, + bool_or = 6, + bool_orc = 7, + bool_xor = 8, +}; + +enum field_setting { + LK0 = 0, + LK1 = 1, + AA0 = 0, + AA1 = 1, + LSHFT = 0, + RSHFT = 1, + RC0 = 0, + RC1 = 1, + OV0 = 0, + OV1 = 1, + CARRY0 = 0, + CARRY1 = 1, + IS601 = 0, + NOT601 = 1 +}; + namespace dppc_interpreter { template extern void ppc_bcctr(); template extern void ppc_bclr(); @@ -404,72 +430,55 @@ extern void ppc_crorc(); extern void ppc_crxor(); extern void ppc_isync(); -extern void ppc_add(); -extern void ppc_addc(); -extern void ppc_adde(); -extern void ppc_addme(); -extern void ppc_addze(); -extern void ppc_and(); -extern void ppc_andc(); +template extern void ppc_do_bool(); + +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(); -extern void ppc_cntlzw(); +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(); -extern void ppc_divw(); -extern void ppc_divwu(); +template extern void ppc_divw(); +template extern void ppc_divwu(); extern void ppc_eciwx(); extern void ppc_ecowx(); extern void ppc_eieio(); -extern void ppc_eqv(); -extern void ppc_extsb(); -extern void ppc_extsh(); +template extern void ppc_exts(); extern void ppc_icbi(); extern void ppc_mftb(); -extern void ppc_lhzux(); -extern void ppc_lhzx(); extern void ppc_lhaux(); extern void ppc_lhax(); extern void ppc_lhbrx(); extern void ppc_lwarx(); -extern void ppc_lbzux(); -extern void ppc_lbzx(); extern void ppc_lwbrx(); -extern void ppc_lwzux(); -extern void ppc_lwzx(); +template extern void ppc_lzx(); +template extern void ppc_lzux(); extern void ppc_mcrxr(); extern void ppc_mfcr(); -extern void ppc_mulhwu(); -extern void ppc_mulhw(); -extern void ppc_mullw(); -extern void ppc_nand(); -extern void ppc_neg(); -extern void ppc_nor(); -extern void ppc_or(); -extern void ppc_orc(); -extern void ppc_slw(); -extern void ppc_srw(); -extern void ppc_sraw(); -extern void ppc_srawi(); -extern void ppc_stbx(); -extern void ppc_stbux(); +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_sthx(); -extern void ppc_sthux(); extern void ppc_sthbrx(); -extern void ppc_stwx(); extern void ppc_stwcx(); -extern void ppc_stwux(); extern void ppc_stwbrx(); -extern void ppc_subf(); -extern void ppc_subfc(); -extern void ppc_subfe(); -extern void ppc_subfme(); -extern void ppc_subfze(); +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(); @@ -477,7 +486,6 @@ extern void ppc_tlbli(); extern void ppc_tlbld(); extern void ppc_tlbsync(); extern void ppc_tw(); -extern void ppc_xor(); extern void ppc_lswi(); extern void ppc_lswx(); @@ -496,52 +504,39 @@ extern void ppc_mfspr(); extern void ppc_mtmsr(); extern void ppc_mtspr(); -extern void ppc_mtfsb0(); -extern void ppc_mtfsb1(); +template extern void ppc_mtfsb0(); +template extern void ppc_mtfsb1(); extern void ppc_mcrfs(); -extern void ppc_fmr(); -template extern void ppc_mffs(); -extern void ppc_mtfsf(); -extern void ppc_mtfsfi(); +template extern void ppc_fmr(); +template extern void ppc_mffs(); +template extern void ppc_mtfsf(); +template extern void ppc_mtfsfi(); -extern void ppc_addi(); -extern void ppc_addic(); -extern void ppc_addicdot(); -extern void ppc_addis(); -extern void ppc_andidot(); -extern void ppc_andisdot(); +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(); -extern void ppc_lbz(); -extern void ppc_lbzu(); +template extern void ppc_lz(); +template extern void ppc_lzu(); extern void ppc_lha(); extern void ppc_lhau(); -extern void ppc_lhz(); -extern void ppc_lhzu(); -extern void ppc_lwz(); -extern void ppc_lwzu(); extern void ppc_lmw(); extern void ppc_mulli(); -extern void ppc_ori(); -extern void ppc_oris(); +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(); -extern void ppc_stb(); -extern void ppc_stbu(); -extern void ppc_sth(); -extern void ppc_sthu(); -extern void ppc_stw(); -extern void ppc_stwu(); +template extern void ppc_st(); +template extern void ppc_stu(); extern void ppc_stmw(); extern void ppc_subfic(); extern void ppc_twi(); -extern void ppc_xori(); -extern void ppc_xoris(); +template extern void ppc_xori(); extern void ppc_lfs(); extern void ppc_lfsu(); @@ -560,66 +555,66 @@ extern void ppc_stfdu(); extern void ppc_stfdx(); extern void ppc_stfdux(); -extern void ppc_fadd(); -extern void ppc_fsub(); -extern void ppc_fmul(); -extern void ppc_fdiv(); -extern void ppc_fadds(); -extern void ppc_fsubs(); -extern void ppc_fmuls(); -extern void ppc_fdivs(); -extern void ppc_fmadd(); -extern void ppc_fmsub(); -extern void ppc_fnmadd(); -extern void ppc_fnmsub(); -extern void ppc_fmadds(); -extern void ppc_fmsubs(); -extern void ppc_fnmadds(); -extern void ppc_fnmsubs(); -extern void ppc_fabs(); -extern void ppc_fnabs(); -extern void ppc_fneg(); -extern void ppc_fsel(); -extern void ppc_fres(); -extern void ppc_fsqrts(); -extern void ppc_fsqrt(); -extern void ppc_frsqrte(); -extern void ppc_frsp(); -extern void ppc_fctiw(); -extern void ppc_fctiwz(); +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(); // Power-specific instructions -extern void power_abs(); +template extern void power_abs(); extern void power_clcs(); -extern void power_div(); -extern void power_divs(); -extern void power_doz(); +template extern void power_div(); +template extern void power_divs(); +template extern void power_doz(); extern void power_dozi(); -extern void power_lscbx(); -extern void power_maskg(); -extern void power_maskir(); -extern void power_mul(); -extern void power_nabs(); +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(); -extern void power_rrib(); -extern void power_sle(); -extern void power_sleq(); -extern void power_sliq(); -extern void power_slliq(); -extern void power_sllq(); -extern void power_slq(); -extern void power_sraiq(); -extern void power_sraq(); -extern void power_sre(); -extern void power_srea(); -extern void power_sreq(); -extern void power_sriq(); -extern void power_srliq(); -extern void power_srlq(); -extern void power_srq(); +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(); } // namespace dppc_interpreter // AltiVec instructions diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 70ca4d9..ec0e6c6 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -44,9 +44,6 @@ Po_Cause power_off_reason = po_enter_debugger; SetPRS ppc_state; -bool rc_flag = 0; // Record flag -bool oe_flag = 0; // Overflow flag - bool grab_return; bool grab_breakpoint; @@ -138,18 +135,28 @@ public: /** Primary opcode (bits 0...5) lookup table. */ static PPCOpcode OpcodeGrabber[] = { - ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_illegalop, - ppc_illegalop, ppc_illegalop, ppc_mulli, ppc_subfic, power_dozi, - ppc_cmpli, ppc_cmpi, ppc_addic, ppc_addicdot, ppc_addi, - ppc_addis, ppc_opcode16, ppc_sc, ppc_opcode18, ppc_opcode19, - ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm, ppc_ori, - ppc_oris, ppc_xori, ppc_xoris, ppc_andidot, ppc_andisdot, - ppc_illegalop, ppc_opcode31, ppc_lwz, ppc_lwzu, ppc_lbz, - ppc_lbzu, ppc_stw, ppc_stwu, ppc_stb, ppc_stbu, - ppc_lhz, ppc_lhzu, ppc_lha, ppc_lhau, ppc_sth, - ppc_sthu, ppc_lmw, ppc_stmw, ppc_lfs, ppc_lfsu, - ppc_lfd, ppc_lfdu, ppc_stfs, ppc_stfsu, ppc_stfd, - ppc_stfdu, ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode59, + ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, + ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_mulli, + ppc_subfic, power_dozi, ppc_cmpli, ppc_cmpi, + ppc_addic, ppc_addic, + ppc_addi, ppc_addi, + ppc_opcode16, ppc_sc, ppc_opcode18, ppc_opcode19, + ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm, + ppc_ori, ppc_ori, + ppc_xori, ppc_xori, + ppc_andirc, ppc_andirc, + ppc_illegalop, ppc_opcode31, + ppc_lz, ppc_lzu, + ppc_lz, ppc_lzu, + ppc_st, ppc_stu, + ppc_st, ppc_stu, + ppc_lz, ppc_lzu, + ppc_lha, ppc_lhau, + ppc_st, ppc_stu, + ppc_lmw, ppc_stmw, + ppc_lfs, ppc_lfsu, ppc_lfd, ppc_lfdu, + ppc_stfs, ppc_stfsu, ppc_stfd, ppc_stfdu, + ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode59, ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode63 }; @@ -169,9 +176,9 @@ static PPCOpcode SubOpcode18Grabber[] = { /** Instructions decoding tables for integer, single floating-point, and double-floating point ops respectively */ -PPCOpcode SubOpcode31Grabber[1024]; -PPCOpcode SubOpcode59Grabber[32]; -PPCOpcode SubOpcode63Grabber[1024]; +PPCOpcode SubOpcode31Grabber[2048]; +PPCOpcode SubOpcode59Grabber[64]; +PPCOpcode SubOpcode63Grabber[2048]; /** Exception helpers. */ @@ -272,21 +279,17 @@ template void ppc_opcode19(); template void ppc_opcode19(); void ppc_opcode31() { - uint16_t subop_grab = (ppc_cur_instruction & 0x7FFUL) >> 1UL; - rc_flag = ppc_cur_instruction & 0x1; - oe_flag = ppc_cur_instruction & 0x400; + uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; SubOpcode31Grabber[subop_grab](); } void ppc_opcode59() { - uint16_t subop_grab = (ppc_cur_instruction & 0x3EUL) >> 1UL; - rc_flag = ppc_cur_instruction & 0x1; + uint16_t subop_grab = ppc_cur_instruction & 0x3FUL; SubOpcode59Grabber[subop_grab](); } void ppc_opcode63() { - uint16_t subop_grab = (ppc_cur_instruction & 0x7FFUL) >> 1UL; - rc_flag = ppc_cur_instruction & 0x1; + uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; SubOpcode63Grabber[subop_grab](); } @@ -578,132 +581,230 @@ void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size) } void initialize_ppc_opcode_tables() { - std::fill_n(SubOpcode31Grabber, 1024, ppc_illegalop); + std::fill_n(SubOpcode31Grabber, 2048, ppc_illegalop); SubOpcode31Grabber[0] = ppc_cmp; - SubOpcode31Grabber[4] = ppc_tw; - SubOpcode31Grabber[32] = ppc_cmpl; + SubOpcode31Grabber[8] = ppc_tw; + SubOpcode31Grabber[64] = ppc_cmpl; - SubOpcode31Grabber[8] = SubOpcode31Grabber[520] = ppc_subfc; - SubOpcode31Grabber[40] = SubOpcode31Grabber[552] = ppc_subf; - SubOpcode31Grabber[104] = SubOpcode31Grabber[616] = ppc_neg; - SubOpcode31Grabber[136] = SubOpcode31Grabber[648] = ppc_subfe; - SubOpcode31Grabber[200] = SubOpcode31Grabber[712] = ppc_subfze; - SubOpcode31Grabber[232] = SubOpcode31Grabber[744] = ppc_subfme; + SubOpcode31Grabber[16] = ppc_subf; + SubOpcode31Grabber[17] = ppc_subf; + SubOpcode31Grabber[80] = ppc_subf; + SubOpcode31Grabber[81] = ppc_subf; + SubOpcode31Grabber[208] = ppc_neg; + SubOpcode31Grabber[209] = ppc_neg; + SubOpcode31Grabber[272] = ppc_subfe; + SubOpcode31Grabber[273] = ppc_subfe; + SubOpcode31Grabber[400] = ppc_subfze; + SubOpcode31Grabber[401] = ppc_subfze; + SubOpcode31Grabber[464] = ppc_subfme; + SubOpcode31Grabber[465] = ppc_subfme; - SubOpcode31Grabber[10] = SubOpcode31Grabber[522] = ppc_addc; - SubOpcode31Grabber[138] = SubOpcode31Grabber[650] = ppc_adde; - SubOpcode31Grabber[202] = SubOpcode31Grabber[714] = ppc_addze; - SubOpcode31Grabber[234] = SubOpcode31Grabber[746] = ppc_addme; - SubOpcode31Grabber[266] = SubOpcode31Grabber[778] = ppc_add; + SubOpcode31Grabber[1040] = ppc_subf; + SubOpcode31Grabber[1041] = ppc_subf; + SubOpcode31Grabber[1104] = ppc_subf; + SubOpcode31Grabber[1105] = ppc_subf; + SubOpcode31Grabber[1232] = ppc_neg; + SubOpcode31Grabber[1233] = ppc_neg; + SubOpcode31Grabber[1296] = ppc_subfe; + SubOpcode31Grabber[1297] = ppc_subfe; + SubOpcode31Grabber[1424] = ppc_subfze; + SubOpcode31Grabber[1425] = ppc_subfze; + SubOpcode31Grabber[464] = ppc_subfme; + SubOpcode31Grabber[465] = ppc_subfme; - SubOpcode31Grabber[11] = ppc_mulhwu; - SubOpcode31Grabber[75] = ppc_mulhw; - SubOpcode31Grabber[235] = SubOpcode31Grabber[747] = ppc_mullw; - SubOpcode31Grabber[459] = SubOpcode31Grabber[971] = ppc_divwu; - SubOpcode31Grabber[491] = SubOpcode31Grabber[1003] = ppc_divw; + SubOpcode31Grabber[20] = ppc_add; + SubOpcode31Grabber[21] = ppc_add; + SubOpcode31Grabber[276] = ppc_adde; + SubOpcode31Grabber[277] = ppc_adde; + SubOpcode31Grabber[404] = ppc_addze; + SubOpcode31Grabber[405] = ppc_addze; + SubOpcode31Grabber[468] = ppc_addme; + SubOpcode31Grabber[469] = ppc_addme; + SubOpcode31Grabber[532] = ppc_add; + SubOpcode31Grabber[533] = ppc_add; - SubOpcode31Grabber[20] = ppc_lwarx; - SubOpcode31Grabber[23] = ppc_lwzx; - SubOpcode31Grabber[55] = ppc_lwzux; - SubOpcode31Grabber[87] = ppc_lbzx; - SubOpcode31Grabber[119] = ppc_lbzux; - SubOpcode31Grabber[279] = ppc_lhzx; - SubOpcode31Grabber[311] = ppc_lhzux; - SubOpcode31Grabber[343] = ppc_lhax; - SubOpcode31Grabber[375] = ppc_lhaux; - SubOpcode31Grabber[533] = ppc_lswx; - SubOpcode31Grabber[534] = ppc_lwbrx; - SubOpcode31Grabber[535] = ppc_lfsx; - SubOpcode31Grabber[567] = ppc_lfsux; - SubOpcode31Grabber[597] = ppc_lswi; - SubOpcode31Grabber[599] = ppc_lfdx; - SubOpcode31Grabber[631] = ppc_lfdux; - SubOpcode31Grabber[790] = ppc_lhbrx; + SubOpcode31Grabber[1044] = ppc_add; + SubOpcode31Grabber[1045] = ppc_add; + SubOpcode31Grabber[1300] = ppc_adde; + SubOpcode31Grabber[1301] = ppc_adde; + SubOpcode31Grabber[1428] = ppc_addze; + SubOpcode31Grabber[1429] = ppc_addze; + SubOpcode31Grabber[1492] = ppc_addme; + SubOpcode31Grabber[1493] = ppc_addme; + SubOpcode31Grabber[1556] = ppc_add; + SubOpcode31Grabber[1557] = ppc_add; - SubOpcode31Grabber[150] = ppc_stwcx; - SubOpcode31Grabber[151] = ppc_stwx; - SubOpcode31Grabber[183] = ppc_stwux; - SubOpcode31Grabber[215] = ppc_stbx; - SubOpcode31Grabber[247] = ppc_stbux; - SubOpcode31Grabber[407] = ppc_sthx; - SubOpcode31Grabber[439] = ppc_sthux; - SubOpcode31Grabber[661] = ppc_stswx; - SubOpcode31Grabber[662] = ppc_stwbrx; - SubOpcode31Grabber[663] = ppc_stfsx; - SubOpcode31Grabber[695] = ppc_stfsux; - SubOpcode31Grabber[725] = ppc_stswi; - SubOpcode31Grabber[727] = ppc_stfdx; - SubOpcode31Grabber[759] = ppc_stfdux; - SubOpcode31Grabber[918] = ppc_sthbrx; - SubOpcode31Grabber[983] = ppc_stfiwx; + SubOpcode31Grabber[22] = ppc_mulhwu; + SubOpcode31Grabber[23] = ppc_mulhwu; + SubOpcode31Grabber[150] = ppc_mulhw; + SubOpcode31Grabber[151] = ppc_mulhw; + SubOpcode31Grabber[470] = ppc_mullw; + SubOpcode31Grabber[471] = ppc_mullw; + SubOpcode31Grabber[918] = ppc_divwu; + SubOpcode31Grabber[919] = ppc_divwu; + SubOpcode31Grabber[982] = ppc_divw; + SubOpcode31Grabber[983] = ppc_divw; - SubOpcode31Grabber[310] = ppc_eciwx; - SubOpcode31Grabber[438] = ppc_ecowx; + SubOpcode31Grabber[1494] = ppc_mullw; + SubOpcode31Grabber[1495] = ppc_mullw; + SubOpcode31Grabber[1942] = ppc_divwu; + SubOpcode31Grabber[1943] = ppc_divwu; + SubOpcode31Grabber[2006] = ppc_divw; + SubOpcode31Grabber[2007] = ppc_divw; - SubOpcode31Grabber[24] = ppc_slw; - SubOpcode31Grabber[28] = ppc_and; - SubOpcode31Grabber[60] = ppc_andc; - SubOpcode31Grabber[124] = ppc_nor; - SubOpcode31Grabber[284] = ppc_eqv; - SubOpcode31Grabber[316] = ppc_xor; - SubOpcode31Grabber[412] = ppc_orc; - SubOpcode31Grabber[444] = ppc_or; - SubOpcode31Grabber[476] = ppc_nand; - SubOpcode31Grabber[536] = ppc_srw; - SubOpcode31Grabber[792] = ppc_sraw; - SubOpcode31Grabber[824] = ppc_srawi; - SubOpcode31Grabber[922] = ppc_extsh; - SubOpcode31Grabber[954] = ppc_extsb; + SubOpcode31Grabber[40] = ppc_lwarx; + SubOpcode31Grabber[46] = ppc_lzx; + SubOpcode31Grabber[110] = ppc_lzux; + SubOpcode31Grabber[174] = ppc_lzx; + SubOpcode31Grabber[238] = ppc_lzux; + SubOpcode31Grabber[558] = ppc_lzx; + SubOpcode31Grabber[662] = ppc_lzux; + SubOpcode31Grabber[686] = ppc_lhax; + SubOpcode31Grabber[750] = ppc_lhaux; + SubOpcode31Grabber[1066] = ppc_lswx; + SubOpcode31Grabber[1068] = ppc_lwbrx; + SubOpcode31Grabber[1070] = ppc_lfsx; + SubOpcode31Grabber[1134] = ppc_lfsux; + SubOpcode31Grabber[1194] = ppc_lswi; + SubOpcode31Grabber[1198] = ppc_lfdx; + SubOpcode31Grabber[1262] = ppc_lfdux; + SubOpcode31Grabber[1580] = ppc_lhbrx; - SubOpcode31Grabber[26] = ppc_cntlzw; + SubOpcode31Grabber[301] = ppc_stwcx; + SubOpcode31Grabber[302] = ppc_stx; + SubOpcode31Grabber[366] = ppc_stux; + SubOpcode31Grabber[430] = ppc_stx; + SubOpcode31Grabber[494] = ppc_stux; + SubOpcode31Grabber[814] = ppc_stx; + SubOpcode31Grabber[878] = ppc_stux; + SubOpcode31Grabber[1322] = ppc_stswx; + SubOpcode31Grabber[1324] = ppc_stwbrx; + SubOpcode31Grabber[1326] = ppc_stfsx; + SubOpcode31Grabber[1390] = ppc_stfsux; + SubOpcode31Grabber[1450] = ppc_stswi; + SubOpcode31Grabber[1454] = ppc_stfdx; + SubOpcode31Grabber[1518] = ppc_stfdux; + SubOpcode31Grabber[1836] = ppc_sthbrx; + SubOpcode31Grabber[1966] = ppc_stfiwx; - SubOpcode31Grabber[19] = ppc_mfcr; - SubOpcode31Grabber[83] = ppc_mfmsr; - SubOpcode31Grabber[144] = ppc_mtcrf; - SubOpcode31Grabber[146] = ppc_mtmsr; - SubOpcode31Grabber[210] = ppc_mtsr; - SubOpcode31Grabber[242] = ppc_mtsrin; - SubOpcode31Grabber[339] = ppc_mfspr; - SubOpcode31Grabber[371] = ppc_mftb; - SubOpcode31Grabber[467] = ppc_mtspr; - SubOpcode31Grabber[512] = ppc_mcrxr; - SubOpcode31Grabber[595] = ppc_mfsr; - SubOpcode31Grabber[659] = ppc_mfsrin; + SubOpcode31Grabber[620] = ppc_eciwx; + SubOpcode31Grabber[876] = ppc_ecowx; - SubOpcode31Grabber[54] = ppc_dcbst; - SubOpcode31Grabber[86] = ppc_dcbf; - SubOpcode31Grabber[246] = ppc_dcbtst; - SubOpcode31Grabber[278] = ppc_dcbt; - SubOpcode31Grabber[598] = ppc_sync; - SubOpcode31Grabber[470] = ppc_dcbi; - SubOpcode31Grabber[1014] = ppc_dcbz; + SubOpcode31Grabber[48] = ppc_shift; + SubOpcode31Grabber[49] = ppc_shift; + SubOpcode31Grabber[56] = ppc_do_bool; + SubOpcode31Grabber[57] = ppc_do_bool; + SubOpcode31Grabber[120] = ppc_do_bool; + SubOpcode31Grabber[121] = ppc_do_bool; + SubOpcode31Grabber[248] = ppc_do_bool; + SubOpcode31Grabber[249] = ppc_do_bool; + SubOpcode31Grabber[568] = ppc_do_bool; + SubOpcode31Grabber[569] = ppc_do_bool; + SubOpcode31Grabber[632] = ppc_do_bool; + SubOpcode31Grabber[633] = ppc_do_bool; + SubOpcode31Grabber[824] = ppc_do_bool; + SubOpcode31Grabber[825] = ppc_do_bool; + SubOpcode31Grabber[888] = ppc_do_bool; + SubOpcode31Grabber[889] = ppc_do_bool; + SubOpcode31Grabber[1072] = ppc_shift; + SubOpcode31Grabber[1073] = ppc_shift; + SubOpcode31Grabber[1584] = ppc_sraw; + SubOpcode31Grabber[1585] = ppc_sraw; + SubOpcode31Grabber[1648] = ppc_srawi; + SubOpcode31Grabber[1649] = ppc_srawi; + SubOpcode31Grabber[1844] = ppc_exts; + SubOpcode31Grabber[1845] = ppc_exts; + SubOpcode31Grabber[1908] = ppc_exts; + SubOpcode31Grabber[1909] = ppc_exts; - SubOpcode31Grabber[29] = power_maskg; - SubOpcode31Grabber[107] = SubOpcode31Grabber[619] = power_mul; - SubOpcode31Grabber[152] = power_slq; - SubOpcode31Grabber[153] = power_sle; - SubOpcode31Grabber[184] = power_sliq; - SubOpcode31Grabber[216] = power_sllq; - SubOpcode31Grabber[217] = power_sleq; - SubOpcode31Grabber[248] = power_slliq; - SubOpcode31Grabber[264] = SubOpcode31Grabber[776] = power_doz; - SubOpcode31Grabber[277] = power_lscbx; - SubOpcode31Grabber[331] = SubOpcode31Grabber[843] = power_div; - SubOpcode31Grabber[360] = SubOpcode31Grabber[872] = power_abs; - SubOpcode31Grabber[363] = SubOpcode31Grabber[875] = power_divs; - SubOpcode31Grabber[488] = SubOpcode31Grabber[1000] = power_nabs; - SubOpcode31Grabber[531] = power_clcs; - SubOpcode31Grabber[537] = power_rrib; - SubOpcode31Grabber[541] = power_maskir; - SubOpcode31Grabber[664] = power_srq; - SubOpcode31Grabber[665] = power_sre; - SubOpcode31Grabber[696] = power_sriq; - SubOpcode31Grabber[728] = power_srlq; - SubOpcode31Grabber[729] = power_sreq; - SubOpcode31Grabber[760] = power_srliq; - SubOpcode31Grabber[920] = power_sraq; - SubOpcode31Grabber[921] = power_srea; - SubOpcode31Grabber[952] = power_sraiq; + SubOpcode31Grabber[52] = ppc_cntlzw; + SubOpcode31Grabber[53] = ppc_cntlzw; + + SubOpcode31Grabber[38] = ppc_mfcr; + SubOpcode31Grabber[166] = ppc_mfmsr; + SubOpcode31Grabber[144] = ppc_mtcrf; + SubOpcode31Grabber[292] = ppc_mtmsr; + SubOpcode31Grabber[420] = ppc_mtsr; + SubOpcode31Grabber[484] = ppc_mtsrin; + SubOpcode31Grabber[678] = ppc_mfspr; + SubOpcode31Grabber[742] = ppc_mftb; + SubOpcode31Grabber[934] = ppc_mtspr; + SubOpcode31Grabber[1024] = ppc_mcrxr; + SubOpcode31Grabber[1190] = ppc_mfsr; + SubOpcode31Grabber[1318] = ppc_mfsrin; + + SubOpcode31Grabber[108] = ppc_dcbst; + SubOpcode31Grabber[172] = ppc_dcbf; + SubOpcode31Grabber[492] = ppc_dcbtst; + SubOpcode31Grabber[556] = ppc_dcbt; + SubOpcode31Grabber[940] = ppc_dcbi; + SubOpcode31Grabber[1196] = ppc_sync; + SubOpcode31Grabber[2028] = ppc_dcbz; + + SubOpcode31Grabber[58] = power_maskg; + SubOpcode31Grabber[59] = power_maskg; + SubOpcode31Grabber[214] = power_mul; + SubOpcode31Grabber[215] = power_mul; + SubOpcode31Grabber[304] = power_slq; + SubOpcode31Grabber[305] = power_slq; + SubOpcode31Grabber[306] = power_sle; + SubOpcode31Grabber[306] = power_sle; + SubOpcode31Grabber[368] = power_sliq; + SubOpcode31Grabber[369] = power_sliq; + SubOpcode31Grabber[432] = power_sllq; + SubOpcode31Grabber[433] = power_sllq; + SubOpcode31Grabber[434] = power_sleq; + SubOpcode31Grabber[435] = power_sleq; + SubOpcode31Grabber[496] = power_slliq; + SubOpcode31Grabber[497] = power_slliq; + SubOpcode31Grabber[528] = power_doz; + SubOpcode31Grabber[529] = power_doz; + SubOpcode31Grabber[554] = power_lscbx; + SubOpcode31Grabber[555] = power_lscbx; + SubOpcode31Grabber[662] = power_div; + SubOpcode31Grabber[663] = power_div; + SubOpcode31Grabber[720] = power_abs; + SubOpcode31Grabber[721] = power_abs; + SubOpcode31Grabber[726] = power_divs; + SubOpcode31Grabber[727] = power_divs; + SubOpcode31Grabber[976] = power_nabs; + SubOpcode31Grabber[977] = power_nabs; + SubOpcode31Grabber[1062] = power_clcs; + SubOpcode31Grabber[1074] = power_rrib; + SubOpcode31Grabber[1075] = power_rrib; + SubOpcode31Grabber[1082] = power_maskir; + SubOpcode31Grabber[1083] = power_maskir; + SubOpcode31Grabber[1328] = power_srq; + SubOpcode31Grabber[1329] = power_srq; + SubOpcode31Grabber[1330] = power_sre; + SubOpcode31Grabber[1331] = power_sre; + SubOpcode31Grabber[1332] = power_sriq; + SubOpcode31Grabber[1333] = power_sriq; + SubOpcode31Grabber[1456] = power_srlq; + SubOpcode31Grabber[1457] = power_srlq; + SubOpcode31Grabber[1458] = power_sreq; + SubOpcode31Grabber[1459] = power_sreq; + SubOpcode31Grabber[1520] = power_srliq; + SubOpcode31Grabber[1521] = power_srliq; + SubOpcode31Grabber[1840] = power_sraq; + SubOpcode31Grabber[1841] = power_sraq; + SubOpcode31Grabber[1842] = power_srea; + SubOpcode31Grabber[1843] = power_srea; + SubOpcode31Grabber[1904] = power_sraiq; + SubOpcode31Grabber[1905] = power_sraiq; + + SubOpcode31Grabber[1238] = power_mul; + SubOpcode31Grabber[1239] = power_mul; + SubOpcode31Grabber[1552] = power_doz; + SubOpcode31Grabber[1553] = power_doz; + SubOpcode31Grabber[1686] = power_div; + SubOpcode31Grabber[1687] = power_div; + SubOpcode31Grabber[1744] = power_abs; + SubOpcode31Grabber[1745] = power_abs; + SubOpcode31Grabber[1750] = power_divs; + SubOpcode31Grabber[1751] = power_divs; + SubOpcode31Grabber[2000] = power_nabs; + SubOpcode31Grabber[2001] = power_nabs; SubOpcode31Grabber[306] = ppc_tlbie; SubOpcode31Grabber[370] = ppc_tlbia; @@ -713,47 +814,80 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[978] = ppc_tlbld; SubOpcode31Grabber[1010] = ppc_tlbli; - std::fill_n(SubOpcode59Grabber, 32, ppc_illegalop); - SubOpcode59Grabber[18] = ppc_fdivs; - SubOpcode59Grabber[20] = ppc_fsubs; - SubOpcode59Grabber[21] = ppc_fadds; - SubOpcode59Grabber[22] = ppc_fsqrts; - SubOpcode59Grabber[24] = ppc_fres; - SubOpcode59Grabber[25] = ppc_fmuls; - SubOpcode59Grabber[28] = ppc_fmsubs; - SubOpcode59Grabber[29] = ppc_fmadds; - SubOpcode59Grabber[30] = ppc_fnmsubs; - SubOpcode59Grabber[31] = ppc_fnmadds; + std::fill_n(SubOpcode59Grabber, 64, ppc_illegalop); + SubOpcode59Grabber[36] = ppc_fdivs; + SubOpcode59Grabber[37] = ppc_fdivs; + SubOpcode59Grabber[40] = ppc_fsubs; + SubOpcode59Grabber[41] = ppc_fsubs; + SubOpcode59Grabber[42] = ppc_fadds; + SubOpcode59Grabber[43] = ppc_fadds; + SubOpcode59Grabber[44] = ppc_fsqrts; + SubOpcode59Grabber[45] = ppc_fsqrts; + SubOpcode59Grabber[48] = ppc_fres; + SubOpcode59Grabber[49] = ppc_fres; + SubOpcode59Grabber[50] = ppc_fmuls; + SubOpcode59Grabber[51] = ppc_fmuls; + SubOpcode59Grabber[56] = ppc_fmsubs; + SubOpcode59Grabber[57] = ppc_fmsubs; + SubOpcode59Grabber[58] = ppc_fmadds; + SubOpcode59Grabber[59] = ppc_fmadds; + SubOpcode59Grabber[60] = ppc_fnmsubs; + SubOpcode59Grabber[61] = ppc_fnmsubs; + SubOpcode59Grabber[62] = ppc_fnmadds; + SubOpcode59Grabber[63] = ppc_fnmadds; - std::fill_n(SubOpcode63Grabber, 1024, ppc_illegalop); - SubOpcode63Grabber[0] = ppc_fcmpu; - SubOpcode63Grabber[12] = ppc_frsp; - SubOpcode63Grabber[14] = ppc_fctiw; - SubOpcode63Grabber[15] = ppc_fctiwz; - SubOpcode63Grabber[18] = ppc_fdiv; - SubOpcode63Grabber[20] = ppc_fsub; - SubOpcode63Grabber[21] = ppc_fadd; - SubOpcode63Grabber[22] = ppc_fsqrt; - SubOpcode63Grabber[26] = ppc_frsqrte; - SubOpcode63Grabber[32] = ppc_fcmpo; - SubOpcode63Grabber[38] = ppc_mtfsb1; - SubOpcode63Grabber[40] = ppc_fneg; - SubOpcode63Grabber[64] = ppc_mcrfs; - SubOpcode63Grabber[70] = ppc_mtfsb0; - SubOpcode63Grabber[72] = ppc_fmr; - SubOpcode63Grabber[134] = ppc_mtfsfi; - SubOpcode63Grabber[136] = ppc_fnabs; - SubOpcode63Grabber[264] = ppc_fabs; - SubOpcode63Grabber[583] = ppc_mffs; - SubOpcode63Grabber[711] = ppc_mtfsf; + std::fill_n(SubOpcode63Grabber, 2048, ppc_illegalop); + SubOpcode63Grabber[0] = ppc_fcmpu; + SubOpcode63Grabber[24] = ppc_frsp; + SubOpcode63Grabber[25] = ppc_frsp; + SubOpcode63Grabber[28] = ppc_fctiw; + SubOpcode63Grabber[29] = ppc_fctiw; + SubOpcode63Grabber[30] = ppc_fctiwz; + SubOpcode63Grabber[31] = ppc_fctiwz; + SubOpcode63Grabber[36] = ppc_fdiv; + SubOpcode63Grabber[37] = ppc_fdiv; + SubOpcode63Grabber[40] = ppc_fsub; + SubOpcode63Grabber[41] = ppc_fsub; + SubOpcode63Grabber[42] = ppc_fadd; + SubOpcode63Grabber[43] = ppc_fadd; + SubOpcode63Grabber[44] = ppc_fsqrt; + SubOpcode63Grabber[45] = ppc_fsqrt; + SubOpcode63Grabber[52] = ppc_frsqrte; + SubOpcode63Grabber[53] = ppc_frsqrte; + SubOpcode63Grabber[64] = ppc_fcmpo; + SubOpcode63Grabber[76] = ppc_mtfsb1; + SubOpcode63Grabber[77] = ppc_mtfsb1; + SubOpcode63Grabber[80] = ppc_fneg; + SubOpcode63Grabber[81] = ppc_fneg; + SubOpcode63Grabber[128] = ppc_mcrfs; + SubOpcode63Grabber[140] = ppc_mtfsb0; + SubOpcode63Grabber[141] = ppc_mtfsb0; + SubOpcode63Grabber[144] = ppc_fmr; + SubOpcode63Grabber[145] = ppc_fmr; + SubOpcode63Grabber[268] = ppc_mtfsfi; + SubOpcode63Grabber[269] = ppc_mtfsfi; + SubOpcode63Grabber[272] = ppc_fnabs; + SubOpcode63Grabber[273] = ppc_fnabs; + SubOpcode63Grabber[528] = ppc_fabs; + SubOpcode63Grabber[529] = ppc_fabs; + SubOpcode63Grabber[1166] = ppc_mffs; + SubOpcode63Grabber[1167] = ppc_mffs; + SubOpcode63Grabber[1422] = ppc_mtfsf; + SubOpcode63Grabber[1423] = ppc_mtfsf; - for (int i = 0; i < 1024; i += 32) { - SubOpcode63Grabber[i + 23] = ppc_fsel; - SubOpcode63Grabber[i + 25] = ppc_fmul; - SubOpcode63Grabber[i + 28] = ppc_fmsub; - SubOpcode63Grabber[i + 29] = ppc_fmadd; - SubOpcode63Grabber[i + 30] = ppc_fnmsub; - SubOpcode63Grabber[i + 31] = ppc_fnmadd; + for (int i = 0; i < 2048; i += 64) { + SubOpcode63Grabber[i + 46] = ppc_fsel; + SubOpcode63Grabber[i + 47] = ppc_fsel; + SubOpcode63Grabber[i + 50] = ppc_fmul; + SubOpcode63Grabber[i + 50] = ppc_fmul; + SubOpcode63Grabber[i + 56] = ppc_fmsub; + SubOpcode63Grabber[i + 57] = ppc_fmsub; + SubOpcode63Grabber[i + 58] = ppc_fmadd; + SubOpcode63Grabber[i + 59] = ppc_fmadd; + SubOpcode63Grabber[i + 60] = ppc_fnmsub; + SubOpcode63Grabber[i + 61] = ppc_fnmsub; + SubOpcode63Grabber[i + 62] = ppc_fnmadd; + SubOpcode63Grabber[i + 63] = ppc_fnmadd; } } @@ -777,19 +911,23 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq) initialize_ppc_opcode_tables(); if (cpu_version == PPC_VER::MPC601) { - OpcodeGrabber[19] = ppc_opcode19; - SubOpcode31Grabber[370] = ppc_illegalop; // tlbia - SubOpcode31Grabber[371] = ppc_illegalop; // mftb - SubOpcode59Grabber[24] = ppc_illegalop; // fres - SubOpcode63Grabber[26] = ppc_illegalop; // frsqrte - SubOpcode63Grabber[583] = ppc_mffs; - for (int i = 0; i < 1024; i += 32) { - SubOpcode63Grabber[i + 23] = ppc_illegalop; // fsel + OpcodeGrabber[19] = ppc_opcode19; + SubOpcode31Grabber[740] = ppc_illegalop; // tlbia + SubOpcode31Grabber[742] = ppc_illegalop; // mftb + SubOpcode59Grabber[48] = ppc_illegalop; // fres + SubOpcode63Grabber[52] = ppc_illegalop; // frsqrte + SubOpcode63Grabber[1166] = ppc_mffs; + SubOpcode63Grabber[1167] = ppc_mffs; + for (int i = 0; i < 2048; i += 64) { + SubOpcode63Grabber[i + 46] = ppc_illegalop; // fsel + SubOpcode63Grabber[i + 47] = ppc_illegalop; // fsel. } } if (cpu_version != PPC_VER::MPC970MP) { - SubOpcode59Grabber[22] = ppc_illegalop; // fsqrts - SubOpcode63Grabber[22] = ppc_illegalop; // fsqrt + SubOpcode59Grabber[44] = ppc_illegalop; // fsqrts + SubOpcode59Grabber[45] = ppc_illegalop; // fsqrts. + SubOpcode63Grabber[44] = ppc_illegalop; // fsqrt + SubOpcode63Grabber[45] = ppc_illegalop; // fsqrt. } // initialize emulator timers diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index 4a221a1..bb36dcf 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -96,7 +96,7 @@ void update_fex() { } template -void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool rc_flag = false) { +void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool rec = false) { double input_a = ppc_state.fpr[chosen_reg_1].dbl64_r; double input_b = ppc_state.fpr[chosen_reg_2].dbl64_r; @@ -160,145 +160,178 @@ static void fpresult_update(double set_result) { } // Floating Point Arithmetic +template void dppc_interpreter::ppc_fadd() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { ppc_state.fpscr |= FPCC_FUNAN; - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = val_reg_a + val_reg_b; ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fadd(); +template void dppc_interpreter::ppc_fadd(); + +template void dppc_interpreter::ppc_fsub() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { ppc_state.fpscr |= FPCC_FUNAN; - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = val_reg_a - val_reg_b; ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fsub(); +template void dppc_interpreter::ppc_fsub(); + +template void dppc_interpreter::ppc_fdiv() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { - ppc_confirm_inf_nan
(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan
(reg_a, reg_b, rec); } double ppc_dblresult64_d = val_reg_a / val_reg_b; ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fdiv(); +template void dppc_interpreter::ppc_fdiv(); + +template void dppc_interpreter::ppc_fmul() { ppc_grab_regsfpdac(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } double ppc_dblresult64_d = val_reg_a * val_reg_c; ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmul(); +template void dppc_interpreter::ppc_fmul(); + +template void dppc_interpreter::ppc_fmadd() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmadd(); +template void dppc_interpreter::ppc_fmadd(); + +template void dppc_interpreter::ppc_fmsub() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, -val_reg_b); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmsub(); +template void dppc_interpreter::ppc_fmsub(); + +template void dppc_interpreter::ppc_fnmadd() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fnmadd(); +template void dppc_interpreter::ppc_fnmadd(); + +template void dppc_interpreter::ppc_fnmsub() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = std::fma(-val_reg_a, val_reg_c, val_reg_b); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fnmsub(); +template void dppc_interpreter::ppc_fnmsub(); + +template void dppc_interpreter::ppc_fadds() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } float ppc_fltresult32_d = val_reg_a + val_reg_b; @@ -307,127 +340,159 @@ void dppc_interpreter::ppc_fadds() { fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fadds(); +template void dppc_interpreter::ppc_fadds(); + +template void dppc_interpreter::ppc_fsubs() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fsubs(); +template void dppc_interpreter::ppc_fsubs(); + +template void dppc_interpreter::ppc_fdivs() { ppc_grab_regsfpdab(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) { - ppc_confirm_inf_nan
(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan
(reg_a, reg_b, rec); } double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fdivs(); +template void dppc_interpreter::ppc_fdivs(); + +template void dppc_interpreter::ppc_fmuls() { ppc_grab_regsfpdac(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmuls(); +template void dppc_interpreter::ppc_fmuls(); + +template void dppc_interpreter::ppc_fmadds() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmadds(); +template void dppc_interpreter::ppc_fmadds(); + +template void dppc_interpreter::ppc_fmsubs() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fmsubs(); +template void dppc_interpreter::ppc_fmsubs(); + +template void dppc_interpreter::ppc_fnmadds() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fnmadds(); +template void dppc_interpreter::ppc_fnmadds(); + +template void dppc_interpreter::ppc_fnmsubs() { ppc_grab_regsfpdabc(ppc_cur_instruction); if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) { - ppc_confirm_inf_nan(reg_a, reg_c, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_c, rec); } if (std::isnan(val_reg_b)) { - ppc_confirm_inf_nan(reg_a, reg_b, rc_flag); + ppc_confirm_inf_nan(reg_a, reg_b, rec); } double ppc_dblresult64_d = (float)std::fma(-val_reg_a, val_reg_c, val_reg_b); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fnmsubs(); +template void dppc_interpreter::ppc_fnmsubs(); + +template void dppc_interpreter::ppc_fabs() { ppc_grab_regsfpdb(ppc_cur_instruction); @@ -435,10 +500,14 @@ void dppc_interpreter::ppc_fabs() { ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fabs(); +template void dppc_interpreter::ppc_fabs(); + +template void dppc_interpreter::ppc_fnabs() { ppc_grab_regsfpdb(ppc_cur_instruction); @@ -447,10 +516,14 @@ void dppc_interpreter::ppc_fnabs() { ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fnabs(); +template void dppc_interpreter::ppc_fnabs(); + +template void dppc_interpreter::ppc_fneg() { ppc_grab_regsfpdb(ppc_cur_instruction); @@ -458,10 +531,14 @@ void dppc_interpreter::ppc_fneg() { ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fneg(); +template void dppc_interpreter::ppc_fneg(); + +template void dppc_interpreter::ppc_fsel() { ppc_grab_regsfpdabc(ppc_cur_instruction); @@ -469,54 +546,74 @@ void dppc_interpreter::ppc_fsel() { ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fsel(); +template void dppc_interpreter::ppc_fsel(); + +template void dppc_interpreter::ppc_fsqrt() { ppc_grab_regsfpdb(ppc_cur_instruction); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = std::sqrt(testd2); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - ppc_confirm_inf_nan(0, reg_b, rc_flag); + ppc_confirm_inf_nan(0, reg_b, rec); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fsqrt(); +template void dppc_interpreter::ppc_fsqrt(); + +template void dppc_interpreter::ppc_fsqrts() { ppc_grab_regsfpdb(ppc_cur_instruction); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = (float)std::sqrt(testd2); ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); - ppc_confirm_inf_nan(0, reg_b, rc_flag); + ppc_confirm_inf_nan(0, reg_b, rec); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fsqrts(); +template void dppc_interpreter::ppc_fsqrts(); + +template void dppc_interpreter::ppc_frsqrte() { ppc_grab_regsfpdb(ppc_cur_instruction); double testd2 = (double)(GET_FPR(reg_b)); double ppc_dblresult64_d = 1.0 / sqrt(testd2); - ppc_confirm_inf_nan(0, reg_b, rc_flag); + ppc_confirm_inf_nan(0, reg_b, rec); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_frsqrte(); +template void dppc_interpreter::ppc_frsqrte(); + +template void dppc_interpreter::ppc_frsp() { ppc_grab_regsfpdb(ppc_cur_instruction); double ppc_dblresult64_d = (float)(GET_FPR(reg_b)); ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_frsp(); +template void dppc_interpreter::ppc_frsp(); + +template void dppc_interpreter::ppc_fres() { ppc_grab_regsfpdb(ppc_cur_instruction); double start_num = GET_FPR(reg_b); @@ -534,11 +631,14 @@ void dppc_interpreter::ppc_fres() { ppc_state.fpscr |= FPSCR::VXSNAN; } - if (rc_flag) + if (rec) ppc_update_cr1(); } -static void round_to_int(const uint8_t mode) { +template void dppc_interpreter::ppc_fres(); +template void dppc_interpreter::ppc_fres(); + +static void round_to_int(const uint8_t mode, bool rec) { ppc_grab_regsfpdb(ppc_cur_instruction); double val_reg_b = GET_FPR(reg_b); @@ -591,18 +691,26 @@ static void round_to_int(const uint8_t mode) { ppc_store_dfpresult_int(reg_d, ppc_result64_d); } - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_fctiw() { - round_to_int(ppc_state.fpscr & 0x3); + round_to_int(ppc_state.fpscr & 0x3, rec); } +template void dppc_interpreter::ppc_fctiw(); +template void dppc_interpreter::ppc_fctiw(); + +template void dppc_interpreter::ppc_fctiwz() { - round_to_int(1); + round_to_int(1, rec); } +template void dppc_interpreter::ppc_fctiwz(); +template void dppc_interpreter::ppc_fctiwz(); + // Floating Point Store and Load void dppc_interpreter::ppc_lfs() { @@ -769,27 +877,34 @@ void dppc_interpreter::ppc_stfiwx() { // Floating Point Register Transfer +template void dppc_interpreter::ppc_fmr() { ppc_grab_regsfpdb(ppc_cur_instruction); ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r; - if (rc_flag) + if (rec) ppc_update_cr1(); } -template +template void dppc_interpreter::ppc_fmr(); +template void dppc_interpreter::ppc_fmr(); + +template void dppc_interpreter::ppc_mffs() { - ppc_grab_regsda(ppc_cur_instruction); + int reg_d = (ppc_cur_instruction >> 21) & 31; ppc_state.fpr[reg_d].int64_r = uint64_t(ppc_state.fpscr) | (for601 ? 0xFFFFFFFF00000000ULL : 0xFFF8000000000000ULL); - if (rc_flag) + if (rec) 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(); +template void dppc_interpreter::ppc_mffs(); +template void dppc_interpreter::ppc_mtfsf() { int reg_b = (ppc_cur_instruction >> 11) & 0x1F; uint8_t fm = (ppc_cur_instruction >> 17) & 0xFF; @@ -815,10 +930,14 @@ void dppc_interpreter::ppc_mtfsf() { // copy FPR[reg_b] to FPSCR under control of cr_mask ppc_state.fpscr = (ppc_state.fpscr & ~cr_mask) | (ppc_state.fpr[reg_b].int64_r & cr_mask); - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_mtfsf(); +template void dppc_interpreter::ppc_mtfsf(); + +template void dppc_interpreter::ppc_mtfsfi() { int crf_d = (ppc_cur_instruction >> 21) & 0x1C; uint32_t imm = (ppc_cur_instruction << 16) & 0xF0000000UL; @@ -831,30 +950,41 @@ void dppc_interpreter::ppc_mtfsfi() { // TODO: update FEX and VX according to the "usual rule" - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_mtfsfi(); +template void dppc_interpreter::ppc_mtfsfi(); + +template void dppc_interpreter::ppc_mtfsb0() { int crf_d = (ppc_cur_instruction >> 21) & 0x1F; if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitely cleared ppc_state.fpscr &= ~(0x80000000UL >> crf_d); } - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_mtfsb0(); +template void dppc_interpreter::ppc_mtfsb0(); + +template void dppc_interpreter::ppc_mtfsb1() { int crf_d = (ppc_cur_instruction >> 21) & 0x1F; if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitely set ppc_state.fpscr |= (0x80000000UL >> crf_d); } - if (rc_flag) + if (rec) ppc_update_cr1(); } +template void dppc_interpreter::ppc_mtfsb1(); +template void dppc_interpreter::ppc_mtfsb1(); + void dppc_interpreter::ppc_mcrfs() { int crf_d = (ppc_cur_instruction >> 21) & 0x1C; int crf_s = (ppc_cur_instruction >> 16) & 0x1C; diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index e96dfdd..0000a9c 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -98,54 +98,55 @@ comparisons needed. This means loads of functions, but less CPU cycles needed to function (theoretically). **/ +template void dppc_interpreter::ppc_addi() { ppc_grab_regsdasimm(ppc_cur_instruction); - ppc_state.gpr[reg_d] = (reg_a == 0) ? simm : (ppc_result_a + simm); + 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_addic() { ppc_grab_regsdasimm(ppc_cur_instruction); uint32_t ppc_result_d = (ppc_result_a + simm); ppc_carry(ppc_result_a, ppc_result_d); + if (rec) + ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_addicdot() { - ppc_grab_regsdasimm(ppc_cur_instruction); - uint32_t ppc_result_d = ppc_result_a + simm; - ppc_changecrf0(ppc_result_d); - ppc_carry(ppc_result_a, ppc_result_d); - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - -void dppc_interpreter::ppc_addis() { - ppc_grab_regsdasimm(ppc_cur_instruction); - ppc_state.gpr[reg_d] = (reg_a == 0) ? (simm << 16) : (ppc_result_a + (simm << 16)); -} +template void dppc_interpreter::ppc_addic(); +template void dppc_interpreter::ppc_addic();; +template void dppc_interpreter::ppc_add() { ppc_grab_regsdab(ppc_cur_instruction); uint32_t ppc_result_d = ppc_result_a + ppc_result_b; - if (oe_flag) + + if (carry) + ppc_carry(ppc_result_a, ppc_result_d); + if (rec) ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - if (rc_flag) + if (ov) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_addc() { - ppc_grab_regsdab(ppc_cur_instruction); - uint32_t ppc_result_d = ppc_result_a + ppc_result_b; - ppc_carry(ppc_result_a, ppc_result_d); - - if (oe_flag) - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - if (rc_flag) - ppc_changecrf0(ppc_result_d); - - 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_adde() { ppc_grab_regsdab(ppc_cur_instruction); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); @@ -157,14 +158,20 @@ void dppc_interpreter::ppc_adde() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - if (oe_flag) + if (ov) ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_addme() { ppc_grab_regsda(ppc_cur_instruction); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); @@ -176,14 +183,20 @@ void dppc_interpreter::ppc_addme() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - if (oe_flag) + if (ov) ppc_setsoov(ppc_result_a, 0, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_addze() { ppc_grab_regsda(ppc_cur_instruction); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); @@ -195,38 +208,18 @@ void dppc_interpreter::ppc_addze() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - if (oe_flag) + if (ov) ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_subf() { - ppc_grab_regsdab(ppc_cur_instruction); - uint32_t ppc_result_d = ppc_result_b - ppc_result_a; - - if (oe_flag) - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - if (rc_flag) - ppc_changecrf0(ppc_result_d); - - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - -void dppc_interpreter::ppc_subfc() { - ppc_grab_regsdab(ppc_cur_instruction); - uint32_t ppc_result_d = ppc_result_b - ppc_result_a; - ppc_carry_sub(ppc_result_a, ppc_result_b); - - if (oe_flag) - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - if (rc_flag) - ppc_changecrf0(ppc_result_d); - - 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(); void dppc_interpreter::ppc_subfic() { ppc_grab_regsdasimm(ppc_cur_instruction); @@ -238,6 +231,31 @@ void dppc_interpreter::ppc_subfic() { ppc_store_iresult_reg(reg_d, ppc_result_d); } +template +void dppc_interpreter::ppc_subf() { + ppc_grab_regsdab(ppc_cur_instruction); + uint32_t ppc_result_d = ppc_result_b - ppc_result_a; + + if (carry) + ppc_carry_sub(ppc_result_a, ppc_result_b); + if (ov) + ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rec) + ppc_changecrf0(ppc_result_d); + + 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_subfe() { ppc_grab_regsdab(ppc_cur_instruction); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); @@ -247,14 +265,20 @@ void dppc_interpreter::ppc_subfe() { else ppc_carry(~ppc_result_a, ppc_result_d); - if (oe_flag) + if (ov) ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_subfme() { ppc_grab_regsda(ppc_cur_instruction); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); @@ -265,19 +289,25 @@ void dppc_interpreter::ppc_subfme() { else ppc_state.spr[SPR::XER] |= XER::CA; - if (oe_flag) { + if (ov) { if (ppc_result_d == ppc_result_a && int32_t(ppc_result_d) > 0) ppc_state.spr[SPR::XER] |= XER::SO | XER::OV; else ppc_state.spr[SPR::XER] &= ~XER::OV; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_subfze() { ppc_grab_regsda(ppc_cur_instruction); uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA); @@ -288,154 +318,122 @@ void dppc_interpreter::ppc_subfze() { else ppc_state.spr[SPR::XER] &= ~XER::CA; - if (oe_flag) { + if (ov) { if (ppc_result_d && ppc_result_d == ppc_result_a) ppc_state.spr[SPR::XER] |= XER::SO | XER::OV; else ppc_state.spr[SPR::XER] &= ~XER::OV; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_and() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ppc_result_d & ppc_result_b; +template void dppc_interpreter::ppc_subfze();; +template void dppc_interpreter::ppc_subfze(); +template void dppc_interpreter::ppc_subfze(); +template void dppc_interpreter::ppc_subfze(); - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_andc() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ppc_result_d & ~(ppc_result_b); - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_andidot() { +template +void dppc_interpreter::ppc_andirc() { ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = ppc_result_d & uimm; + 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); -} +} -void dppc_interpreter::ppc_andisdot() { - ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = ppc_result_d & (uimm << 16); - ppc_changecrf0(ppc_result_a); - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_nand() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ~(ppc_result_d & ppc_result_b); - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_or() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ppc_result_d | ppc_result_b; - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_orc() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ppc_result_d | ~(ppc_result_b); - - if (rc_flag) - 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_ori() { ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = ppc_result_d | uimm; + ppc_result_a = shift ? (ppc_result_d ^ (uimm << 16)) : (ppc_result_d ^ uimm); ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_oris() { - ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = (uimm << 16) | ppc_result_d; - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_eqv() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ~(ppc_result_d ^ ppc_result_b); - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_nor() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ~(ppc_result_d | ppc_result_b); - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - ppc_store_iresult_reg(reg_a, ppc_result_a); -} - -void dppc_interpreter::ppc_xor() { - ppc_grab_regssab(ppc_cur_instruction); - ppc_result_a = ppc_result_d ^ ppc_result_b; - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - 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_xori() { ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = ppc_result_d ^ uimm; + ppc_result_a = shift ? (ppc_result_d ^ (uimm << 16)) : (ppc_result_d ^ uimm); ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_xoris() { - ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = ppc_result_d ^ (uimm << 16); +template void dppc_interpreter::ppc_xori(); +template void dppc_interpreter::ppc_xori(); + +template +void dppc_interpreter::ppc_do_bool() { + ppc_grab_regssab(ppc_cur_instruction); + if (bool_op == bool_fun::bool_and) + ppc_result_a = ppc_result_d & ppc_result_b; + else if (bool_op == bool_fun::bool_andc) + ppc_result_a = ppc_result_d & ~(ppc_result_b); + else if (bool_op == bool_fun::bool_eqv) + ppc_result_a = ~(ppc_result_d ^ ppc_result_b); + else if (bool_op == bool_fun::bool_nand) + ppc_result_a = ~(ppc_result_d & ppc_result_b); + else if (bool_op == bool_fun::bool_nor) + ppc_result_a = ~(ppc_result_d | ppc_result_b); + else if (bool_op == bool_fun::bool_or) + ppc_result_a = ppc_result_d | ppc_result_b; + else if (bool_op == bool_fun::bool_orc) + ppc_result_a = ppc_result_d | ~(ppc_result_b); + else if (bool_op == bool_fun::bool_xor) + ppc_result_a = ppc_result_d ^ ppc_result_b; + + if (rec) + ppc_changecrf0(ppc_result_a); + ppc_store_iresult_reg(reg_a, ppc_result_a); } +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); + +template void dppc_interpreter::ppc_neg() { ppc_grab_regsda(ppc_cur_instruction); uint32_t ppc_result_d = ~(ppc_result_a) + 1; - if (oe_flag) { + if (ov) { if (ppc_result_a == 0x80000000) ppc_state.spr[SPR::XER] |= 0xC0000000; else ppc_state.spr[SPR::XER] &= 0xBFFFFFFF; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_cntlzw() { ppc_grab_regssa(ppc_cur_instruction); @@ -455,40 +453,52 @@ void dppc_interpreter::ppc_cntlzw() { #endif ppc_result_a = lead; - if (rc_flag) { + if (rec) { ppc_changecrf0(ppc_result_a); } 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_mulhwu() { ppc_grab_regsdab(ppc_cur_instruction); uint64_t product = uint64_t(ppc_result_a) * uint64_t(ppc_result_b); uint32_t ppc_result_d = uint32_t(product >> 32); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_mulhw() { ppc_grab_regsdab(ppc_cur_instruction); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(ppc_result_b)); uint32_t ppc_result_d = product >> 32; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_mullw() { ppc_grab_regsdab(ppc_cur_instruction); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(ppc_result_b)); - if (oe_flag) { + if (ov) { if (product != int64_t(int32_t(product))) { ppc_state.spr[SPR::XER] |= 0xC0000000UL; } else { @@ -498,12 +508,17 @@ void dppc_interpreter::ppc_mullw() { uint32_t ppc_result_d = (uint32_t)product; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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(); + void dppc_interpreter::ppc_mulli() { ppc_grab_regsdasimm(ppc_cur_instruction); int64_t product = int64_t(int32_t(ppc_result_a)) * int64_t(int32_t(simm)); @@ -511,6 +526,7 @@ void dppc_interpreter::ppc_mulli() { ppc_store_iresult_reg(reg_d, ppc_result_d); } +template void dppc_interpreter::ppc_divw() { uint32_t ppc_result_d; ppc_grab_regsdab(ppc_cur_instruction); @@ -519,28 +535,34 @@ void dppc_interpreter::ppc_divw() { ppc_result_d = 0; // tested on G4 in Mac OS X 10.4 and Open Firmware. // ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */ - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] |= 0xC0000000; } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) { ppc_result_d = 0; // tested on G4 in Mac OS X 10.4 and Open Firmware. - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] |= 0xC0000000; } else { /* normal signed devision */ ppc_result_d = int32_t(ppc_result_a) / int32_t(ppc_result_b); - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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_divwu() { uint32_t ppc_result_d; ppc_grab_regsdab(ppc_cur_instruction); @@ -548,54 +570,54 @@ void dppc_interpreter::ppc_divwu() { if (!ppc_result_b) { /* division by zero */ ppc_result_d = 0; - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] |= 0xC0000000; - if (rc_flag) + if (rec) ppc_state.cr |= 0x20000000; } else { ppc_result_d = ppc_result_a / ppc_result_b; - if (oe_flag) + if (ov) ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_d); 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(); + // Value shifting -void dppc_interpreter::ppc_slw() { +template +void dppc_interpreter::ppc_shift() { ppc_grab_regssab(ppc_cur_instruction); if (ppc_result_b & 0x20) { ppc_result_a = 0; - } else { - ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F); + } + else { + ppc_result_a = left ? (ppc_result_d << (ppc_result_b & 0x1F)) + : (ppc_result_d >> (ppc_result_b & 0x1F)); } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_srw() { - ppc_grab_regssab(ppc_cur_instruction); - if (ppc_result_b & 0x20) { - ppc_result_a = 0; - } else { - ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F); - } - - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - 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_sraw() { ppc_grab_regssab(ppc_cur_instruction); @@ -614,12 +636,16 @@ void dppc_interpreter::ppc_sraw() { ppc_state.spr[SPR::XER] |= XER::CA; } - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); 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_srawi() { ppc_grab_regssa(ppc_cur_instruction); uint32_t shift = (ppc_cur_instruction >> 11) & 0x1F; @@ -632,12 +658,15 @@ void dppc_interpreter::ppc_srawi() { ppc_result_a = int32_t(ppc_result_d) >> shift; - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } +template void dppc_interpreter::ppc_srawi(); +template void dppc_interpreter::ppc_srawi();; + /** 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) { uint32_t m1 = 0xFFFFFFFFUL >> rot_mb; @@ -992,24 +1021,21 @@ void dppc_interpreter::ppc_mcrxr() { ppc_state.spr[SPR::XER] &= 0x0FFFFFFF; } -void dppc_interpreter::ppc_extsb() { +template +void dppc_interpreter::ppc_exts() { ppc_grab_regssa(ppc_cur_instruction); - ppc_result_a = int32_t(int8_t(ppc_result_d)); + ppc_result_a = int32_t(T(ppc_result_d)); - if (rc_flag) + if (rec) ppc_changecrf0(ppc_result_a); ppc_store_iresult_reg(reg_a, ppc_result_a); } -void dppc_interpreter::ppc_extsh() { - ppc_grab_regssa(ppc_cur_instruction); - ppc_result_a = int32_t(int16_t(ppc_result_d)); - if (rc_flag) - ppc_changecrf0(ppc_result_a); - - 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(); // Branching Instructions @@ -1028,10 +1054,10 @@ 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(); +template void dppc_interpreter::ppc_b(); +template void dppc_interpreter::ppc_b(); +template void dppc_interpreter::ppc_b(); template void dppc_interpreter::ppc_bc() { @@ -1059,10 +1085,10 @@ 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(); +template void dppc_interpreter::ppc_bc(); +template void dppc_interpreter::ppc_bc(); +template void dppc_interpreter::ppc_bc(); template void dppc_interpreter::ppc_bcctr() { @@ -1094,10 +1120,10 @@ 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(); +template void dppc_interpreter::ppc_bcctr(); +template void dppc_interpreter::ppc_bcctr(); +template void dppc_interpreter::ppc_bcctr(); template void dppc_interpreter::ppc_bclr() { @@ -1121,8 +1147,8 @@ 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(); +template void dppc_interpreter::ppc_bclr(); // Compare Instructions @@ -1360,10 +1386,12 @@ void dppc_interpreter::ppc_sync() { void dppc_interpreter::ppc_icbi() { /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_dcbf() { /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_dcbi() { @@ -1371,10 +1399,12 @@ void dppc_interpreter::ppc_dcbi() { num_supervisor_instrs++; #endif /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_dcbst() { /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_dcbt() { @@ -1404,7 +1434,8 @@ void dppc_interpreter::ppc_dcbz() { // Integer Load and Store Functions -void dppc_interpreter::ppc_stb() { +template +void dppc_interpreter::ppc_st() { #ifdef CPU_PROFILING num_int_stores++; #endif @@ -1412,20 +1443,28 @@ void dppc_interpreter::ppc_stb() { ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += reg_a ? ppc_result_a : 0; mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_byte(ppc_effective_address, ppc_result_d); } -void dppc_interpreter::ppc_stbx() { +template void dppc_interpreter::ppc_st(); +template void dppc_interpreter::ppc_st(); +template void dppc_interpreter::ppc_st(); + +template +void dppc_interpreter::ppc_stx() { #ifdef CPU_PROFILING num_int_stores++; #endif ppc_grab_regssab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_byte(ppc_effective_address, ppc_result_d); + mmu_write_vmem(ppc_effective_address, ppc_result_d); } -void dppc_interpreter::ppc_stbu() { +template void dppc_interpreter::ppc_stx(); +template void dppc_interpreter::ppc_stx(); +template void dppc_interpreter::ppc_stx(); + +template +void dppc_interpreter::ppc_stu() { #ifdef CPU_PROFILING num_int_stores++; #endif @@ -1433,80 +1472,35 @@ void dppc_interpreter::ppc_stbu() { if (reg_a != 0) { ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += ppc_result_a; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_byte(ppc_effective_address, ppc_result_d); + mmu_write_vmem(ppc_effective_address, ppc_result_d); ppc_state.gpr[reg_a] = ppc_effective_address; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_stbux() { +template void dppc_interpreter::ppc_stu(); +template void dppc_interpreter::ppc_stu(); +template void dppc_interpreter::ppc_stu(); + +template +void dppc_interpreter::ppc_stux() { #ifdef CPU_PROFILING num_int_stores++; #endif ppc_grab_regssab(ppc_cur_instruction); if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_byte(ppc_effective_address, ppc_result_d); + mmu_write_vmem(ppc_effective_address, ppc_result_d); ppc_state.gpr[reg_a] = ppc_effective_address; } else { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } -void dppc_interpreter::ppc_sth() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssa(ppc_cur_instruction); - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += reg_a ? ppc_result_a : 0; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_word(ppc_effective_address, ppc_result_d); -} - -void dppc_interpreter::ppc_sthu() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssa(ppc_cur_instruction); - if (reg_a != 0) { - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += ppc_result_a; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_word(ppc_effective_address, ppc_result_d); - ppc_state.gpr[reg_a] = ppc_effective_address; - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - -void dppc_interpreter::ppc_sthux() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssab(ppc_cur_instruction); - if (reg_a != 0) { - ppc_effective_address = ppc_result_a + ppc_result_b; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_word(ppc_effective_address, ppc_result_d); - ppc_state.gpr[reg_a] = ppc_effective_address; - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - -void dppc_interpreter::ppc_sthx() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssab(ppc_cur_instruction); - ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_word(ppc_effective_address, ppc_result_d); -} +template void dppc_interpreter::ppc_stux(); +template void dppc_interpreter::ppc_stux(); +template void dppc_interpreter::ppc_stux(); void dppc_interpreter::ppc_sthbrx() { #ifdef CPU_PROFILING @@ -1516,77 +1510,20 @@ void dppc_interpreter::ppc_sthbrx() { ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_result_d = uint32_t(BYTESWAP_16(uint16_t(ppc_result_d))); mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_word(ppc_effective_address, ppc_result_d); -} - -void dppc_interpreter::ppc_stw() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssa(ppc_cur_instruction); - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += reg_a ? ppc_result_a : 0; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_dword(ppc_effective_address, ppc_result_d); -} - -void dppc_interpreter::ppc_stwx() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssab(ppc_cur_instruction); - ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_dword(ppc_effective_address, ppc_result_d); } void dppc_interpreter::ppc_stwcx() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - if (rc_flag == 0) { - ppc_illegalop(); - } else { - ppc_grab_regssab(ppc_cur_instruction); - ppc_effective_address = (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] & 0x80000000UL) >> 3; // copy XER[SO] to CR0[SO] - if (ppc_state.reserve) { - mmu_write_vmem(ppc_effective_address, ppc_result_d); - ppc_state.reserve = false; - ppc_state.cr |= 0x20000000UL; // set CR0[EQ] - } - } -} - -void dppc_interpreter::ppc_stwu() { -#ifdef CPU_PROFILING - num_int_stores++; -#endif - ppc_grab_regssa(ppc_cur_instruction); - if (reg_a != 0) { - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += ppc_result_a; - mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_dword(ppc_effective_address, ppc_result_d); - ppc_state.gpr[reg_a] = ppc_effective_address; - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - -void dppc_interpreter::ppc_stwux() { #ifdef CPU_PROFILING num_int_stores++; #endif ppc_grab_regssab(ppc_cur_instruction); - if (reg_a != 0) { - ppc_effective_address = ppc_result_a + ppc_result_b; + ppc_effective_address = (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] & 0x80000000UL) >> 3; // copy XER[SO] to CR0[SO] + if (ppc_state.reserve) { mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_dword(ppc_effective_address, ppc_result_d); - ppc_state.gpr[reg_a] = ppc_effective_address; - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); + ppc_state.reserve = false; + ppc_state.cr |= 0x20000000UL; // set CR0[EQ] } } @@ -1598,7 +1535,6 @@ void dppc_interpreter::ppc_stwbrx() { ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_result_d = BYTESWAP_32(ppc_result_d); mmu_write_vmem(ppc_effective_address, ppc_result_d); - //mem_write_dword(ppc_effective_address, ppc_result_d); } void dppc_interpreter::ppc_stmw() { @@ -1616,24 +1552,28 @@ void dppc_interpreter::ppc_stmw() { for (; reg_s <= 31; reg_s++) { mmu_write_vmem(ppc_effective_address, ppc_state.gpr[reg_s]); - //mem_write_dword(ppc_effective_address, ppc_state.gpr[reg_s]); ppc_effective_address += 4; } } -void dppc_interpreter::ppc_lbz() { +template +void dppc_interpreter::ppc_lz() { #ifdef CPU_PROFILING num_int_loads++; #endif ppc_grab_regsda(ppc_cur_instruction); ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += reg_a ? ppc_result_a : 0; - //ppc_result_d = mem_grab_byte(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); + uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lbzu() { +template void dppc_interpreter::ppc_lz(); +template void dppc_interpreter::ppc_lz(); +template void dppc_interpreter::ppc_lz(); + +template +void dppc_interpreter::ppc_lzu() { #ifdef CPU_PROFILING num_int_loads++; #endif @@ -1641,8 +1581,7 @@ void dppc_interpreter::ppc_lbzu() { ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); if ((reg_a != reg_d) && reg_a != 0) { ppc_effective_address += ppc_result_a; - //ppc_result_d = mem_grab_byte(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); + uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); uint32_t ppc_result_a = ppc_effective_address; ppc_store_iresult_reg(reg_d, ppc_result_d); ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1651,26 +1590,35 @@ void dppc_interpreter::ppc_lbzu() { } } -void dppc_interpreter::ppc_lbzx() { +template void dppc_interpreter::ppc_lzu(); +template void dppc_interpreter::ppc_lzu(); +template void dppc_interpreter::ppc_lzu(); + +template +void dppc_interpreter::ppc_lzx() { #ifdef CPU_PROFILING num_int_loads++; #endif ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //ppc_result_d = mem_grab_byte(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); + // ppc_result_d = mem_grab_byte(ppc_effective_address); + uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lbzux() { +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_lzux() { #ifdef CPU_PROFILING num_int_loads++; #endif ppc_grab_regsdab(ppc_cur_instruction); if ((reg_a != reg_d) && reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; - //ppc_result_d = mem_grab_byte(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); + uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); ppc_result_a = ppc_effective_address; ppc_store_iresult_reg(reg_d, ppc_result_d); ppc_store_iresult_reg(reg_a, ppc_result_a); @@ -1679,64 +1627,9 @@ void dppc_interpreter::ppc_lbzux() { } } - -void dppc_interpreter::ppc_lhz() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsda(ppc_cur_instruction); - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += reg_a ? ppc_result_a : 0; - //ppc_result_d = mem_grab_word(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - -void dppc_interpreter::ppc_lhzu() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsda(ppc_cur_instruction); - if ((reg_a != reg_d) && reg_a != 0) { - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += ppc_result_a; - //ppc_result_d = mem_grab_word(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - uint32_t ppc_result_a = ppc_effective_address; - ppc_store_iresult_reg(reg_d, ppc_result_d); - ppc_store_iresult_reg(reg_a, ppc_result_a); - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - -void dppc_interpreter::ppc_lhzx() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsdab(ppc_cur_instruction); - ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //ppc_result_d = mem_grab_word(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - -void dppc_interpreter::ppc_lhzux() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsdab(ppc_cur_instruction); - if ((reg_a != reg_d) && reg_a != 0) { - ppc_effective_address = ppc_result_a + ppc_result_b; - //ppc_result_d = mem_grab_word(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - uint32_t ppc_result_a = ppc_effective_address; - ppc_store_iresult_reg(reg_d, ppc_result_d); - ppc_store_iresult_reg(reg_a, ppc_result_a); - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} +template void dppc_interpreter::ppc_lzux(void); +template void dppc_interpreter::ppc_lzux(void); +template void dppc_interpreter::ppc_lzux(void); void dppc_interpreter::ppc_lha() { #ifdef CPU_PROFILING @@ -1745,7 +1638,6 @@ void dppc_interpreter::ppc_lha() { ppc_grab_regsda(ppc_cur_instruction); ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += (reg_a ? ppc_result_a : 0); - //uint16_t val = mem_grab_word(ppc_effective_address); int16_t val = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, int32_t(val)); } @@ -1758,7 +1650,6 @@ void dppc_interpreter::ppc_lhau() { if ((reg_a != reg_d) && reg_a != 0) { ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += ppc_result_a; - //uint16_t val = mem_grab_word(ppc_effective_address); int16_t val = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, int32_t(val)); uint32_t ppc_result_a = ppc_effective_address; @@ -1775,7 +1666,6 @@ void dppc_interpreter::ppc_lhaux() { ppc_grab_regsdab(ppc_cur_instruction); if ((reg_a != reg_d) && reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; - // uint16_t val = mem_grab_word(ppc_effective_address); int16_t val = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, int32_t(val)); uint32_t ppc_result_a = ppc_effective_address; @@ -1792,7 +1682,6 @@ void dppc_interpreter::ppc_lhax() { #endif ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //uint16_t val = mem_grab_word(ppc_effective_address); int16_t val = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, int32_t(val)); } @@ -1803,81 +1692,20 @@ void dppc_interpreter::ppc_lhbrx() { #endif ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //ppc_result_d = (uint32_t)(BYTESWAP_16(mem_grab_word(ppc_effective_address))); uint32_t ppc_result_d = uint32_t(BYTESWAP_16(mmu_read_vmem(ppc_effective_address))); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lwz() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsda(ppc_cur_instruction); - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; - //ppc_result_d = mem_grab_dword(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - void dppc_interpreter::ppc_lwbrx() { #ifdef CPU_PROFILING num_int_loads++; #endif ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //ppc_result_d = BYTESWAP_32(mem_grab_dword(ppc_effective_address)); uint32_t ppc_result_d = BYTESWAP_32(mmu_read_vmem(ppc_effective_address)); ppc_store_iresult_reg(reg_d, ppc_result_d); } -void dppc_interpreter::ppc_lwzu() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsda(ppc_cur_instruction); - ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); - if ((reg_a != reg_d) && reg_a != 0) { - ppc_effective_address += ppc_result_a; - //ppc_result_d = mem_grab_dword(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - ppc_store_iresult_reg(reg_d, ppc_result_d); - uint32_t ppc_result_a = ppc_effective_address; - ppc_store_iresult_reg(reg_a, ppc_result_a); - } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - -void dppc_interpreter::ppc_lwzx() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsdab(ppc_cur_instruction); - ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); - //ppc_result_d = mem_grab_dword(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - ppc_store_iresult_reg(reg_d, ppc_result_d); -} - -void dppc_interpreter::ppc_lwzux() { -#ifdef CPU_PROFILING - num_int_loads++; -#endif - ppc_grab_regsdab(ppc_cur_instruction); - if ((reg_a != reg_d) && reg_a != 0) { - ppc_effective_address = ppc_result_a + ppc_result_b; - // ppc_result_d = mem_grab_dword(ppc_effective_address); - uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); - uint32_t ppc_result_a = ppc_effective_address; - ppc_store_iresult_reg(reg_d, ppc_result_d); - ppc_store_iresult_reg(reg_a, ppc_result_a); - } - else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } -} - void dppc_interpreter::ppc_lwarx() { #ifdef CPU_PROFILING num_int_loads++; @@ -1886,7 +1714,6 @@ void dppc_interpreter::ppc_lwarx() { ppc_grab_regsdab(ppc_cur_instruction); ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0); ppc_state.reserve = true; - //ppc_result_d = mem_grab_dword(ppc_effective_address); uint32_t ppc_result_d = mmu_read_vmem(ppc_effective_address); ppc_store_iresult_reg(reg_d, ppc_result_d); } @@ -1900,7 +1727,6 @@ void dppc_interpreter::ppc_lmw() { ppc_effective_address += (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] = mem_grab_dword(ppc_effective_address); ppc_state.gpr[reg_d] = mmu_read_vmem(ppc_effective_address); ppc_effective_address += 4; reg_d++; @@ -2111,6 +1937,7 @@ void dppc_interpreter::ppc_tlbia() { num_supervisor_instrs++; #endif /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_tlbld() { @@ -2118,6 +1945,7 @@ void dppc_interpreter::ppc_tlbld() { num_supervisor_instrs++; #endif /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_tlbli() { @@ -2125,6 +1953,7 @@ void dppc_interpreter::ppc_tlbli() { num_supervisor_instrs++; #endif /* placeholder */ + ppc_illegalop(); } void dppc_interpreter::ppc_tlbsync() { @@ -2132,4 +1961,5 @@ void dppc_interpreter::ppc_tlbsync() { num_supervisor_instrs++; #endif /* placeholder */ + ppc_illegalop(); } From 56314854653165faa09c8265d38bf7d50c8be15f Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 24 Mar 2024 14:06:07 -0700 Subject: [PATCH 2/9] Cleaning up templating --- cpu/ppc/ppcemu.h | 4 ++-- cpu/ppc/ppcexec.cpp | 43 ++++++++++++++++++++-------------------- cpu/ppc/ppcfpopcodes.cpp | 28 +++++++++++++------------- cpu/ppc/ppcopcodes.cpp | 32 +++++++++++------------------- 4 files changed, 50 insertions(+), 57 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index a9b1d6c..6939d54 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -405,8 +405,8 @@ enum field_setting { LK1 = 1, AA0 = 0, AA1 = 1, - LSHFT = 0, - RSHFT = 1, + SHFT0 = 0, + SHFT1 = 1, RC0 = 0, RC1 = 1, OV0 = 0, diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index ec0e6c6..9704a05 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -134,17 +134,18 @@ public: /** Opcode lookup tables. */ /** Primary opcode (bits 0...5) lookup table. */ -static PPCOpcode OpcodeGrabber[] = { + static PPCOpcode OpcodeGrabber[] = { ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_mulli, ppc_subfic, power_dozi, ppc_cmpli, ppc_cmpi, - ppc_addic, ppc_addic, - ppc_addi, ppc_addi, - ppc_opcode16, ppc_sc, ppc_opcode18, ppc_opcode19, + ppc_addic, ppc_addic, + ppc_addi, ppc_addi, + ppc_opcode16, ppc_sc, + ppc_opcode18, ppc_opcode19, ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm, - ppc_ori, ppc_ori, - ppc_xori, ppc_xori, - ppc_andirc, ppc_andirc, + ppc_ori, ppc_ori, + ppc_xori, ppc_xori, + ppc_andirc, ppc_andirc, ppc_illegalop, ppc_opcode31, ppc_lz, ppc_lzu, ppc_lz, ppc_lzu, @@ -161,17 +162,17 @@ static PPCOpcode OpcodeGrabber[] = { }; /** Lookup tables for branch instructions. */ -static PPCOpcode SubOpcode16Grabber[] = { - dppc_interpreter::ppc_bc, //bc - dppc_interpreter::ppc_bc, //bcl - dppc_interpreter::ppc_bc, //bca - dppc_interpreter::ppc_bc}; //bcla +const static PPCOpcode SubOpcode16Grabber[] = { + dppc_interpreter::ppc_bc, // bc + dppc_interpreter::ppc_bc, // bcl + dppc_interpreter::ppc_bc, // bca + dppc_interpreter::ppc_bc}; // bcla -static PPCOpcode SubOpcode18Grabber[] = { - dppc_interpreter::ppc_b, //b - dppc_interpreter::ppc_b, //bl - dppc_interpreter::ppc_b, //ba - dppc_interpreter::ppc_b}; //bla +const static PPCOpcode SubOpcode18Grabber[] = { + dppc_interpreter::ppc_b, // b + dppc_interpreter::ppc_b, // bl + dppc_interpreter::ppc_b, // ba + dppc_interpreter::ppc_b}; // bla /** Instructions decoding tables for integer, single floating-point, and double-floating point ops respectively */ @@ -690,8 +691,8 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[620] = ppc_eciwx; SubOpcode31Grabber[876] = ppc_ecowx; - SubOpcode31Grabber[48] = ppc_shift; - SubOpcode31Grabber[49] = ppc_shift; + SubOpcode31Grabber[48] = ppc_shift; + SubOpcode31Grabber[49] = ppc_shift; SubOpcode31Grabber[56] = ppc_do_bool; SubOpcode31Grabber[57] = ppc_do_bool; SubOpcode31Grabber[120] = ppc_do_bool; @@ -706,8 +707,8 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[825] = ppc_do_bool; SubOpcode31Grabber[888] = ppc_do_bool; SubOpcode31Grabber[889] = ppc_do_bool; - SubOpcode31Grabber[1072] = ppc_shift; - SubOpcode31Grabber[1073] = ppc_shift; + SubOpcode31Grabber[1072] = ppc_shift; + SubOpcode31Grabber[1073] = ppc_shift; SubOpcode31Grabber[1584] = ppc_sraw; SubOpcode31Grabber[1585] = ppc_sraw; SubOpcode31Grabber[1648] = ppc_srawi; diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index bb36dcf..4c2a56f 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -886,8 +886,8 @@ void dppc_interpreter::ppc_fmr() { ppc_update_cr1(); } -template void dppc_interpreter::ppc_fmr(); -template void dppc_interpreter::ppc_fmr(); +template void dppc_interpreter::ppc_fmr(); +template void dppc_interpreter::ppc_fmr(); template void dppc_interpreter::ppc_mffs() { @@ -899,10 +899,10 @@ 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(); +template void dppc_interpreter::ppc_mffs(); +template void dppc_interpreter::ppc_mffs(); +template void dppc_interpreter::ppc_mffs(); template void dppc_interpreter::ppc_mtfsf() { @@ -934,8 +934,8 @@ 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(); +template void dppc_interpreter::ppc_mtfsf(); template void dppc_interpreter::ppc_mtfsfi() { @@ -954,8 +954,8 @@ 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(); +template void dppc_interpreter::ppc_mtfsfi(); template void dppc_interpreter::ppc_mtfsb0() { @@ -968,8 +968,8 @@ 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(); +template void dppc_interpreter::ppc_mtfsb0(); template void dppc_interpreter::ppc_mtfsb1() { @@ -982,8 +982,8 @@ 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(); +template void dppc_interpreter::ppc_mtfsb1(); void dppc_interpreter::ppc_mcrfs() { int crf_d = (ppc_cur_instruction >> 21) & 0x1C; diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 0000a9c..1d27906 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -107,8 +107,8 @@ void dppc_interpreter::ppc_addi() { 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(); +template void dppc_interpreter::ppc_addi(); template void dppc_interpreter::ppc_addic() { @@ -344,8 +344,8 @@ void dppc_interpreter::ppc_andirc() { 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(); +template void dppc_interpreter::ppc_andirc(); template void dppc_interpreter::ppc_ori() { @@ -354,8 +354,8 @@ void dppc_interpreter::ppc_ori() { 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(); +template void dppc_interpreter::ppc_ori(); template void dppc_interpreter::ppc_xori() { @@ -364,8 +364,8 @@ void dppc_interpreter::ppc_xori() { 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(); +template void dppc_interpreter::ppc_xori(); template void dppc_interpreter::ppc_do_bool() { @@ -612,10 +612,10 @@ 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(); +template void dppc_interpreter::ppc_shift(); +template void dppc_interpreter::ppc_shift(); +template void dppc_interpreter::ppc_shift(); template void dppc_interpreter::ppc_sraw() { @@ -1386,12 +1386,10 @@ void dppc_interpreter::ppc_sync() { void dppc_interpreter::ppc_icbi() { /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_dcbf() { /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_dcbi() { @@ -1399,12 +1397,10 @@ void dppc_interpreter::ppc_dcbi() { num_supervisor_instrs++; #endif /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_dcbst() { /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_dcbt() { @@ -1937,7 +1933,6 @@ void dppc_interpreter::ppc_tlbia() { num_supervisor_instrs++; #endif /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_tlbld() { @@ -1945,7 +1940,6 @@ void dppc_interpreter::ppc_tlbld() { num_supervisor_instrs++; #endif /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_tlbli() { @@ -1953,7 +1947,6 @@ void dppc_interpreter::ppc_tlbli() { num_supervisor_instrs++; #endif /* placeholder */ - ppc_illegalop(); } void dppc_interpreter::ppc_tlbsync() { @@ -1961,5 +1954,4 @@ void dppc_interpreter::ppc_tlbsync() { num_supervisor_instrs++; #endif /* placeholder */ - ppc_illegalop(); } From 30802affd4cb012a291d4a59b03368300c639692 Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:24:36 -0700 Subject: [PATCH 3/9] Continued fixes for tables --- cpu/ppc/ppcexec.cpp | 34 +++++----- cpu/ppc/ppcfpopcodes.cpp | 4 -- cpu/ppc/ppcmacros.h | 3 + cpu/ppc/ppcopcodes.cpp | 134 +++++++++++++++++++-------------------- 4 files changed, 88 insertions(+), 87 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 9704a05..d32f3b7 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -261,23 +261,23 @@ void ppc_opcode19() { break; case 1056: if (for601) - ppc_bcctr(); + ppc_bcctr(); else - ppc_bcctr(); + ppc_bcctr(); break; case 1057: if (for601) - ppc_bcctr(); + ppc_bcctr(); else - ppc_bcctr(); + ppc_bcctr(); break; default: ppc_illegalop(); } } -template void ppc_opcode19(); -template void ppc_opcode19(); +template void ppc_opcode19(); +template void ppc_opcode19(); void ppc_opcode31() { uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL; @@ -603,15 +603,15 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[1040] = ppc_subf; SubOpcode31Grabber[1041] = ppc_subf; SubOpcode31Grabber[1104] = ppc_subf; - SubOpcode31Grabber[1105] = ppc_subf; + SubOpcode31Grabber[1105] = ppc_subf; SubOpcode31Grabber[1232] = ppc_neg; SubOpcode31Grabber[1233] = ppc_neg; SubOpcode31Grabber[1296] = ppc_subfe; SubOpcode31Grabber[1297] = ppc_subfe; SubOpcode31Grabber[1424] = ppc_subfze; SubOpcode31Grabber[1425] = ppc_subfze; - SubOpcode31Grabber[464] = ppc_subfme; - SubOpcode31Grabber[465] = ppc_subfme; + SubOpcode31Grabber[1488] = ppc_subfme; + SubOpcode31Grabber[1489] = ppc_subfme; SubOpcode31Grabber[20] = ppc_add; SubOpcode31Grabber[21] = ppc_add; @@ -650,8 +650,8 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[1495] = ppc_mullw; SubOpcode31Grabber[1942] = ppc_divwu; SubOpcode31Grabber[1943] = ppc_divwu; - SubOpcode31Grabber[2006] = ppc_divw; - SubOpcode31Grabber[2007] = ppc_divw; + SubOpcode31Grabber[2006] = ppc_divw; + SubOpcode31Grabber[2007] = ppc_divw; SubOpcode31Grabber[40] = ppc_lwarx; SubOpcode31Grabber[46] = ppc_lzx; @@ -707,16 +707,18 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[825] = ppc_do_bool; SubOpcode31Grabber[888] = ppc_do_bool; SubOpcode31Grabber[889] = ppc_do_bool; + SubOpcode31Grabber[952] = ppc_do_bool; + SubOpcode31Grabber[953] = ppc_do_bool; SubOpcode31Grabber[1072] = ppc_shift; SubOpcode31Grabber[1073] = ppc_shift; SubOpcode31Grabber[1584] = ppc_sraw; SubOpcode31Grabber[1585] = ppc_sraw; SubOpcode31Grabber[1648] = ppc_srawi; SubOpcode31Grabber[1649] = ppc_srawi; - SubOpcode31Grabber[1844] = ppc_exts; - SubOpcode31Grabber[1845] = ppc_exts; - SubOpcode31Grabber[1908] = ppc_exts; - SubOpcode31Grabber[1909] = ppc_exts; + SubOpcode31Grabber[1844] = ppc_exts; + SubOpcode31Grabber[1845] = ppc_exts; + SubOpcode31Grabber[1908] = ppc_exts; + SubOpcode31Grabber[1909] = ppc_exts; SubOpcode31Grabber[52] = ppc_cntlzw; SubOpcode31Grabber[53] = ppc_cntlzw; @@ -880,7 +882,7 @@ void initialize_ppc_opcode_tables() { SubOpcode63Grabber[i + 46] = ppc_fsel; SubOpcode63Grabber[i + 47] = ppc_fsel; SubOpcode63Grabber[i + 50] = ppc_fmul; - SubOpcode63Grabber[i + 50] = ppc_fmul; + SubOpcode63Grabber[i + 51] = ppc_fmul; SubOpcode63Grabber[i + 56] = ppc_fmsub; SubOpcode63Grabber[i + 57] = ppc_fmsub; SubOpcode63Grabber[i + 58] = ppc_fmadd; diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index 4c2a56f..76a74fc 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -30,12 +30,8 @@ along with this program. If not, see . #include #include -// Used for FP calcs - // Storage and register retrieval functions for the floating point functions. -#define GET_FPR(reg) ppc_state.fpr[(reg)].dbl64_r - double fp_return_double(uint32_t reg) { return ppc_state.fpr[reg].dbl64_r; } diff --git a/cpu/ppc/ppcmacros.h b/cpu/ppc/ppcmacros.h index 1630f95..4db787d 100644 --- a/cpu/ppc/ppcmacros.h +++ b/cpu/ppc/ppcmacros.h @@ -112,6 +112,9 @@ along with this program. If not, see . int reg_d = (opcode >> 21) & 31; \ int reg_b = (opcode >> 11) & 31; +#define GET_FPR(reg) \ + ppc_state.fpr[(reg)].dbl64_r + #define ppc_grab_regsfpdiab(opcode) \ int reg_d = (opcode >> 21) & 31; \ int reg_a = (opcode >> 16) & 31; \ diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 1d27906..a1a9093 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -166,10 +166,10 @@ 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(); +template void dppc_interpreter::ppc_adde(); +template void dppc_interpreter::ppc_adde(); +template void dppc_interpreter::ppc_adde(); template void dppc_interpreter::ppc_addme() { @@ -191,10 +191,10 @@ 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(); +template void dppc_interpreter::ppc_addme(); +template void dppc_interpreter::ppc_addme(); +template void dppc_interpreter::ppc_addme(); template void dppc_interpreter::ppc_addze() { @@ -216,10 +216,10 @@ 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(); +template void dppc_interpreter::ppc_addze(); +template void dppc_interpreter::ppc_addze(); +template void dppc_interpreter::ppc_addze(); void dppc_interpreter::ppc_subfic() { ppc_grab_regsdasimm(ppc_cur_instruction); @@ -246,14 +246,14 @@ 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(); +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_subfe() { @@ -273,10 +273,10 @@ 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(); +template void dppc_interpreter::ppc_subfe(); +template void dppc_interpreter::ppc_subfe(); +template void dppc_interpreter::ppc_subfe(); template void dppc_interpreter::ppc_subfme() { @@ -302,10 +302,10 @@ 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(); +template void dppc_interpreter::ppc_subfme(); +template void dppc_interpreter::ppc_subfme(); +template void dppc_interpreter::ppc_subfme(); template void dppc_interpreter::ppc_subfze() { @@ -331,10 +331,10 @@ 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(); +template void dppc_interpreter::ppc_subfze(); +template void dppc_interpreter::ppc_subfze(); +template void dppc_interpreter::ppc_subfze(); template void dppc_interpreter::ppc_andirc() { @@ -350,7 +350,7 @@ template void dppc_interpreter::ppc_andirc(); template void dppc_interpreter::ppc_ori() { ppc_grab_regssauimm(ppc_cur_instruction); - ppc_result_a = shift ? (ppc_result_d ^ (uimm << 16)) : (ppc_result_d ^ uimm); + ppc_result_a = shift ? (ppc_result_d | (uimm << 16)) : (ppc_result_d | uimm); ppc_store_iresult_reg(reg_a, ppc_result_a); } @@ -393,22 +393,22 @@ void dppc_interpreter::ppc_do_bool() { ppc_store_iresult_reg(reg_a, ppc_result_a); } -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); -template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); +template void dppc_interpreter::ppc_do_bool(); template void dppc_interpreter::ppc_neg() { @@ -429,9 +429,9 @@ 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(); +template void dppc_interpreter::ppc_neg(); +template void dppc_interpreter::ppc_neg(); +template void dppc_interpreter::ppc_neg(); template void dppc_interpreter::ppc_cntlzw() { @@ -514,10 +514,10 @@ 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(); +template void dppc_interpreter::ppc_mullw(); +template void dppc_interpreter::ppc_mullw(); +template void dppc_interpreter::ppc_mullw(); void dppc_interpreter::ppc_mulli() { ppc_grab_regsdasimm(ppc_cur_instruction); @@ -558,9 +558,9 @@ 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(); +template void dppc_interpreter::ppc_divw(); +template void dppc_interpreter::ppc_divw(); +template void dppc_interpreter::ppc_divw(); template void dppc_interpreter::ppc_divwu() { @@ -589,9 +589,9 @@ 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(); +template void dppc_interpreter::ppc_divwu(); +template void dppc_interpreter::ppc_divwu(); +template void dppc_interpreter::ppc_divwu(); // Value shifting @@ -626,7 +626,7 @@ void dppc_interpreter::ppc_sraw() { if (ppc_result_b & 0x20) { // fill rA with the sign bit of rS - uint32_t ppc_result_a = int32_t(ppc_result_d) >> 31; + ppc_result_a = int32_t(ppc_result_d) >> 31; if (ppc_result_a) // if rA is negative ppc_state.spr[SPR::XER] |= XER::CA; } else { @@ -1032,10 +1032,10 @@ 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(); +template void dppc_interpreter::ppc_exts(); +template void dppc_interpreter::ppc_exts(); +template void dppc_interpreter::ppc_exts(); // Branching Instructions From c781820bf675875c4cb9c796bd50ff75cd0e076a Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:43:14 -0700 Subject: [PATCH 4/9] Continued table fixes --- cpu/ppc/ppcexec.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index d32f3b7..d0f4d5f 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -725,7 +725,7 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[38] = ppc_mfcr; SubOpcode31Grabber[166] = ppc_mfmsr; - SubOpcode31Grabber[144] = ppc_mtcrf; + SubOpcode31Grabber[288] = ppc_mtcrf; SubOpcode31Grabber[292] = ppc_mtmsr; SubOpcode31Grabber[420] = ppc_mtsr; SubOpcode31Grabber[484] = ppc_mtsrin; @@ -809,13 +809,13 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[2000] = power_nabs; SubOpcode31Grabber[2001] = power_nabs; - SubOpcode31Grabber[306] = ppc_tlbie; - SubOpcode31Grabber[370] = ppc_tlbia; - SubOpcode31Grabber[566] = ppc_tlbsync; - SubOpcode31Grabber[854] = ppc_eieio; - SubOpcode31Grabber[982] = ppc_icbi; - SubOpcode31Grabber[978] = ppc_tlbld; - SubOpcode31Grabber[1010] = ppc_tlbli; + SubOpcode31Grabber[612] = ppc_tlbie; + SubOpcode31Grabber[740] = ppc_tlbia; + SubOpcode31Grabber[1132] = ppc_tlbsync; + SubOpcode31Grabber[1708] = ppc_eieio; + SubOpcode31Grabber[1964] = ppc_icbi; + SubOpcode31Grabber[1956] = ppc_tlbld; + SubOpcode31Grabber[2020] = ppc_tlbli; std::fill_n(SubOpcode59Grabber, 64, ppc_illegalop); SubOpcode59Grabber[36] = ppc_fdivs; From effe0198cecbcd02fb199eae703a3de0cbeef6e8 Mon Sep 17 00:00:00 2001 From: joevt Date: Sun, 24 Mar 2024 22:50:45 -0700 Subject: [PATCH 5/9] ppcexec: Fix bcctr templated parameters. --- cpu/ppc/ppcexec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index d0f4d5f..ab52873 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -263,11 +263,11 @@ void ppc_opcode19() { if (for601) ppc_bcctr(); else - ppc_bcctr(); + ppc_bcctr(); break; case 1057: if (for601) - ppc_bcctr(); + ppc_bcctr(); else ppc_bcctr(); break; From e2864ab08cd1f4f4ce9dcc4d70f3ff7e583493f0 Mon Sep 17 00:00:00 2001 From: joevt Date: Sun, 24 Mar 2024 23:20:18 -0700 Subject: [PATCH 6/9] ppcopcodes: Fix templated add. --- cpu/ppc/ppcopcodes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index a1a9093..7d7119f 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -130,9 +130,9 @@ void dppc_interpreter::ppc_add() { if (carry) ppc_carry(ppc_result_a, ppc_result_d); - if (rec) - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); if (ov) + ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); + if (rec) ppc_changecrf0(ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); } From b9aae485177d03ab42d9bc34fed46f80139e1366 Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 25 Mar 2024 01:03:11 -0700 Subject: [PATCH 7/9] ppcopcodes: Fix templated st. --- cpu/ppc/ppcopcodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 7d7119f..0db736e 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -1438,7 +1438,7 @@ void dppc_interpreter::ppc_st() { ppc_grab_regssa(ppc_cur_instruction); ppc_effective_address = int32_t(int16_t(ppc_cur_instruction)); ppc_effective_address += reg_a ? ppc_result_a : 0; - mmu_write_vmem(ppc_effective_address, ppc_result_d); + mmu_write_vmem(ppc_effective_address, ppc_result_d); } template void dppc_interpreter::ppc_st(); From 15a9ffd3406822eb9a23476c47bb0af3a2b599d2 Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 25 Mar 2024 03:42:44 -0700 Subject: [PATCH 8/9] ppcopcodes: Indent. From f08d9ba81e8d7db00087999e0f5e96c413027268 Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 25 Mar 2024 01:21:33 -0700 Subject: [PATCH 9/9] ppcexec: Fix templated lhzux. --- cpu/ppc/ppcexec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index ab52873..f4e2715 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -659,7 +659,7 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[174] = ppc_lzx; SubOpcode31Grabber[238] = ppc_lzux; SubOpcode31Grabber[558] = ppc_lzx; - SubOpcode31Grabber[662] = ppc_lzux; + SubOpcode31Grabber[622] = ppc_lzux; SubOpcode31Grabber[686] = ppc_lhax; SubOpcode31Grabber[750] = ppc_lhaux; SubOpcode31Grabber[1066] = ppc_lswx;