1
0
mirror of https://github.com/dingusdev/dingusppc.git synced 2025-03-24 09:30:55 +00:00

ppcexec: Simplify ppc_exec_inner.

One while loop instead of two.
One call to ppc_read_instruction instead of four.
This commit is contained in:
joevt 2024-12-17 04:45:46 -08:00 committed by dingusdev
parent 7b1ea17fb8
commit e63f928a3c

@ -264,62 +264,46 @@ typedef enum {
template <ppc_exec_type_t exec_type> template <ppc_exec_type_t exec_type>
static void ppc_exec_inner(uint32_t start_addr, uint32_t size) static void ppc_exec_inner(uint32_t start_addr, uint32_t size)
{ {
uint64_t max_cycles; uint64_t max_cycles = 0;
uint32_t page_start, eb_start, eb_end; uint32_t page_start, eb_start, eb_end = 0;
uint32_t opcode; uint32_t opcode;
uint8_t* pc_real; uint8_t* pc_real;
max_cycles = 0;
while (power_on) { while (power_on) {
if (exec_type == debug) if (exec_type == debug)
if (ppc_state.pc >= start_addr && ppc_state.pc < start_addr + size) if (ppc_state.pc >= start_addr && ppc_state.pc < start_addr + size)
break; break;
// define boundaries of the next execution block if (ppc_state.pc >= eb_end) {
// max execution block length = one memory page // define boundaries of the next execution block
eb_start = ppc_state.pc; // max execution block length = one memory page
page_start = eb_start & PPC_PAGE_MASK; eb_start = ppc_state.pc;
eb_end = page_start + PPC_PAGE_SIZE - 1; page_start = eb_start & PPC_PAGE_MASK;
exec_flags = 0; eb_end = page_start + PPC_PAGE_SIZE - 1;
exec_flags = 0;
pc_real = mmu_translate_imem(eb_start);
}
pc_real = mmu_translate_imem(eb_start);
opcode = ppc_read_instruction(pc_real); opcode = ppc_read_instruction(pc_real);
ppc_main_opcode(opcode);
if (g_icycles++ >= max_cycles || exec_timer)
max_cycles = process_events();
// interpret execution block if (exec_flags) {
while (power_on && ppc_state.pc < eb_end) { // define next execution block
if (exec_type == debug) eb_start = ppc_next_instruction_address;
if (ppc_state.pc >= start_addr && ppc_state.pc < start_addr + size) if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
break; pc_real += (int)eb_start - (int)ppc_state.pc;
ppc_main_opcode(opcode);
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
if (exec_flags) {
// define next execution block
eb_start = ppc_next_instruction_address;
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
pc_real += (int)eb_start - (int)ppc_state.pc;
opcode = ppc_read_instruction(pc_real);
} else {
page_start = eb_start & PPC_PAGE_MASK;
eb_end = page_start + PPC_PAGE_SIZE - 1;
pc_real = mmu_translate_imem(eb_start);
opcode = ppc_read_instruction(pc_real);
}
ppc_state.pc = eb_start;
exec_flags = 0;
} else { } else {
ppc_state.pc += 4; page_start = eb_start & PPC_PAGE_MASK;
pc_real += 4; eb_end = page_start + PPC_PAGE_SIZE - 1;
opcode = ppc_read_instruction(pc_real); pc_real = mmu_translate_imem(eb_start);
} }
ppc_state.pc = eb_start;
if (exec_type == until) exec_flags = 0;
if (ppc_state.pc == start_addr) } else { [[likely]]
break; ppc_state.pc += 4;
pc_real += 4;
} }
if (exec_type == until) if (exec_type == until)