diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index acb468e..d328fc9 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -536,14 +536,8 @@ extern void ppc_addicdot(); extern void ppc_addis(); extern void ppc_andidot(); extern void ppc_andisdot(); -extern void ppc_b(); -extern void ppc_ba(); -extern void ppc_bl(); -extern void ppc_bla(); -extern void ppc_bc(); -extern void ppc_bca(); -extern void ppc_bcl(); -extern void ppc_bcla(); +template extern void ppc_b(); +template extern void ppc_bc(); extern void ppc_cmpi(); extern void ppc_cmpli(); extern void ppc_lbz(); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 5beb7c7..770954a 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -151,16 +151,16 @@ static PPCOpcode OpcodeGrabber[] = { /** Lookup tables for branch instructions. */ static PPCOpcode SubOpcode16Grabber[] = { - dppc_interpreter::ppc_bc, - dppc_interpreter::ppc_bcl, - dppc_interpreter::ppc_bca, - dppc_interpreter::ppc_bcla}; + 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, - dppc_interpreter::ppc_bl, - dppc_interpreter::ppc_ba, - dppc_interpreter::ppc_bla}; + 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 */ diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 71fe289..5ec7a61 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -1116,32 +1116,27 @@ void dppc_interpreter::ppc_extsh() { // Branching Instructions +template void dppc_interpreter::ppc_b() { - int32_t adr_li = int32_t(ppc_cur_instruction << 6) >> 6; - ppc_next_instruction_address = uint32_t(ppc_state.pc + adr_li); + int32_t adr_li = int32_t((ppc_cur_instruction & ~3UL) << 6) >> 6; + + if (a) + ppc_next_instruction_address = adr_li; + else + ppc_next_instruction_address = uint32_t(ppc_state.pc + adr_li); + + if (l) + ppc_state.spr[SPR::LR] = uint32_t(ppc_state.pc + 4); + exec_flags = EXEF_BRANCH; } -void dppc_interpreter::ppc_bl() { - int32_t adr_li = int32_t((ppc_cur_instruction & ~3UL) << 6) >> 6; - ppc_next_instruction_address = uint32_t(ppc_state.pc + adr_li); - ppc_state.spr[SPR::LR] = uint32_t(ppc_state.pc + 4); - exec_flags = EXEF_BRANCH; -} - -void dppc_interpreter::ppc_ba() { - int32_t adr_li = int32_t((ppc_cur_instruction & ~3UL) << 6) >> 6; - ppc_next_instruction_address = adr_li; - exec_flags = EXEF_BRANCH; -} - -void dppc_interpreter::ppc_bla() { - int32_t adr_li = int32_t((ppc_cur_instruction & ~3UL) << 6) >> 6; - ppc_next_instruction_address = adr_li; - ppc_state.spr[SPR::LR] = uint32_t(ppc_state.pc + 4); - 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_bc() { uint32_t ctr_ok; uint32_t cnd_ok; @@ -1156,69 +1151,21 @@ void dppc_interpreter::ppc_bc() { cnd_ok = (br_bo & 0x10) | (!(ppc_state.cr & (0x80000000UL >> br_bi)) == !(br_bo & 0x08)); if (ctr_ok && cnd_ok) { - ppc_next_instruction_address = (ppc_state.pc + br_bd); + if (a) + ppc_next_instruction_address = br_bd; + else + ppc_next_instruction_address = uint32_t(ppc_state.pc + br_bd); exec_flags = EXEF_BRANCH; } + + if (l) + ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -void dppc_interpreter::ppc_bca() { - uint32_t ctr_ok; - uint32_t cnd_ok; - uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; - int32_t br_bd = int32_t(int16_t(ppc_cur_instruction & ~3UL)); - - if (!(br_bo & 0x04)) { - (ppc_state.spr[SPR::CTR])--; /* decrement CTR */ - } - ctr_ok = (br_bo & 0x04) | ((ppc_state.spr[SPR::CTR] != 0) == !(br_bo & 0x02)); - cnd_ok = (br_bo & 0x10) | (!(ppc_state.cr & (0x80000000UL >> br_bi)) == !(br_bo & 0x08)); - - if (ctr_ok && cnd_ok) { - ppc_next_instruction_address = br_bd; - exec_flags = EXEF_BRANCH; - } -} - -void dppc_interpreter::ppc_bcl() { - uint32_t ctr_ok; - uint32_t cnd_ok; - uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; - int32_t br_bd = int32_t(int16_t(ppc_cur_instruction & ~3UL)); - - if (!(br_bo & 0x04)) { - (ppc_state.spr[SPR::CTR])--; /* decrement CTR */ - } - ctr_ok = (br_bo & 0x04) | ((ppc_state.spr[SPR::CTR] != 0) == !(br_bo & 0x02)); - cnd_ok = (br_bo & 0x10) | (!(ppc_state.cr & (0x80000000UL >> br_bi)) == !(br_bo & 0x08)); - - if (ctr_ok && cnd_ok) { - ppc_next_instruction_address = (ppc_state.pc + br_bd); - exec_flags = EXEF_BRANCH; - } - ppc_state.spr[SPR::LR] = ppc_state.pc + 4; -} - -void dppc_interpreter::ppc_bcla() { - uint32_t ctr_ok; - uint32_t cnd_ok; - uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; - uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; - int32_t br_bd = int32_t(int16_t(ppc_cur_instruction & ~3UL)); - - if (!(br_bo & 0x04)) { - (ppc_state.spr[SPR::CTR])--; /* decrement CTR */ - } - ctr_ok = (br_bo & 0x04) | ((ppc_state.spr[SPR::CTR] != 0) == !(br_bo & 0x02)); - cnd_ok = (br_bo & 0x10) | (!(ppc_state.cr & (0x80000000UL >> br_bi)) == !(br_bo & 0x08)); - - if (ctr_ok && cnd_ok) { - ppc_next_instruction_address = br_bd; - exec_flags = EXEF_BRANCH; - } - ppc_state.spr[SPR::LR] = ppc_state.pc + 4; -} +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_bcctr() {