From 6b74e358dcc32dbef6845eb0c34ce22dd9f3308f Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 13 Jul 2020 23:39:31 +0200 Subject: [PATCH 01/20] WIP: basic 68k debugging environment. --- CMakeLists.txt | 9 +++- cpu/ppc/ppcemu.h | 2 +- cpu/ppc/ppcexec.cpp | 2 +- cpu/ppc/ppcopcodes.cpp | 2 +- debugger/debugger.cpp | 115 +++++++++++++++++++++++++++++++++++++---- devices/atirage.cpp | 2 + 6 files changed, 117 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 052b007..99c1839 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,11 @@ if (UNIX AND NOT APPLE) endif() endif() +find_package(PkgConfig REQUIRED) +pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.1) +include_directories(${CAPSTONE_INCLUDE_DIRS}) +link_directories(${CAPSTONE_LIBRARY_DIRS}) + add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/") add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/") add_subdirectory("${PROJECT_SOURCE_DIR}/devices/") @@ -64,7 +69,7 @@ target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/S cubeb) else() #target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() @@ -80,7 +85,7 @@ target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL cubeb) else() #target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() add_custom_command( diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 54f595d..7270bbc 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -481,7 +481,7 @@ extern void ppc_b(); extern void ppc_ba(); extern void ppc_bl(); extern void ppc_bla(); -extern void ppc_bc(); +extern void ppc_bc1(); extern void ppc_bca(); extern void ppc_bcl(); extern void ppc_bcla(); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 066ccfc..ee20032 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -82,7 +82,7 @@ static PPCOpcode OpcodeGrabber[] = { ppc_psq_st, ppc_psq_stu, ppc_illegalop, ppc_opcode63}; /** Lookup tables for branch instructions. */ -static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla}; +static PPCOpcode SubOpcode16Grabber[] = {ppc_bc1, ppc_bcl, ppc_bca, ppc_bcla}; static PPCOpcode SubOpcode18Grabber[] = {ppc_b, ppc_bl, ppc_ba, ppc_bla}; diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index bcfd278..0094db5 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -1416,7 +1416,7 @@ void ppc_bla() { bb_kind = BB_end_kind::BB_BRANCH; } -void ppc_bc() { +void ppc_bc1() { uint32_t ctr_ok; uint32_t cnd_ok; uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index 1c0ee2e..a041ba6 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -19,9 +19,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "../cpu/ppc/ppcdisasm.h" -#include "../cpu/ppc/ppcemu.h" -#include "../cpu/ppc/ppcmmu.h" #include #include #include @@ -30,6 +27,10 @@ along with this program. If not, see . #include #include #include +#include +#include "../cpu/ppc/ppcdisasm.h" +#include "../cpu/ppc/ppcemu.h" +#include "../cpu/ppc/ppcmmu.h" using namespace std; @@ -88,6 +89,42 @@ static void disasm(uint32_t count, uint32_t address) { } } +static void disasm_68k(uint32_t count, uint32_t address) { + csh cs_handle; + uint8_t code[8]; + size_t code_size; + uint64_t dis_addr; + + if (cs_open(CS_ARCH_M68K, CS_MODE_M68K_040, &cs_handle) != CS_ERR_OK) { + cout << "Capstone initialization error" << endl; + return; + } + + cs_insn* insn = cs_malloc(cs_handle); + + for (; count > 0; count--) { + for (int i = 0; i < sizeof(code); i++) { + code[i] = mem_read_dbg(address + i, 1); + } + + const uint8_t *code_ptr = code; + code_size = sizeof(code); + dis_addr = address; + + if (cs_disasm_iter(cs_handle, &code_ptr, &code_size, &dis_addr, insn)) { + cout << uppercase << hex << insn->address; + cout << " " << insn->mnemonic << " " << insn->op_str << endl; + address = dis_addr; + } else { + cout << "DS.W " << hex << ((code[0] << 8) | code[1]) << endl; + address += 2; + } + } + + cs_free(insn, 1); + cs_close(&cs_handle); +} + static void dump_mem(string& params) { int cell_size, chars_per_line; bool is_char; @@ -181,13 +218,42 @@ static void dump_mem(string& params) { cout << endl << endl; } +void print_68k_regs() +{ + int i; + string reg; + + for (i = 0; i < 8; i++) { + reg = "R" + to_string(i + 8); + cout << "D" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; + } + + for (i = 0; i < 7; i++) { + reg = "R" + to_string(i + 16); + cout << "A" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; + } + reg = "R1"; + cout << "A7 : " << uppercase << hex << get_reg(reg) << endl; + + reg = "R24"; + cout << "PC: " << uppercase << hex << get_reg(reg) - 2 << endl; + + reg = "R25"; + cout << "SR: " << uppercase << hex << ((get_reg(reg) & 0xFF) << 8) << endl; + + reg = "R26"; + cout << "CCR: " << uppercase << hex << get_reg(reg) << endl; +} + void enter_debugger() { string inp, cmd, addr_str, expr_str, reg_expr, last_cmd, reg_value_str, inst_string, inst_num_str; uint32_t addr, inst_grab; std::stringstream ss; - int log_level; + int log_level, context; size_t separator_pos; + context = 1; /* start with the PowerPC context */ + cout << "Welcome to the DingusPPC command line debugger." << endl; cout << "Please enter a command or 'help'." << endl << endl; @@ -220,7 +286,11 @@ void enter_debugger() { } #endif else if (cmd == "regs") { - print_gprs(); + if (context == 2) { + print_68k_regs(); + } else { + print_gprs(); + } } else if (cmd == "set") { ss >> expr_str; @@ -278,27 +348,52 @@ void enter_debugger() { } catch (invalid_argument& exc) { try { /* number conversion failed, trying reg name */ - addr = get_reg(addr_str); + if (context == 2 && (addr_str == "pc" || addr_str == "PC")) { + addr_str = "R24"; + addr = get_reg(addr_str) - 2; + } else { + addr = get_reg(addr_str); + } } catch (invalid_argument& exc) { cout << exc.what() << endl; continue; } } try { - disasm(inst_grab, addr); + if (context == 2) { + disasm_68k(inst_grab, addr); + } else { + disasm(inst_grab, addr); + } } catch (invalid_argument& exc) { cout << exc.what() << endl; } } else { /* disas without arguments defaults to disas 1,pc */ - addr_str = "PC"; - addr = get_reg(addr_str); - disasm(1, addr); + if (context == 2) { + addr_str = "R24"; + addr = get_reg(addr_str); + disasm_68k(1, addr - 2); + } else { + addr_str = "PC"; + addr = get_reg(addr_str); + disasm(1, addr); + } } } else if (cmd == "dump") { expr_str = ""; ss >> expr_str; dump_mem(expr_str); + } else if (cmd == "context") { + expr_str = ""; + ss >> expr_str; + if (expr_str == "ppc" || expr_str == "PPC") { + context = 1; + } else if (expr_str == "68k" || expr_str == "68K") { + context = 2; + } else { + cout << "Unknown debugging context: " << expr_str << endl; + } } else { cout << "Unknown command: " << cmd << endl; continue; diff --git a/devices/atirage.cpp b/devices/atirage.cpp index e85f0e6..f9e1eb7 100644 --- a/devices/atirage.cpp +++ b/devices/atirage.cpp @@ -170,6 +170,8 @@ uint32_t ATIRage::read_reg(uint32_t offset, uint32_t size) { uint32_t res; switch (offset & ~3) { + case ATI_GP_IO: + break; case ATI_DAC_REGS: if (offset == ATI_DAC_DATA) { this->block_io_regs[ATI_DAC_DATA] = From b9dcfef551048348dbdb2bd1222ac99433f85eb8 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 16 Jul 2020 14:26:34 +0200 Subject: [PATCH 02/20] debugger: debugging commands for 68k code. --- cpu/ppc/ppcemu.h | 1 + cpu/ppc/ppcexec.cpp | 60 ++++++++++++++++++++++++++++ debugger/debugger.cpp | 93 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 148 insertions(+), 6 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 7270bbc..f719298 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -677,6 +677,7 @@ extern void ppc_main_opcode(void); extern void ppc_exec(void); extern void ppc_exec_single(void); extern void ppc_exec_until(uint32_t goal_addr); +extern void ppc_exec_dbg(uint32_t start_addr, uint32_t size); /* debugging support API */ void print_gprs(void); /* print content of the general purpose registers */ diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index ee20032..9cc3ee8 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -669,6 +669,66 @@ again: } } +/** Execute PPC code until control is reached the specified region. */ +void ppc_exec_dbg(uint32_t start_addr, uint32_t size) +{ + uint32_t bb_start_la, page_start, delta; + uint8_t* pc_real; + + /* start new basic block */ + glob_bb_start_la = bb_start_la = ppc_state.pc; + bb_kind = BB_end_kind::BB_NONE; + + if (setjmp(exc_env)) { + /* reaching here means we got a low-level exception */ +#ifdef NEW_TBR_UPDATE_ALGO + cycles_count += ((ppc_state.pc - glob_bb_start_la) >> 2) + 1; + UPDATE_TBR_DEC +#else + timebase_counter += ((ppc_state.pc - glob_bb_start_la) >> 2) + 1; +#endif + glob_bb_start_la = bb_start_la = ppc_next_instruction_address; + pc_real = quickinstruction_translate(bb_start_la); + page_start = bb_start_la & 0xFFFFF000; + ppc_state.pc = bb_start_la; + bb_kind = BB_end_kind::BB_NONE; + goto again; + } + + /* initial MMU translation for the current code page. */ + pc_real = quickinstruction_translate(bb_start_la); + + /* set current code page limits */ + page_start = bb_start_la & 0xFFFFF000; + +again: + while (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size) { + ppc_main_opcode(); + if (bb_kind != BB_end_kind::BB_NONE) { +#ifdef NEW_TBR_UPDATE_ALGO + cycles_count += ((ppc_state.pc - bb_start_la) >> 2) + 1; + UPDATE_TBR_DEC +#else + timebase_counter += ((ppc_state.pc - bb_start_la) >> 2) + 1; +#endif + glob_bb_start_la = bb_start_la = ppc_next_instruction_address; + if ((ppc_next_instruction_address & 0xFFFFF000) != page_start) { + page_start = bb_start_la & 0xFFFFF000; + pc_real = quickinstruction_translate(bb_start_la); + } else { + pc_real += (int)bb_start_la - (int)ppc_state.pc; + ppc_set_cur_instruction(pc_real); + } + ppc_state.pc = bb_start_la; + bb_kind = BB_end_kind::BB_NONE; + } else { + ppc_state.pc += 4; + pc_real += 4; + ppc_set_cur_instruction(pc_real); + } + } +} + uint64_t instr_count, old_instr_count; diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index a041ba6..d828e96 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -72,6 +72,9 @@ static void show_help() { cout << " disas N,X -- disassemble N instructions starting at address X" << endl; cout << " X can be any number or a known register name" << endl; cout << " disas with no arguments defaults to disas 1,pc" << endl; + cout << " context X -- switch to the debugging context X." << endl; + cout << " X can be either 'ppc' (default) or '68k'" << endl; + cout << " Use 68k for debugging emulated 68k code only." << endl; cout << " quit -- quit the debugger" << endl << endl; cout << "Pressing ENTER will repeat last command." << endl; } @@ -91,7 +94,7 @@ static void disasm(uint32_t count, uint32_t address) { static void disasm_68k(uint32_t count, uint32_t address) { csh cs_handle; - uint8_t code[8]; + uint8_t code[10]; size_t code_size; uint64_t dis_addr; @@ -103,6 +106,7 @@ static void disasm_68k(uint32_t count, uint32_t address) { cs_insn* insn = cs_malloc(cs_handle); for (; count > 0; count--) { + /* prefetch opcode bytes (a 68k instruction can occupy 2...10 bytes) */ for (int i = 0; i < sizeof(code); i++) { code[i] = mem_read_dbg(address + i, 1); } @@ -112,8 +116,8 @@ static void disasm_68k(uint32_t count, uint32_t address) { dis_addr = address; if (cs_disasm_iter(cs_handle, &code_ptr, &code_size, &dis_addr, insn)) { - cout << uppercase << hex << insn->address; - cout << " " << insn->mnemonic << " " << insn->op_str << endl; + cout << uppercase << hex << insn->address << " "; + cout << setw(10) << left << insn->mnemonic << insn->op_str << endl; address = dis_addr; } else { cout << "DS.W " << hex << ((code[0] << 8) | code[1]) << endl; @@ -125,6 +129,75 @@ static void disasm_68k(uint32_t count, uint32_t address) { cs_close(&cs_handle); } +/* emulator opcode table size --> 512 KB */ +#define EMU_68K_TABLE_SIZE 0x80000 + +/** Execute one emulated 68k instruction. */ +void exec_single_68k() +{ + string reg; + uint32_t emu_table_virt, cur_68k_pc, cur_instr_tab_entry, ppc_pc; + + /* PPC r24 contains 68k PC advanced by two bytes + as part of instruction prefetching */ + reg = "R24"; + cur_68k_pc = get_reg(reg) - 2; + + /* PPC r29 contains base address of the emulator opcode table */ + reg = "R29"; + emu_table_virt = get_reg(reg) & 0xFFF80000; + + /* calculate address of the current opcode table entry as follows: + get_word(68k_PC) * entry_size + table_base */ + cur_instr_tab_entry = mem_grab_word(cur_68k_pc) * 8 + emu_table_virt; + + /* grab the PPC PC too */ + reg = "PC"; + ppc_pc = get_reg(reg); + + //printf("cur_instr_tab_entry = %X\n", cur_instr_tab_entry); + + /* because the first two PPC instructions for each emulated 68k once + are resided in the emulator opcode table, we need to execute them + one by one until the execution goes outside the opcode table. */ + while (ppc_pc >= cur_instr_tab_entry && ppc_pc < cur_instr_tab_entry + 8) { + ppc_exec_single(); + reg = "PC"; + ppc_pc = get_reg(reg); + LOG_F(9, "Tracing within emulator table, PC = %X\n", ppc_pc); + } + + /* Getting here means we're outside the emualtor opcode table. + Execute PPC code until we hit the opcode table again. */ + LOG_F(9, "Tracing outside the emulator table, PC = %X\n", ppc_pc); + ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE); +} + +/** Execute emulated 68k code until target_addr is reached. */ +void exec_until_68k(uint32_t target_addr) +{ + string reg; + uint32_t emu_table_virt, ppc_pc; + + reg = "R29"; + emu_table_virt = get_reg(reg) & 0xFFF80000; + + reg = "R24"; + while (target_addr != (get_reg(reg) - 2)) { + reg = "PC"; + ppc_pc = get_reg(reg); + + if (ppc_pc >= emu_table_virt && ppc_pc < (emu_table_virt + EMU_68K_TABLE_SIZE)) { + LOG_F(9, "Tracing within emulator table, PC = %X\n", ppc_pc); + ppc_exec_single(); + } else { + LOG_F(9, "Tracing outside the emulator table, PC = %X\n", ppc_pc); + ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE); + } + reg = "R24"; + } +} + static void dump_mem(string& params) { int cell_size, chars_per_line; bool is_char; @@ -258,7 +331,7 @@ void enter_debugger() { cout << "Please enter a command or 'help'." << endl << endl; while (1) { - cout << "ppcdbg> "; + cout << "dingusdbg> "; /* reset string stream */ ss.str(""); @@ -318,7 +391,11 @@ void enter_debugger() { cout << exc.what() << endl; } } else if (cmd == "step" || cmd == "si") { - ppc_exec_single(); + if (context == 2) { + exec_single_68k(); + } else { + ppc_exec_single(); + } } else if (cmd == "next" || cmd == "ni") { addr_str = "PC"; addr = get_reg(addr_str) + 4; @@ -327,7 +404,11 @@ void enter_debugger() { ss >> addr_str; try { addr = str2addr(addr_str); - ppc_exec_until(addr); + if (context == 2) { + exec_until_68k(addr); + } else { + ppc_exec_until(addr); + } } catch (invalid_argument& exc) { cout << exc.what() << endl; } From 660d227ac7ce0bf5e07147481130e0ed044b9f2b Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 20 Jul 2020 18:00:04 +0200 Subject: [PATCH 03/20] debugger: fix string formatting. --- debugger/debugger.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index d828e96..8f68bf8 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -117,6 +117,7 @@ static void disasm_68k(uint32_t count, uint32_t address) { if (cs_disasm_iter(cs_handle, &code_ptr, &code_size, &dis_addr, insn)) { cout << uppercase << hex << insn->address << " "; + cout << setfill(' '); cout << setw(10) << left << insn->mnemonic << insn->op_str << endl; address = dis_addr; } else { @@ -279,7 +280,8 @@ static void dump_mem(string& params) { cout << (char)val; chars_per_line += cell_size; } else { - cout << setw(cell_size * 2) << setfill('0') << uppercase << hex << val << " "; + cout << setw(cell_size * 2) << setfill('0') << right; + cout << uppercase << hex << val << " "; chars_per_line += cell_size * 2 + 2; } } From 353035e9ca2588a971165ab918503b1345c5d3f0 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 20 Jul 2020 23:02:07 +0200 Subject: [PATCH 04/20] Prevent clobbering during debugging. --- cpu/ppc/ppcexec.cpp | 6 ++++-- debugger/debugger.cpp | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 9cc3ee8..1e0083b 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -610,7 +610,7 @@ void ppc_exec_single() } /** Execute PPC code until goal_addr is reached. */ -void ppc_exec_until(uint32_t goal_addr) +void ppc_exec_until(volatile uint32_t goal_addr) { uint32_t bb_start_la, page_start, delta; uint8_t* pc_real; @@ -670,7 +670,7 @@ again: } /** Execute PPC code until control is reached the specified region. */ -void ppc_exec_dbg(uint32_t start_addr, uint32_t size) +void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size) { uint32_t bb_start_la, page_start, delta; uint8_t* pc_real; @@ -692,6 +692,7 @@ void ppc_exec_dbg(uint32_t start_addr, uint32_t size) page_start = bb_start_la & 0xFFFFF000; ppc_state.pc = bb_start_la; bb_kind = BB_end_kind::BB_NONE; + //printf("DBG Exec: got exception, continue at %X\n", ppc_state.pc); goto again; } @@ -721,6 +722,7 @@ again: } ppc_state.pc = bb_start_la; bb_kind = BB_end_kind::BB_NONE; + //printf("DBG Exec: new basic block at %X, start_addr=%X\n", ppc_state.pc, start_addr); } else { ppc_state.pc += 4; pc_real += 4; diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index 8f68bf8..bf1b4c9 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -171,7 +171,7 @@ void exec_single_68k() /* Getting here means we're outside the emualtor opcode table. Execute PPC code until we hit the opcode table again. */ LOG_F(9, "Tracing outside the emulator table, PC = %X\n", ppc_pc); - ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE); + ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE - 1); } /** Execute emulated 68k code until target_addr is reached. */ @@ -188,12 +188,12 @@ void exec_until_68k(uint32_t target_addr) reg = "PC"; ppc_pc = get_reg(reg); - if (ppc_pc >= emu_table_virt && ppc_pc < (emu_table_virt + EMU_68K_TABLE_SIZE)) { + if (ppc_pc >= emu_table_virt && ppc_pc < (emu_table_virt + EMU_68K_TABLE_SIZE - 1)) { LOG_F(9, "Tracing within emulator table, PC = %X\n", ppc_pc); ppc_exec_single(); } else { LOG_F(9, "Tracing outside the emulator table, PC = %X\n", ppc_pc); - ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE); + ppc_exec_dbg(emu_table_virt, EMU_68K_TABLE_SIZE - 1); } reg = "R24"; } From 6cc88d3b02f822a79d22aaec726196fed21411b3 Mon Sep 17 00:00:00 2001 From: dingusdev Date: Thu, 15 Oct 2020 21:10:17 -0700 Subject: [PATCH 05/20] Started a timing mechanism --- CMakeLists.txt | 3 + execution/CMakeLists.txt | 6 ++ execution/interpreter_loop.cpp | 111 +++++++++++++++++++++++++++++++++ execution/interpreter_loop.h | 23 +++++++ main.cpp | 5 +- 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 execution/CMakeLists.txt create mode 100644 execution/interpreter_loop.cpp create mode 100644 execution/interpreter_loop.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a2973b8..d9dd0e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ endif() add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/") add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/") add_subdirectory("${PROJECT_SOURCE_DIR}/devices/") +add_subdirectory("${PROJECT_SOURCE_DIR}/execution") add_subdirectory("${PROJECT_SOURCE_DIR}/machines/") add_subdirectory("${PROJECT_SOURCE_DIR}/thirdparty/loguru/") @@ -57,6 +58,7 @@ file(GLOB TEST_SOURCES "${PROJECT_SOURCE_DIR}/cpu/ppc/test/*.cpp") add_executable(dingusppc ${SOURCES} $ $ $ + $ $ $) @@ -74,6 +76,7 @@ endif() add_executable(testppc ${TEST_SOURCES} $ $ $ + $ $ $) diff --git a/execution/CMakeLists.txt b/execution/CMakeLists.txt new file mode 100644 index 0000000..7e5ac0d --- /dev/null +++ b/execution/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories("${PROJECT_SOURCE_DIR}") + +file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +add_library(execution OBJECT ${SOURCES}) +target_link_libraries(execution PRIVATE cubeb) diff --git a/execution/interpreter_loop.cpp b/execution/interpreter_loop.cpp new file mode 100644 index 0000000..d9cb245 --- /dev/null +++ b/execution/interpreter_loop.cpp @@ -0,0 +1,111 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-20 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +std::chrono::high_resolution_clock::time_point global; // global timer +std::chrono::high_resolution_clock::time_point cuda_timer; // updates every 11 ms +std::chrono::high_resolution_clock::time_point disp_timer; // updates every 16 ms + +using namespace std; + +const uint64_t cuda_update = 11000; +const uint64_t display_update = 16667; + +bool cuda_priority = 0; +bool disp_priority = 0; + +uint64_t elapsed_times[3] = {0}; // Elapsed time to reach a cycle (for display) +uint64_t routine_bench[3] = {0}; // Estimated time (in microseconds) to cycle through functions +uint64_t routine_runtime[3] = {0, cuda_update, display_update}; // Time to elapse before execution + +enum general_routine_timepoint { OVERALL_UPDATE_TIME, CUDA_UPDATE_TIME, DISPLAY_UPDATE_TIME }; + +void round_robin_bench() { + // Benchmark how much time elapses during a minimal CPU block + + std::chrono::high_resolution_clock::time_point dummy = std::chrono::high_resolution_clock::now(); + + for (int i = 0; i < 4096; i++) { + ppc_ori(); //execute NOPs as a basic test + } + + std::chrono::high_resolution_clock::time_point dummy2 = std::chrono::high_resolution_clock::now(); + routine_bench[OVERALL_UPDATE_TIME] = + std::chrono::duration_cast(dummy2 - dummy).count(); + std::cout << "Initial test: " << routine_bench[OVERALL_UPDATE_TIME] << endl; +} + +void interpreter_update_counters() { + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); + elapsed_times[OVERALL_UPDATE_TIME] = + std::chrono::duration_cast(end - global).count(); + elapsed_times[CUDA_UPDATE_TIME] = + std::chrono::duration_cast(end - cuda_timer).count(); + elapsed_times[DISPLAY_UPDATE_TIME] = + std::chrono::duration_cast(end - disp_timer).count(); + + // Calculate if the threshold for updating a time-critical section has reached or is about to be reached + if ((elapsed_times[CUDA_UPDATE_TIME] + routine_bench[OVERALL_UPDATE_TIME]) >= + routine_runtime[CUDA_UPDATE_TIME]) { + cuda_priority = true; + elapsed_times[CUDA_UPDATE_TIME] = 0; + cuda_timer = end; + } + + if ((elapsed_times[DISPLAY_UPDATE_TIME] + routine_bench[OVERALL_UPDATE_TIME]) >= + routine_runtime[DISPLAY_UPDATE_TIME]) { + disp_priority = true; + elapsed_times[DISPLAY_UPDATE_TIME] = 0; + disp_timer = end; + } +} + +void interpreter_main_loop() { + // Round robin algorithm goes here + round_robin_bench(); + + global = std::chrono::high_resolution_clock::now(); + cuda_timer = global; + disp_timer = global; + + for (;;) { + if (cuda_priority) { + LOG_F(9, "Placeholder for Cuda Update function!\n"); + cuda_priority = false; + } + + if (disp_priority) { + LOG_F(9, "Placeholder for Display Update function! \n"); + disp_priority = false; + } + + ppc_exec(); + + interpreter_update_counters(); + } +} \ No newline at end of file diff --git a/execution/interpreter_loop.h b/execution/interpreter_loop.h new file mode 100644 index 0000000..e760826 --- /dev/null +++ b/execution/interpreter_loop.h @@ -0,0 +1,23 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-20 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +void interpreter_update_counters(); +void interpreter_main_loop(); \ No newline at end of file diff --git a/main.cpp b/main.cpp index 7c88af1..7a66297 100644 --- a/main.cpp +++ b/main.cpp @@ -23,6 +23,7 @@ along with this program. If not, see . // This is where the magic begins #include "debugger/debugger.h" +#include "execution/interpreter_loop.h" #include "machines/machinefactory.h" #include "machines/machineproperties.h" #include "ppcemu.h" @@ -165,9 +166,7 @@ int main(int argc, char** argv) { switch (execution_mode) { case 0: - for (;;) { - ppc_exec(); - } + interpreter_main_loop(); break; case 1: enter_debugger(); From dc58386237a5453d91d76f4ad04b36b92178b7d4 Mon Sep 17 00:00:00 2001 From: dingusdev Date: Sat, 17 Oct 2020 14:30:37 -0700 Subject: [PATCH 06/20] Started re-refactoring opcode retrieval --- cpu/ppc/poweropcodes.cpp | 434 ++++------------------- cpu/ppc/ppcemu.h | 139 +------- cpu/ppc/ppcexec.cpp | 680 ++++++++++++++++------------------- cpu/ppc/ppcfpopcodes.cpp | 364 +++---------------- cpu/ppc/ppcopcodes.cpp | 727 ++++++++------------------------------ cpu/ppc/test/ppctests.cpp | 2 + main.cpp | 2 + 7 files changed, 602 insertions(+), 1746 deletions(-) diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index 731b563..44b2135 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -24,58 +24,38 @@ along with this program. If not, see . #include "ppcemu.h" #include "ppcmmu.h" +#include #include #include #include +#include #include #include +// Affects the XER register's SO and OV Bits + +inline void power_setsoov(uint32_t a, uint32_t b, uint32_t d) { + if ((a ^ b) & (a ^ d) & 0x80000000UL) { + ppc_state.spr[SPR::XER] |= 0xC0000000UL; + } else { + ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; + } +} + void power_abs() { ppc_grab_regsda(); if (ppc_result_a == 0x80000000) { ppc_result_d = ppc_result_a; + if (oe_flag) + ppc_state.spr[SPR::XER] |= 0x40000000; } else { ppc_result_d = ppc_result_a & 0x7FFFFFFF; } - ppc_store_result_regd(); -} + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void power_absdot() { - ppc_grab_regsda(); - if (ppc_result_a == 0x80000000) { - ppc_result_d = ppc_result_a; - - } else { - ppc_result_d = ppc_result_a & 0x7FFFFFFF; - } - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -void power_abso() { - ppc_grab_regsda(); - if (ppc_result_a == 0x80000000) { - ppc_result_d = ppc_result_a; - ppc_state.spr[SPR::XER] |= 0x40000000; - - } else { - ppc_result_d = ppc_result_a & 0x7FFFFFFF; - } - ppc_store_result_regd(); -} - -void power_absodot() { - ppc_grab_regsda(); - if (ppc_result_a == 0x80000000) { - ppc_result_d = ppc_result_a; - ppc_state.spr[SPR::XER] |= 0x40000000; - - } else { - ppc_result_d = ppc_result_a & 0x7FFFFFFF; - } - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -91,22 +71,12 @@ void power_clcs() { default: ppc_result_d = 0; } - ppc_store_result_regd(); -} -void power_clcsdot() { - switch (reg_a) { - case 12: - case 13: - case 14: - case 15: - ppc_result_d = 65535; - break; - default: - ppc_result_d = 0; + if (rc_flag) { + ppc_changecrf0(ppc_result_d); + printf("Does RC do anything here? (TODO) \n"); } - ppc_changecrf0(ppc_result_d); - printf("Does RC do anything here? (TODO) \n"); + ppc_store_result_regd(); } @@ -114,46 +84,28 @@ void power_div() { ppc_grab_regsdab(); ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b; ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b; + + if (oe_flag) + power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } -void power_divdot() { - ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b; -} - -void power_divo() { - ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b; -} - -void power_divodot() { - ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b; -} - void power_divs() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a / ppc_result_b; ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); + + if (oe_flag) + power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } -void power_divsdot() { - ppc_result_d = ppc_result_a / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); -} - -void power_divso() { - ppc_result_d = ppc_result_a / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); -} - -void power_divsodot() { - ppc_result_d = ppc_result_a / ppc_result_b; - ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); -} - void power_doz() { ppc_grab_regsdab(); if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) { @@ -161,36 +113,13 @@ void power_doz() { } else { ppc_result_d = ~ppc_result_a + ppc_result_b + 1; } + + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_rega(); } -void power_dozdot() { - ppc_grab_regsdab(); - if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) { - ppc_result_d = 0; - } else { - ppc_result_d = ~ppc_result_a + ppc_result_b + 1; - } - ppc_changecrf0(ppc_result_d); - ppc_store_result_rega(); -} - -void power_dozo() { - if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) { - ppc_result_d = 0; - } else { - ppc_result_d = ~ppc_result_a + ppc_result_b + 1; - } -} - -void power_dozodot() { - if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) { - ppc_result_d = 0; - } else { - ppc_result_d = ~ppc_result_a + ppc_result_b + 1; - } -} - void power_dozi() { ppc_grab_regsdab(); if (((int32_t)ppc_result_a) > simm) { @@ -254,11 +183,12 @@ void power_lscbx() { } } while (bytes_to_load > 0); ppc_state.spr[SPR::XER] = (ppc_state.spr[SPR::XER] & 0xFFFFFF80) | bytes_copied; - ppc_store_result_regd(); -} -void power_lscbxdot() { - printf("OOPS! Placeholder!!! \n"); + + if (rc_flag) + ppc_changecrf0(ppc_result_d); + + ppc_store_result_regd(); } void power_maskg() { @@ -281,29 +211,10 @@ void power_maskg() { } ppc_result_a = insert_mask; - ppc_store_result_rega(); -} -void power_maskgdot() { - ppc_grab_regssab(); - uint32_t mask_start = ppc_result_d & 31; - uint32_t mask_end = ppc_result_b & 31; - uint32_t insert_mask = 0; + if (rc_flag) + ppc_changecrf0(ppc_result_d); - if (mask_start < (mask_end + 1)) { - for (uint32_t i = mask_start; i < mask_end; i++) { - insert_mask |= (0x80000000 >> i); - } - } else if (mask_start == (mask_end + 1)) { - insert_mask = 0xFFFFFFFF; - } else { - insert_mask = 0xFFFFFFFF; - for (uint32_t i = (mask_end + 1); i < (mask_start - 1); i++) { - insert_mask &= (~(0x80000000 >> i)); - } - } - - ppc_result_a = insert_mask; ppc_store_result_rega(); } @@ -320,23 +231,10 @@ void power_maskir() { } while (insert_rot > 0); ppc_result_a = (ppc_result_d & ppc_result_b); - ppc_store_result_rega(); -} -void power_maskirdot() { - ppc_grab_regssab(); - uint32_t mask_insert = ppc_result_a; - uint32_t insert_rot = 0x80000000; - do { - if (ppc_result_b & insert_rot) { - mask_insert &= ~insert_rot; - mask_insert |= (ppc_result_d & insert_rot); - } - insert_rot = insert_rot >> 1; - } while (insert_rot > 0); + if (rc_flag) + ppc_changecrf0(ppc_result_a); - ppc_result_a = (ppc_result_d & ppc_result_b); - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -347,54 +245,23 @@ void power_mul() { product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b); ppc_result_d = ((uint32_t)(product >> 32)); ppc_state.spr[SPR::MQ] = ((uint32_t)(product)); + + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } -void power_muldot() { - ppc_grab_regsdab(); - uint64_t product; - - product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b); - ppc_result_d = ((uint32_t)(product >> 32)); - ppc_state.spr[SPR::MQ] = ((uint32_t)(product)); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -void power_mulo() { - uint64_t product; - - product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b); - ppc_result_d = ((uint32_t)(product >> 32)); - ppc_state.spr[SPR::MQ] = ((uint32_t)(product)); -} - -void power_mulodot() { - uint64_t product; - - product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b); - ppc_result_d = ((uint32_t)(product >> 32)); - ppc_state.spr[SPR::MQ] = ((uint32_t)(product)); -} - void power_nabs() { ppc_grab_regsda(); ppc_result_d = (0x80000000 | ppc_result_a); + + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } -void power_nabsdot() { - ppc_result_d = (0x80000000 | ppc_result_a); -} - -void power_nabso() { - ppc_result_d = (0x80000000 | ppc_result_a); -} - -void power_nabsodot() { - ppc_result_d = (0x80000000 | ppc_result_a); -} - void power_rlmi() { ppc_grab_regssab(); unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; @@ -422,22 +289,16 @@ void power_rlmi() { void power_rrib() { ppc_grab_regssab(); - if (ppc_result_d & 0x80000000) { - ppc_result_a |= (0x80000000 >> ppc_result_b); - } else { - ppc_result_a &= ~(0x80000000 >> ppc_result_b); - } - ppc_store_result_rega(); -} -void power_rribdot() { - ppc_grab_regssab(); if (ppc_result_d & 0x80000000) { ppc_result_a |= (0x80000000 >> ppc_result_b); } else { ppc_result_a &= ~(0x80000000 >> ppc_result_b); } - ppc_changecrf0(ppc_result_a); + + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -451,20 +312,10 @@ void power_sle() { uint32_t insert_final = ((ppc_result_d << rot_amt) | (ppc_result_d >> (32 - rot_amt))); ppc_state.spr[SPR::MQ] = insert_final & insert_mask; ppc_result_a = insert_final & insert_mask; - ppc_store_result_rega(); -} -void power_sledot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - uint32_t rot_amt = ppc_result_b & 31; - for (uint32_t i = 31; i > rot_amt; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_final = ((ppc_result_d << rot_amt) | (ppc_result_d >> (32 - rot_amt))); - ppc_state.spr[SPR::MQ] = insert_final & insert_mask; - ppc_result_a = insert_final & insert_mask; - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -487,29 +338,10 @@ void power_sleq() { ppc_result_a = insert_end; ppc_state.spr[SPR::MQ] = insert_start; - ppc_store_result_rega(); -} -void power_sleqdot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - uint32_t rot_amt = ppc_result_b & 31; - for (uint32_t i = 31; i > rot_amt; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_start = ((ppc_result_d << rot_amt) | (ppc_result_d >> (rot_amt - 31))); - uint32_t insert_end = ppc_state.spr[SPR::MQ]; + if (rc_flag) + ppc_changecrf0(ppc_result_a); - for (int i = 0; i < 32; i++) { - if (insert_mask & (1 << i)) { - insert_end &= ~(1 << i); - insert_end |= (insert_start & (1 << i)); - } - } - - ppc_result_a = insert_end; - ppc_state.spr[SPR::MQ] = insert_start; - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -532,29 +364,10 @@ void power_sliq() { ppc_result_a = insert_end & insert_mask; ppc_state.spr[SPR::MQ] = insert_start; - ppc_store_result_rega(); -} -void power_sliqdot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; - for (uint32_t i = 31; i > rot_sh; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_start = ((ppc_result_d << rot_sh) | (ppc_result_d >> (rot_sh - 31))); - uint32_t insert_end = ppc_state.spr[SPR::MQ]; + if (rc_flag) + ppc_changecrf0(ppc_result_a); - for (int i = 0; i < 32; i++) { - if (insert_mask & (1 << i)) { - insert_end &= ~(1 << i); - insert_end |= (insert_start & (1 << i)); - } - } - - ppc_result_a = insert_end & insert_mask; - ppc_state.spr[SPR::MQ] = insert_start; - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -577,29 +390,10 @@ void power_slliq() { ppc_result_a = insert_end; ppc_state.spr[SPR::MQ] = insert_start; - ppc_store_result_rega(); -} -void power_slliqdot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; - for (uint32_t i = 31; i > rot_sh; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_start = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); - uint32_t insert_end = ppc_state.spr[SPR::MQ]; + if (rc_flag) + ppc_changecrf0(ppc_result_a); - for (int i = 0; i < 32; i++) { - if (insert_mask & (1 << i)) { - insert_end &= ~(1 << i); - insert_end |= (insert_start & (1 << i)); - } - } - - ppc_result_a = insert_end; - ppc_state.spr[SPR::MQ] = insert_start; - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -607,34 +401,18 @@ void power_sllq() { LOG_F(WARNING, "OOPS! Placeholder for sllq!!! \n"); } -void power_sllqdot() { - LOG_F(WARNING, "OOPS! Placeholder for sllq.!!! \n"); -} - void power_slq() { LOG_F(WARNING, "OOPS! Placeholder for slq!!! \n"); } -void power_slqdot() { - LOG_F(WARNING, "OOPS! Placeholder for slq.!!! \n"); -} - void power_sraiq() { LOG_F(WARNING, "OOPS! Placeholder for sraiq!!! \n"); } -void power_sraiqdot() { - LOG_F(WARNING, "OOPS! Placeholder for sraiq.!!! \n"); -} - void power_sraq() { LOG_F(WARNING, "OOPS! Placeholder for sraq!!! \n"); } -void power_sraqdot() { - LOG_F(WARNING, "OOPS! Placeholder for sraq.!!! \n"); -} - void power_sre() { ppc_grab_regssa(); uint32_t insert_mask = 0; @@ -645,20 +423,8 @@ void power_sre() { uint32_t insert_final = ((ppc_result_d >> rot_amt) | (ppc_result_d << (32 - rot_amt))); ppc_state.spr[SPR::MQ] = insert_final & insert_mask; ppc_result_a = insert_final; - ppc_store_result_rega(); -} - -void power_sredot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - uint32_t rot_amt = ppc_result_b & 31; - for (uint32_t i = 31; i > rot_amt; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_final = ((ppc_result_d >> rot_amt) | (ppc_result_d << (32 - rot_amt))); - ppc_state.spr[SPR::MQ] = insert_final & insert_mask; - ppc_result_a = insert_final; - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -666,10 +432,6 @@ void power_srea() { LOG_F(WARNING, "OOPS! Placeholder for srea!!! \n"); } -void power_sreadot() { - LOG_F(WARNING, "OOPS! Placeholder for srea.!!! \n"); -} - void power_sreq() { ppc_grab_regssa(); uint32_t insert_mask = 0; @@ -689,29 +451,10 @@ void power_sreq() { ppc_result_a = insert_end; ppc_state.spr[SPR::MQ] = insert_start; - ppc_store_result_rega(); -} -void power_sreqdot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - unsigned rot_sh = ppc_result_b & 31; - for (uint32_t i = 31; i > rot_sh; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_start = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))); - uint32_t insert_end = ppc_state.spr[SPR::MQ]; + if (rc_flag) + ppc_changecrf0(ppc_result_a); - for (int i = 0; i < 32; i++) { - if (insert_mask & (1 << i)) { - insert_end &= ~(1 << i); - insert_end |= (insert_start & (1 << i)); - } - } - - ppc_result_a = insert_end; - ppc_state.spr[SPR::MQ] = insert_start; - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -734,29 +477,10 @@ void power_sriq() { ppc_result_a = insert_end; ppc_state.spr[SPR::MQ] = insert_start; - ppc_store_result_rega(); -} -void power_sriqdot() { - ppc_grab_regssa(); - uint32_t insert_mask = 0; - unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; - for (uint32_t i = 31; i > rot_sh; i--) { - insert_mask |= (1 << i); - } - uint32_t insert_start = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))); - uint32_t insert_end = ppc_state.spr[SPR::MQ]; + if (rc_flag) + ppc_changecrf0(ppc_result_a); - for (int i = 0; i < 32; i++) { - if (insert_mask & (1 << i)) { - insert_end &= ~(1 << i); - insert_end |= (insert_start & (1 << i)); - } - } - - ppc_result_a = insert_end; - ppc_state.spr[SPR::MQ] = insert_start; - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -764,22 +488,10 @@ void power_srliq() { LOG_F(WARNING, "OOPS! Placeholder for slriq!!! \n"); } -void power_srliqdot() { - LOG_F(WARNING, "OOPS! Placeholder for slriq.!!! \n"); -} - void power_srlq() { LOG_F(WARNING, "OOPS! Placeholder for slrq!!! \n"); } -void power_srlqdot() { - LOG_F(WARNING, "OOPS! Placeholder for slrq.!!! \n"); -} - void power_srq() { LOG_F(WARNING, "OOPS! Placeholder for srq!!! \n"); -} - -void power_srqdot() { - LOG_F(WARNING, "OOPS! Placeholder for srq.!!! \n"); -} +} \ No newline at end of file diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 54f595d..64de5bd 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -226,10 +226,12 @@ extern bool grab_return; extern bool power_on; extern bool is_601; // For PowerPC 601 Emulation -extern bool is_gekko; // For GameCube 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; @@ -245,6 +247,11 @@ extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version); extern void ppc_mmu_init(); void ppc_illegalop(); +void ppc_illegalsubop19(); +void ppc_illegalsubop31(); +void ppc_illegalsubop59(); +void ppc_illegalsubop63(); + void ppc_opcode4(); void ppc_opcode16(); void ppc_opcode18(); @@ -253,6 +260,8 @@ void ppc_opcode31(); void ppc_opcode59(); void ppc_opcode63(); +void initialize_ppc_opcode_tables(); + extern bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uint32_t op); extern double fp_return_double(uint32_t reg); extern uint64_t fp_return_uint64(uint32_t reg); @@ -286,8 +295,6 @@ extern void ppc_store_dfpresult(bool int_rep); void ppc_changecrf0(uint32_t set_result); void ppc_fp_changecrf1(); -void ppc_tbr_update(); - /* Exception handlers. */ [[noreturn]] void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits); [[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits); @@ -311,33 +318,15 @@ extern void ppc_crxor(); extern void ppc_isync(); extern void ppc_add(); -extern void ppc_adddot(); -extern void ppc_addo(); -extern void ppc_addodot(); extern void ppc_addc(); -extern void ppc_addcdot(); -extern void ppc_addco(); -extern void ppc_addcodot(); extern void ppc_adde(); -extern void ppc_addedot(); -extern void ppc_addeo(); -extern void ppc_addeodot(); extern void ppc_addme(); -extern void ppc_addmedot(); -extern void ppc_addmeo(); -extern void ppc_addmeodot(); extern void ppc_addze(); -extern void ppc_addzedot(); -extern void ppc_addzeo(); -extern void ppc_addzeodot(); extern void ppc_and(); -extern void ppc_anddot(); extern void ppc_andc(); -extern void ppc_andcdot(); extern void ppc_cmp(); extern void ppc_cmpl(); extern void ppc_cntlzw(); -extern void ppc_cntlzwdot(); extern void ppc_dcbf(); extern void ppc_dcbi(); extern void ppc_dcbst(); @@ -345,20 +334,11 @@ extern void ppc_dcbt(); extern void ppc_dcbtst(); extern void ppc_dcbz(); extern void ppc_divw(); -extern void ppc_divwdot(); -extern void ppc_divwo(); -extern void ppc_divwodot(); extern void ppc_divwu(); -extern void ppc_divwudot(); -extern void ppc_divwuo(); -extern void ppc_divwuodot(); extern void ppc_eieio(); extern void ppc_eqv(); -extern void ppc_eqvdot(); extern void ppc_extsb(); -extern void ppc_extsbdot(); extern void ppc_extsh(); -extern void ppc_extshdot(); extern void ppc_icbi(); extern void ppc_mftb(); extern void ppc_lhzux(); @@ -375,33 +355,17 @@ extern void ppc_lwzx(); extern void ppc_mcrxr(); extern void ppc_mfcr(); extern void ppc_mulhwu(); -extern void ppc_mulhwudot(); extern void ppc_mulhw(); -extern void ppc_mulhwdot(); extern void ppc_mullw(); -extern void ppc_mullwdot(); -extern void ppc_mullwo(); -extern void ppc_mullwodot(); extern void ppc_nand(); -extern void ppc_nanddot(); extern void ppc_neg(); -extern void ppc_negdot(); -extern void ppc_nego(); -extern void ppc_negodot(); extern void ppc_nor(); -extern void ppc_nordot(); extern void ppc_or(); -extern void ppc_ordot(); extern void ppc_orc(); -extern void ppc_orcdot(); extern void ppc_slw(); -extern void ppc_slwdot(); extern void ppc_srw(); -extern void ppc_srwdot(); extern void ppc_sraw(); -extern void ppc_srawdot(); extern void ppc_srawi(); -extern void ppc_srawidot(); extern void ppc_stbx(); extern void ppc_stbux(); extern void ppc_stfiwx(); @@ -413,25 +377,10 @@ extern void ppc_stwcx(); extern void ppc_stwux(); extern void ppc_stwbrx(); extern void ppc_subf(); -extern void ppc_subfdot(); -extern void ppc_subfo(); -extern void ppc_subfodot(); extern void ppc_subfc(); -extern void ppc_subfcdot(); -extern void ppc_subfco(); -extern void ppc_subfcodot(); extern void ppc_subfe(); -extern void ppc_subfedot(); -extern void ppc_subfeo(); -extern void ppc_subfeodot(); extern void ppc_subfme(); -extern void ppc_subfmedot(); -extern void ppc_subfmeo(); -extern void ppc_subfmeodot(); extern void ppc_subfze(); -extern void ppc_subfzedot(); -extern void ppc_subfzeo(); -extern void ppc_subfzeodot(); extern void ppc_sync(); extern void ppc_tlbia(); extern void ppc_tlbie(); @@ -440,7 +389,6 @@ extern void ppc_tlbld(); extern void ppc_tlbsync(); extern void ppc_tw(); extern void ppc_xor(); -extern void ppc_xordot(); extern void ppc_lswi(); extern void ppc_lswx(); @@ -561,105 +509,38 @@ extern void ppc_frsp(); extern void ppc_fctiw(); extern void ppc_fctiwz(); -extern void ppc_fadddot(); -extern void ppc_fsubdot(); -extern void ppc_fmultdot(); -extern void ppc_fdivdot(); -extern void ppc_fmadddot(); -extern void ppc_fmsubdot(); -extern void ppc_fnmadddot(); -extern void ppc_fnmsubdot(); -extern void ppc_fabsdot(); -extern void ppc_fnabsdot(); -extern void ppc_fnegdot(); -extern void ppc_fseldot(); -extern void ppc_fsqrtdot(); -extern void ppc_frsqrtedot(); -extern void ppc_frspdot(); -extern void ppc_fctiwdot(); -extern void ppc_fctiwzdot(); - -extern void ppc_fresdot(); -extern void ppc_faddsdot(); -extern void ppc_fsubsdot(); -extern void ppc_fmultsdot(); -extern void ppc_fdivsdot(); -extern void ppc_fmaddsdot(); -extern void ppc_fmsubsdot(); -extern void ppc_fnmaddsdot(); -extern void ppc_fnmsubsdot(); -extern void ppc_fsqrtsdot(); - extern void ppc_fcmpo(); extern void ppc_fcmpu(); // Power-specific instructions extern void power_abs(); -extern void power_absdot(); -extern void power_abso(); -extern void power_absodot(); extern void power_clcs(); -extern void power_clcsdot(); extern void power_div(); -extern void power_divdot(); -extern void power_divo(); -extern void power_divodot(); extern void power_divs(); -extern void power_divsdot(); -extern void power_divso(); -extern void power_divsodot(); extern void power_doz(); -extern void power_dozdot(); -extern void power_dozo(); -extern void power_dozodot(); extern void power_dozi(); extern void power_lscbx(); -extern void power_lscbxdot(); extern void power_maskg(); -extern void power_maskgdot(); extern void power_maskir(); -extern void power_maskirdot(); extern void power_mul(); -extern void power_muldot(); -extern void power_mulo(); -extern void power_mulodot(); extern void power_nabs(); -extern void power_nabsdot(); -extern void power_nabso(); -extern void power_nabsodot(); extern void power_rlmi(); extern void power_rrib(); -extern void power_rribdot(); extern void power_sle(); -extern void power_sledot(); extern void power_sleq(); -extern void power_sleqdot(); extern void power_sliq(); -extern void power_sliqdot(); extern void power_slliq(); -extern void power_slliqdot(); extern void power_sllq(); -extern void power_sllqdot(); extern void power_slq(); -extern void power_slqdot(); extern void power_sraiq(); -extern void power_sraiqdot(); extern void power_sraq(); -extern void power_sraqdot(); extern void power_sre(); -extern void power_sredot(); extern void power_srea(); -extern void power_sreadot(); extern void power_sreq(); -extern void power_sreqdot(); extern void power_sriq(); -extern void power_sriqdot(); extern void power_srliq(); -extern void power_srliqdot(); extern void power_srlq(); -extern void power_srlqdot(); extern void power_srq(); -extern void power_srqdot(); // Gekko instructions extern void ppc_psq_l(); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 066ccfc..582d202 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -42,6 +42,9 @@ bool power_on = 1; SetPRS ppc_state; +bool rc_flag = 0; // Record flag +bool oe_flag = 0; // Overflow flag + bool grab_exception; bool grab_return; bool grab_breakpoint; @@ -86,327 +89,12 @@ static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla}; static PPCOpcode SubOpcode18Grabber[] = {ppc_b, ppc_bl, ppc_ba, ppc_bla}; -/** General conditional register instructions decoding table. */ -static std::unordered_map SubOpcode19Grabber = { - {32, &ppc_bclr}, - {33, &ppc_bclrl}, - {66, &ppc_crnor}, - {100, &ppc_rfi}, - {258, &ppc_crandc}, - {300, &ppc_isync}, - {386, &ppc_crxor}, - {450, &ppc_crnand}, - {514, &ppc_crand}, - {578, &ppc_creqv}, - {834, &ppc_crorc}, - {898, &ppc_cror}, - {1056, &ppc_bcctr}, - {1057, &ppc_bcctrl}}; +/** Instructions decoding tables for integer, + single floating-point, and double-floating point ops respectively */ -/** General integer instructions decoding table. */ -static std::unordered_map SubOpcode31Grabber = { - {0, &ppc_cmp}, {8, &ppc_tw}, - {16, &ppc_subfc}, {17, &ppc_subfcdot}, - {20, &ppc_addc}, {21, &ppc_addcdot}, - {22, &ppc_mulhwu}, {23, &ppc_mulhwudot}, - {38, &ppc_mfcr}, {40, &ppc_lwarx}, - {46, &ppc_lwzx}, {48, &ppc_slw}, - {49, &ppc_slwdot}, {52, &ppc_cntlzw}, - {53, &ppc_cntlzwdot}, {56, &ppc_and}, - {57, &ppc_anddot}, {58, &power_maskg}, - {59, &power_maskgdot}, {64, &ppc_cmpl}, - {80, &ppc_subf}, {81, &ppc_subfdot}, - {108, &ppc_dcbst}, {110, &ppc_lwzux}, - {120, &ppc_andc}, {121, &ppc_andcdot}, - {150, &ppc_mulhw}, {151, &ppc_mulhwdot}, - {166, &ppc_mfmsr}, {172, &ppc_dcbf}, - {174, &ppc_lbzx}, {208, &ppc_neg}, - {209, &ppc_negdot}, {214, &power_mul}, - {215, &power_muldot}, {238, &ppc_lbzux}, - {248, &ppc_nor}, {249, &ppc_nordot}, - {272, &ppc_subfe}, {273, &ppc_subfedot}, - {276, &ppc_adde}, {277, &ppc_addedot}, - {288, &ppc_mtcrf}, {292, &ppc_mtmsr}, - {301, &ppc_stwcx}, {302, &ppc_stwx}, - {304, &power_slq}, {305, &power_slqdot}, - {306, &power_sle}, {307, &power_sledot}, - {366, &ppc_stwux}, {368, &power_sliq}, - {400, &ppc_subfze}, {401, &ppc_subfzedot}, - {404, &ppc_addze}, {405, &ppc_addzedot}, - {420, &ppc_mtsr}, {430, &ppc_stbx}, - {432, &power_sllq}, {433, &power_sllqdot}, - {434, &power_sleq}, {436, &power_sleqdot}, - {464, &ppc_subfme}, {465, &ppc_subfmedot}, - {468, &ppc_addme}, {469, &ppc_addmedot}, - {470, &ppc_mullw}, {471, &ppc_mullwdot}, - {484, &ppc_mtsrin}, {492, &ppc_dcbtst}, - {494, &ppc_stbux}, {496, &power_slliq}, - {497, &power_slliqdot}, {528, &power_doz}, - {529, &power_dozdot}, {532, &ppc_add}, - {533, &ppc_adddot}, {554, &power_lscbx}, - {555, &power_lscbxdot}, {556, &ppc_dcbt}, - {558, &ppc_lhzx}, {568, &ppc_eqv}, - {569, &ppc_eqvdot}, {612, &ppc_tlbie}, - {622, &ppc_lhzux}, {632, &ppc_xor}, - {633, &ppc_xordot}, {662, &power_div}, - {663, &power_divdot}, {678, &ppc_mfspr}, - {686, &ppc_lhax}, {720, &power_abs}, - {721, &power_absdot}, {726, &power_divs}, - {727, &power_divsdot}, {740, &ppc_tlbia}, - {742, &ppc_mftb}, {750, &ppc_lhaux}, - {814, &ppc_sthx}, {824, &ppc_orc}, - {825, &ppc_orcdot}, {878, &ppc_sthx}, - {888, &ppc_or}, {889, &ppc_ordot}, - {918, &ppc_divwu}, {919, &ppc_divwudot}, - {934, &ppc_mtspr}, {940, &ppc_dcbi}, - {952, &ppc_nand}, {953, &ppc_nanddot}, - {976, &power_nabs}, {977, &power_nabsdot}, - {982, &ppc_divw}, {983, &ppc_divwdot}, - {1024, &ppc_mcrxr}, {1040, &ppc_subfco}, - {1041, &ppc_subfcodot}, {1044, &ppc_addco}, - {1045, &ppc_addcodot}, {1062, &power_clcs}, - {1063, &power_clcsdot}, {1066, &ppc_lswx}, - {1068, &ppc_lwbrx}, {1070, &ppc_lfsx}, - {1072, &ppc_srw}, {1073, &ppc_srwdot}, - {1074, &power_rrib}, {1075, &power_rribdot}, - {1082, &power_maskir}, {1083, &power_maskirdot}, - {1104, &ppc_subfo}, {1105, &ppc_subfodot}, - {1132, &ppc_tlbsync}, {1134, &ppc_lfsux}, - {1190, &ppc_mfsr}, {1194, &ppc_lswi}, - {1196, &ppc_sync}, {1198, &ppc_lfdx}, - {1232, &ppc_nego}, {1233, &ppc_negodot}, - {1238, &power_mulo}, {1239, &power_mulodot}, - {1262, &ppc_lfdux}, {1296, &ppc_subfeo}, - {1297, &ppc_subfeodot}, {1300, &ppc_addeo}, - {1301, &ppc_addeodot}, {1318, &ppc_mfsrin}, - {1322, &ppc_stswx}, {1324, &ppc_stwbrx}, - {1326, &ppc_stfsx}, {1328, &power_srq}, - {1329, &power_srqdot}, {1330, &power_sre}, - {1331, &power_sredot}, {1390, &ppc_stfsux}, - {1392, &power_sriq}, {1393, &power_sriqdot}, - {1424, &ppc_subfzeo}, {1425, &ppc_subfzeodot}, - {1428, &ppc_addzeo}, {1429, &ppc_addzeodot}, - {1450, &ppc_stswi}, {1454, &ppc_stfdx}, - {1456, &power_srlq}, {1457, &power_srlqdot}, - {1458, &power_sreq}, {1459, &power_sreqdot}, - {1488, &ppc_subfmeo}, {1489, &ppc_subfmeodot}, - {1492, &ppc_addmeo}, {1493, &ppc_addmeodot}, - {1494, &ppc_mullwo}, {1495, &ppc_mullwodot}, - {1518, &ppc_stfdux}, {1520, &power_srliq}, - {1521, &power_srliqdot}, {1552, &power_dozo}, - {1553, &power_dozodot}, {1556, &ppc_addo}, - {1557, &ppc_addodot}, {1580, &ppc_lhbrx}, - {1584, &ppc_sraw}, {1585, &ppc_srawdot}, - {1648, &ppc_srawi}, {1649, &ppc_srawidot}, - {1686, &power_divo}, {1687, &power_divodot}, - {1708, &ppc_eieio}, {1744, &power_abso}, - {1745, &power_absodot}, {1750, &power_divso}, - {1751, &power_divsodot}, {1836, &ppc_sthbrx}, - {1840, &power_sraq}, {1841, &power_sraqdot}, - {1842, &power_srea}, {1843, &power_sreadot}, - {1844, &ppc_extsh}, {1845, &ppc_extshdot}, - {1904, &power_sraiq}, {1905, &power_sraiqdot}, - {1908, &ppc_extsb}, {1909, &ppc_extsbdot}, - {1942, &ppc_divwuo}, {1943, &ppc_divwuodot}, - {1956, &ppc_tlbld}, {1964, &ppc_icbi}, - {1966, &ppc_stfiwx}, {2000, &power_nabso}, - {2001, &power_nabsodot}, {2006, &ppc_divwo}, - {2007, &ppc_divwodot}, {2020, &ppc_tlbli}, - {2028, &ppc_dcbz}}; - -/** Single-precision floating-point instructions decoding table. */ -static std::unordered_map SubOpcode59Grabber = { - {36, &ppc_fdivs}, {37, &ppc_fdivsdot}, {40, &ppc_fsubs}, {41, &ppc_fsubsdot}, - {42, &ppc_fadds}, {43, &ppc_faddsdot}, {44, &ppc_fsqrts}, {45, &ppc_fsqrtsdot}, - {48, &ppc_fres}, {49, &ppc_fresdot}, {50, &ppc_fmults}, {51, &ppc_fmultsdot}, - {56, &ppc_fmsubs}, {57, &ppc_fmsubsdot}, {58, &ppc_fmadds}, {59, &ppc_fmaddsdot}, - {60, &ppc_fnmsubs}, {61, &ppc_fnmsubsdot}, {62, &ppc_fnmadds}, {63, &ppc_fnmaddsdot}, - {114, &ppc_fmults}, {115, &ppc_fmultsdot}, {120, &ppc_fmsubs}, {121, &ppc_fmsubsdot}, - {122, &ppc_fmadds}, {123, &ppc_fmadds}, {124, &ppc_fnmsubs}, {125, &ppc_fnmsubsdot}, - {126, &ppc_fnmadds}, {127, &ppc_fnmaddsdot}, {178, &ppc_fmults}, {179, &ppc_fmultsdot}, - {184, &ppc_fmsubs}, {185, &ppc_fmsubsdot}, {186, &ppc_fmadds}, {187, &ppc_fmaddsdot}, - {188, &ppc_fnmsubs}, {189, &ppc_fnmsubsdot}, {190, &ppc_fnmadds}, {191, &ppc_fnmaddsdot}, - {242, &ppc_fmults}, {243, &ppc_fmultsdot}, {248, &ppc_fmsubs}, {249, &ppc_fmsubsdot}, - {250, &ppc_fmadds}, {251, &ppc_fmaddsdot}, {252, &ppc_fnmsubs}, {253, &ppc_fnmsubsdot}, - {254, &ppc_fnmadds}, {255, &ppc_fnmaddsdot}, {306, &ppc_fmults}, {307, &ppc_fmultsdot}, - {312, &ppc_fmsubs}, {313, &ppc_fmsubsdot}, {314, &ppc_fmadds}, {315, &ppc_fmaddsdot}, - {316, &ppc_fnmsubs}, {317, &ppc_fnmsubsdot}, {318, &ppc_fnmadds}, {319, &ppc_fnmaddsdot}, - {370, &ppc_fmults}, {371, &ppc_fmultsdot}, {376, &ppc_fmsubs}, {377, &ppc_fmsubsdot}, - {378, &ppc_fmadds}, {379, &ppc_fmaddsdot}, {380, &ppc_fnmsubs}, {381, &ppc_fnmsubsdot}, - {382, &ppc_fnmadds}, {383, &ppc_fnmaddsdot}, {434, &ppc_fmults}, {435, &ppc_fmultsdot}, - {440, &ppc_fmsubs}, {441, &ppc_fmsubsdot}, {442, &ppc_fmadds}, {443, &ppc_fmaddsdot}, - {444, &ppc_fnmsubs}, {445, &ppc_fnmsubsdot}, {446, &ppc_fnmadds}, {447, &ppc_fnmaddsdot}, - {498, &ppc_fmults}, {499, &ppc_fmultsdot}, {504, &ppc_fmsubs}, {505, &ppc_fmsubsdot}, - {506, &ppc_fmadds}, {507, &ppc_fmaddsdot}, {508, &ppc_fnmsubs}, {509, &ppc_fnmsubsdot}, - {510, &ppc_fnmadds}, {511, &ppc_fnmaddsdot}, {562, &ppc_fmults}, {563, &ppc_fmultsdot}, - {568, &ppc_fmsubs}, {569, &ppc_fmsubsdot}, {570, &ppc_fmadds}, {571, &ppc_fmaddsdot}, - {572, &ppc_fnmsubs}, {573, &ppc_fnmsubsdot}, {574, &ppc_fnmadds}, {575, &ppc_fnmaddsdot}, - {626, &ppc_fmults}, {627, &ppc_fmultsdot}, {632, &ppc_fmsubs}, {633, &ppc_fmsubsdot}, - {634, &ppc_fmadds}, {635, &ppc_fmaddsdot}, {636, &ppc_fnmsubs}, {637, &ppc_fnmsubsdot}, - {638, &ppc_fnmadds}, {639, &ppc_fnmaddsdot}, {690, &ppc_fmults}, {691, &ppc_fmultsdot}, - {696, &ppc_fmsubs}, {697, &ppc_fmsubsdot}, {698, &ppc_fmadds}, {699, &ppc_fmaddsdot}, - {700, &ppc_fnmsubs}, {701, &ppc_fnmsubsdot}, {702, &ppc_fnmadds}, {703, &ppc_fnmaddsdot}, - {754, &ppc_fmults}, {755, &ppc_fmultsdot}, {760, &ppc_fmsubs}, {761, &ppc_fmsubsdot}, - {762, &ppc_fmadds}, {763, &ppc_fmaddsdot}, {764, &ppc_fnmsubs}, {765, &ppc_fnmsubsdot}, - {766, &ppc_fnmadds}, {767, &ppc_fnmaddsdot}, {818, &ppc_fmults}, {819, &ppc_fmultsdot}, - {824, &ppc_fmsubs}, {825, &ppc_fmsubsdot}, {826, &ppc_fmadds}, {827, &ppc_fmaddsdot}, - {828, &ppc_fnmsubs}, {829, &ppc_fnmsubsdot}, {830, &ppc_fnmadds}, {831, &ppc_fnmaddsdot}, - {882, &ppc_fmults}, {883, &ppc_fmultsdot}, {888, &ppc_fmsubs}, {889, &ppc_fmsubsdot}, - {890, &ppc_fmadds}, {891, &ppc_fmaddsdot}, {892, &ppc_fnmsubs}, {893, &ppc_fnmsubsdot}, - {894, &ppc_fnmadds}, {895, &ppc_fnmaddsdot}, {946, &ppc_fmults}, {947, &ppc_fmultsdot}, - {952, &ppc_fmsubs}, {953, &ppc_fmsubsdot}, {954, &ppc_fmadds}, {955, &ppc_fmaddsdot}, - {957, &ppc_fnmsubs}, {958, &ppc_fnmsubsdot}, {958, &ppc_fnmadds}, {959, &ppc_fnmaddsdot}, - {1010, &ppc_fmults}, {1011, &ppc_fmultsdot}, {1016, &ppc_fmsubs}, {1017, &ppc_fmsubsdot}, - {1018, &ppc_fmadds}, {1019, &ppc_fmaddsdot}, {1020, &ppc_fnmsubs}, {1021, &ppc_fnmsubsdot}, - {1022, &ppc_fnmadds}, {1023, &ppc_fnmaddsdot}, {1074, &ppc_fmults}, {1075, &ppc_fmultsdot}, - {1080, &ppc_fmsubs}, {1081, &ppc_fmsubsdot}, {1082, &ppc_fmadds}, {1083, &ppc_fmaddsdot}, - {1084, &ppc_fnmsubs}, {1085, &ppc_fnmsubsdot}, {1086, &ppc_fnmadds}, {1087, &ppc_fnmaddsdot}, - {1138, &ppc_fmults}, {1139, &ppc_fmultsdot}, {1144, &ppc_fmsubs}, {1145, &ppc_fmsubsdot}, - {1146, &ppc_fmadds}, {1147, &ppc_fmaddsdot}, {1148, &ppc_fnmsubs}, {1149, &ppc_fnmsubsdot}, - {1150, &ppc_fnmadds}, {1151, &ppc_fnmaddsdot}, {1202, &ppc_fmults}, {1203, &ppc_fmultsdot}, - {1208, &ppc_fmsubs}, {1209, &ppc_fmsubsdot}, {1210, &ppc_fmadds}, {1211, &ppc_fmaddsdot}, - {1212, &ppc_fnmsubs}, {1213, &ppc_fnmsubsdot}, {1214, &ppc_fnmadds}, {1215, &ppc_fnmaddsdot}, - {1266, &ppc_fmults}, {1267, &ppc_fmultsdot}, {1272, &ppc_fmsubs}, {1273, &ppc_fmsubsdot}, - {1274, &ppc_fmadds}, {1275, &ppc_fmaddsdot}, {1276, &ppc_fnmsubs}, {1277, &ppc_fnmsubsdot}, - {1278, &ppc_fnmadds}, {1279, &ppc_fnmaddsdot}, {1330, &ppc_fmults}, {1331, &ppc_fmultsdot}, - {1336, &ppc_fmsubs}, {1337, &ppc_fmsubsdot}, {1338, &ppc_fmadds}, {1339, &ppc_fmaddsdot}, - {1340, &ppc_fnmsubs}, {1341, &ppc_fnmsubsdot}, {1342, &ppc_fnmadds}, {1343, &ppc_fnmaddsdot}, - {1394, &ppc_fmults}, {1395, &ppc_fmultsdot}, {1400, &ppc_fmsubs}, {1401, &ppc_fmsubsdot}, - {1402, &ppc_fmadds}, {1403, &ppc_fmaddsdot}, {1404, &ppc_fnmsubs}, {1405, &ppc_fnmsubsdot}, - {1406, &ppc_fnmadds}, {1407, &ppc_fnmaddsdot}, {1458, &ppc_fmults}, {1459, &ppc_fmultsdot}, - {1464, &ppc_fmsubs}, {1465, &ppc_fmsubsdot}, {1466, &ppc_fmadds}, {1467, &ppc_fmaddsdot}, - {1468, &ppc_fnmsubs}, {1469, &ppc_fnmsubsdot}, {1470, &ppc_fnmadds}, {1471, &ppc_fnmaddsdot}, - {1522, &ppc_fmults}, {1523, &ppc_fmultsdot}, {1528, &ppc_fmsubs}, {1529, &ppc_fmsubsdot}, - {1530, &ppc_fmadds}, {1531, &ppc_fmaddsdot}, {1532, &ppc_fnmsubs}, {1533, &ppc_fnmsubsdot}, - {1534, &ppc_fnmadds}, {1535, &ppc_fnmaddsdot}, {1586, &ppc_fmults}, {1587, &ppc_fmultsdot}, - {1592, &ppc_fmsubs}, {1593, &ppc_fmsubsdot}, {1594, &ppc_fmadds}, {1595, &ppc_fmaddsdot}, - {1596, &ppc_fnmsubs}, {1597, &ppc_fnmsubsdot}, {1598, &ppc_fnmadds}, {1599, &ppc_fnmaddsdot}, - {1650, &ppc_fmults}, {1651, &ppc_fmultsdot}, {1656, &ppc_fmsubs}, {1657, &ppc_fmsubsdot}, - {1658, &ppc_fmadds}, {1659, &ppc_fmaddsdot}, {1660, &ppc_fnmsubs}, {1661, &ppc_fnmsubsdot}, - {1662, &ppc_fnmadds}, {1663, &ppc_fnmaddsdot}, {1714, &ppc_fmults}, {1715, &ppc_fmultsdot}, - {1720, &ppc_fmsubs}, {1721, &ppc_fmsubsdot}, {1722, &ppc_fmadds}, {1723, &ppc_fmaddsdot}, - {1724, &ppc_fnmsubs}, {1725, &ppc_fnmsubsdot}, {1726, &ppc_fnmadds}, {1727, &ppc_fnmaddsdot}, - {1778, &ppc_fmults}, {1779, &ppc_fmultsdot}, {1784, &ppc_fmsubs}, {1785, &ppc_fmsubsdot}, - {1786, &ppc_fmadds}, {1787, &ppc_fmaddsdot}, {1788, &ppc_fnmsubs}, {1789, &ppc_fnmsubsdot}, - {1790, &ppc_fnmadds}, {1791, &ppc_fnmaddsdot}, {1842, &ppc_fmults}, {1843, &ppc_fmultsdot}, - {1848, &ppc_fmsubs}, {1849, &ppc_fmsubsdot}, {1850, &ppc_fmadds}, {1851, &ppc_fmaddsdot}, - {1852, &ppc_fnmsubs}, {1853, &ppc_fnmsubsdot}, {1854, &ppc_fnmadds}, {1855, &ppc_fnmaddsdot}, - {1906, &ppc_fmults}, {1907, &ppc_fmultsdot}, {1912, &ppc_fmsubs}, {1913, &ppc_fmsubsdot}, - {1914, &ppc_fmadds}, {1915, &ppc_fmaddsdot}, {1916, &ppc_fnmsubs}, {1917, &ppc_fnmsubsdot}, - {1918, &ppc_fnmadds}, {1919, &ppc_fnmaddsdot}, {1970, &ppc_fmults}, {1971, &ppc_fmultsdot}, - {1976, &ppc_fmsubs}, {1977, &ppc_fmsubsdot}, {1978, &ppc_fmadds}, {1979, &ppc_fmaddsdot}, - {1980, &ppc_fnmsubs}, {1981, &ppc_fnmsubsdot}, {1982, &ppc_fnmadds}, {1983, &ppc_fnmaddsdot}, - {2034, &ppc_fmults}, {2035, &ppc_fmultsdot}, {2040, &ppc_fmsubs}, {2041, &ppc_fmsubsdot}, - {2042, &ppc_fmadds}, {2043, &ppc_fmaddsdot}, {2044, &ppc_fnmsubs}, {2045, &ppc_fnmsubsdot}, - {2046, &ppc_fnmadds}, {2047, &ppc_fnmaddsdot}}; - -/** Double-precision floating-point instructions decoding table. */ -static std::unordered_map SubOpcode63Grabber = { - {0, &ppc_fcmpu}, {24, &ppc_frsp}, {25, &ppc_frspdot}, {28, &ppc_fctiw}, - {29, &ppc_fctiwdot}, {30, &ppc_fctiwz}, {31, &ppc_fctiwzdot}, {36, &ppc_fdiv}, - {37, &ppc_fdivdot}, {40, &ppc_fsub}, {41, &ppc_fsubdot}, {42, &ppc_fadd}, - {43, &ppc_fadddot}, {44, &ppc_fsqrt}, {45, &ppc_fsqrtdot}, {46, &ppc_fsel}, - {47, &ppc_fseldot}, {50, &ppc_fmult}, {51, &ppc_fmultdot}, {52, &ppc_frsqrte}, - {53, &ppc_frsqrtedot}, {56, &ppc_fmsub}, {57, &ppc_fmsubdot}, {58, &ppc_fmadd}, - {59, &ppc_fmadddot}, {60, &ppc_fnmsub}, {61, &ppc_fnmsubdot}, {62, &ppc_fnmadd}, - {63, &ppc_fnmadddot}, {64, &ppc_fcmpo}, {76, &ppc_mtfsb1}, {77, &ppc_mtfsb1dot}, - {80, &ppc_fneg}, {81, &ppc_fnegdot}, {110, &ppc_fsel}, {111, &ppc_fseldot}, - {114, &ppc_fmult}, {115, &ppc_fmultdot}, {120, &ppc_fmsub}, {121, &ppc_fmsubdot}, - {122, &ppc_fmadd}, {123, &ppc_fmadd}, {124, &ppc_fnmsub}, {125, &ppc_fnmsubdot}, - {126, &ppc_fnmadd}, {127, &ppc_fnmadddot}, {128, &ppc_mcrfs}, {140, &ppc_mtfsb0}, - {141, &ppc_mtfsb0dot}, {144, &ppc_fmr}, {174, &ppc_fsel}, {175, &ppc_fseldot}, - {178, &ppc_fmult}, {179, &ppc_fmultdot}, {184, &ppc_fmsub}, {185, &ppc_fmsubdot}, - {186, &ppc_fmadd}, {187, &ppc_fmadddot}, {188, &ppc_fnmsub}, {189, &ppc_fnmsubdot}, - {190, &ppc_fnmadd}, {191, &ppc_fnmadddot}, {238, &ppc_fsel}, {239, &ppc_fseldot}, - {242, &ppc_fmult}, {243, &ppc_fmultdot}, {248, &ppc_fmsub}, {249, &ppc_fmsubdot}, - {250, &ppc_fmadd}, {251, &ppc_fmadddot}, {252, &ppc_fnmsub}, {253, &ppc_fnmsubdot}, - {254, &ppc_fnmadd}, {255, &ppc_fnmadddot}, {268, &ppc_mtfsfi}, {272, &ppc_fnabs}, - {273, &ppc_fnabsdot}, {302, &ppc_fsel}, {303, &ppc_fseldot}, {306, &ppc_fmult}, - {307, &ppc_fmultdot}, {312, &ppc_fmsub}, {313, &ppc_fmsubdot}, {314, &ppc_fmadd}, - {315, &ppc_fmadddot}, {316, &ppc_fnmsub}, {317, &ppc_fnmsubdot}, {318, &ppc_fnmadd}, - {319, &ppc_fnmadddot}, {366, &ppc_fsel}, {367, &ppc_fseldot}, {370, &ppc_fmult}, - {371, &ppc_fmultdot}, {376, &ppc_fmsub}, {377, &ppc_fmsubdot}, {378, &ppc_fmadd}, - {379, &ppc_fmadddot}, {380, &ppc_fnmsub}, {381, &ppc_fnmsubdot}, {382, &ppc_fnmadd}, - {383, &ppc_fnmadddot}, {430, &ppc_fsel}, {431, &ppc_fseldot}, {434, &ppc_fmult}, - {435, &ppc_fmultdot}, {440, &ppc_fmsub}, {441, &ppc_fmsubdot}, {442, &ppc_fmadd}, - {443, &ppc_fmadddot}, {444, &ppc_fnmsub}, {445, &ppc_fnmsubdot}, {446, &ppc_fnmadd}, - {447, &ppc_fnmadddot}, {494, &ppc_fsel}, {495, &ppc_fseldot}, {498, &ppc_fmult}, - {499, &ppc_fmultdot}, {504, &ppc_fmsub}, {505, &ppc_fmsubdot}, {506, &ppc_fmadd}, - {507, &ppc_fmadddot}, {508, &ppc_fnmsub}, {509, &ppc_fnmsubdot}, {510, &ppc_fnmadd}, - {511, &ppc_fnmadddot}, {528, &ppc_fabs}, {529, &ppc_fabsdot}, {536, &ppc_mtfsfidot}, - {558, &ppc_fsel}, {559, &ppc_fseldot}, {562, &ppc_fmult}, {563, &ppc_fmultdot}, - {568, &ppc_fmsub}, {569, &ppc_fmsubdot}, {570, &ppc_fmadd}, {571, &ppc_fmadddot}, - {572, &ppc_fnmsub}, {573, &ppc_fnmsubdot}, {574, &ppc_fnmadd}, {575, &ppc_fnmadddot}, - {622, &ppc_fsel}, {623, &ppc_fseldot}, {626, &ppc_fmult}, {627, &ppc_fmultdot}, - {632, &ppc_fmsub}, {633, &ppc_fmsubdot}, {634, &ppc_fmadd}, {635, &ppc_fmadddot}, - {636, &ppc_fnmsub}, {637, &ppc_fnmsubdot}, {638, &ppc_fnmadd}, {639, &ppc_fnmadddot}, - {686, &ppc_fsel}, {687, &ppc_fseldot}, {690, &ppc_fmult}, {691, &ppc_fmultdot}, - {696, &ppc_fmsub}, {697, &ppc_fmsubdot}, {698, &ppc_fmadd}, {699, &ppc_fmadddot}, - {700, &ppc_fnmsub}, {701, &ppc_fnmsubdot}, {702, &ppc_fnmadd}, {703, &ppc_fnmadddot}, - {750, &ppc_fsel}, {751, &ppc_fseldot}, {754, &ppc_fmult}, {755, &ppc_fmultdot}, - {760, &ppc_fmsub}, {761, &ppc_fmsubdot}, {762, &ppc_fmadd}, {763, &ppc_fmadddot}, - {764, &ppc_fnmsub}, {765, &ppc_fnmsubdot}, {766, &ppc_fnmadd}, {767, &ppc_fnmadddot}, - {814, &ppc_fsel}, {815, &ppc_fseldot}, {818, &ppc_fmult}, {819, &ppc_fmultdot}, - {824, &ppc_fmsub}, {825, &ppc_fmsubdot}, {826, &ppc_fmadd}, {827, &ppc_fmadddot}, - {828, &ppc_fnmsub}, {829, &ppc_fnmsubdot}, {830, &ppc_fnmadd}, {831, &ppc_fnmadddot}, - {878, &ppc_fsel}, {879, &ppc_fseldot}, {882, &ppc_fmult}, {883, &ppc_fmultdot}, - {888, &ppc_fmsub}, {889, &ppc_fmsubdot}, {890, &ppc_fmadd}, {891, &ppc_fmadddot}, - {892, &ppc_fnmsub}, {893, &ppc_fnmsubdot}, {894, &ppc_fnmadd}, {895, &ppc_fnmadddot}, - {942, &ppc_fsel}, {943, &ppc_fseldot}, {946, &ppc_fmult}, {947, &ppc_fmultdot}, - {952, &ppc_fmsub}, {953, &ppc_fmsubdot}, {954, &ppc_fmadd}, {955, &ppc_fmadddot}, - {957, &ppc_fnmsub}, {958, &ppc_fnmsubdot}, {958, &ppc_fnmadd}, {959, &ppc_fnmadddot}, - {1006, &ppc_fsel}, {1007, &ppc_fseldot}, {1010, &ppc_fmult}, {1011, &ppc_fmultdot}, - {1016, &ppc_fmsub}, {1017, &ppc_fmsubdot}, {1018, &ppc_fmadd}, {1019, &ppc_fmadddot}, - {1020, &ppc_fnmsub}, {1021, &ppc_fnmsubdot}, {1022, &ppc_fnmadd}, {1023, &ppc_fnmadddot}, - {1070, &ppc_fsel}, {1071, &ppc_fseldot}, {1074, &ppc_fmult}, {1075, &ppc_fmultdot}, - {1080, &ppc_fmsub}, {1081, &ppc_fmsubdot}, {1082, &ppc_fmadd}, {1083, &ppc_fmadddot}, - {1084, &ppc_fnmsub}, {1085, &ppc_fnmsubdot}, {1086, &ppc_fnmadd}, {1087, &ppc_fnmadddot}, - {1134, &ppc_fsel}, {1135, &ppc_fseldot}, {1138, &ppc_fmult}, {1139, &ppc_fmultdot}, - {1144, &ppc_fmsub}, {1145, &ppc_fmsubdot}, {1146, &ppc_fmadd}, {1147, &ppc_fmadddot}, - {1148, &ppc_fnmsub}, {1149, &ppc_fnmsubdot}, {1150, &ppc_fnmadd}, {1151, &ppc_fnmadddot}, - {1166, &ppc_mffs}, {1167, &ppc_mffsdot}, {1198, &ppc_fsel}, {1199, &ppc_fseldot}, - {1202, &ppc_fmult}, {1203, &ppc_fmultdot}, {1208, &ppc_fmsub}, {1209, &ppc_fmsubdot}, - {1210, &ppc_fmadd}, {1211, &ppc_fmadddot}, {1212, &ppc_fnmsub}, {1213, &ppc_fnmsubdot}, - {1214, &ppc_fnmadd}, {1215, &ppc_fnmadddot}, {1262, &ppc_fsel}, {1263, &ppc_fseldot}, - {1266, &ppc_fmult}, {1267, &ppc_fmultdot}, {1272, &ppc_fmsub}, {1273, &ppc_fmsubdot}, - {1274, &ppc_fmadd}, {1275, &ppc_fmadddot}, {1276, &ppc_fnmsub}, {1277, &ppc_fnmsubdot}, - {1278, &ppc_fnmadd}, {1279, &ppc_fnmadddot}, {1326, &ppc_fsel}, {1327, &ppc_fseldot}, - {1330, &ppc_fmult}, {1331, &ppc_fmultdot}, {1336, &ppc_fmsub}, {1337, &ppc_fmsubdot}, - {1338, &ppc_fmadd}, {1339, &ppc_fmadddot}, {1340, &ppc_fnmsub}, {1341, &ppc_fnmsubdot}, - {1342, &ppc_fnmadd}, {1343, &ppc_fnmadddot}, {1390, &ppc_fsel}, {1391, &ppc_fseldot}, - {1394, &ppc_fmult}, {1395, &ppc_fmultdot}, {1400, &ppc_fmsub}, {1401, &ppc_fmsubdot}, - {1402, &ppc_fmadd}, {1403, &ppc_fmadddot}, {1404, &ppc_fnmsub}, {1405, &ppc_fnmsubdot}, - {1406, &ppc_fnmadd}, {1407, &ppc_fnmadddot}, {1422, &ppc_mtfsf}, {1423, &ppc_mtfsfdot}, - {1454, &ppc_fsel}, {1455, &ppc_fseldot}, {1458, &ppc_fmult}, {1459, &ppc_fmultdot}, - {1464, &ppc_fmsub}, {1465, &ppc_fmsubdot}, {1466, &ppc_fmadd}, {1467, &ppc_fmadddot}, - {1468, &ppc_fnmsub}, {1469, &ppc_fnmsubdot}, {1470, &ppc_fnmadd}, {1471, &ppc_fnmadddot}, - {1518, &ppc_fsel}, {1519, &ppc_fseldot}, {1522, &ppc_fmult}, {1523, &ppc_fmultdot}, - {1528, &ppc_fmsub}, {1529, &ppc_fmsubdot}, {1530, &ppc_fmadd}, {1531, &ppc_fmadddot}, - {1532, &ppc_fnmsub}, {1533, &ppc_fnmsubdot}, {1534, &ppc_fnmadd}, {1535, &ppc_fnmadddot}, - {1582, &ppc_fsel}, {1583, &ppc_fseldot}, {1586, &ppc_fmult}, {1587, &ppc_fmultdot}, - {1592, &ppc_fmsub}, {1593, &ppc_fmsubdot}, {1594, &ppc_fmadd}, {1595, &ppc_fmadddot}, - {1596, &ppc_fnmsub}, {1597, &ppc_fnmsubdot}, {1598, &ppc_fnmadd}, {1599, &ppc_fnmadddot}, - {1646, &ppc_fsel}, {1647, &ppc_fseldot}, {1650, &ppc_fmult}, {1651, &ppc_fmultdot}, - {1656, &ppc_fmsub}, {1657, &ppc_fmsubdot}, {1658, &ppc_fmadd}, {1659, &ppc_fmadddot}, - {1660, &ppc_fnmsub}, {1661, &ppc_fnmsubdot}, {1662, &ppc_fnmadd}, {1663, &ppc_fnmadddot}, - {1710, &ppc_fsel}, {1711, &ppc_fseldot}, {1714, &ppc_fmult}, {1715, &ppc_fmultdot}, - {1720, &ppc_fmsub}, {1721, &ppc_fmsubdot}, {1722, &ppc_fmadd}, {1723, &ppc_fmadddot}, - {1724, &ppc_fnmsub}, {1725, &ppc_fnmsubdot}, {1726, &ppc_fnmadd}, {1727, &ppc_fnmadddot}, - {1774, &ppc_fsel}, {1775, &ppc_fseldot}, {1778, &ppc_fmult}, {1779, &ppc_fmultdot}, - {1784, &ppc_fmsub}, {1785, &ppc_fmsubdot}, {1786, &ppc_fmadd}, {1787, &ppc_fmadddot}, - {1788, &ppc_fnmsub}, {1789, &ppc_fnmsubdot}, {1790, &ppc_fnmadd}, {1791, &ppc_fnmadddot}, - {1838, &ppc_fsel}, {1839, &ppc_fseldot}, {1842, &ppc_fmult}, {1843, &ppc_fmultdot}, - {1848, &ppc_fmsub}, {1849, &ppc_fmsubdot}, {1850, &ppc_fmadd}, {1851, &ppc_fmadddot}, - {1852, &ppc_fnmsub}, {1853, &ppc_fnmsubdot}, {1854, &ppc_fnmadd}, {1855, &ppc_fnmadddot}, - {1902, &ppc_fsel}, {1903, &ppc_fseldot}, {1906, &ppc_fmult}, {1907, &ppc_fmultdot}, - {1912, &ppc_fmsub}, {1913, &ppc_fmsubdot}, {1914, &ppc_fmadd}, {1915, &ppc_fmadddot}, - {1916, &ppc_fnmsub}, {1917, &ppc_fnmsubdot}, {1918, &ppc_fnmadd}, {1919, &ppc_fnmadddot}, - {1966, &ppc_fsel}, {1967, &ppc_fseldot}, {1970, &ppc_fmult}, {1971, &ppc_fmultdot}, - {1976, &ppc_fmsub}, {1977, &ppc_fmsubdot}, {1978, &ppc_fmadd}, {1979, &ppc_fmadddot}, - {1980, &ppc_fnmsub}, {1981, &ppc_fnmsubdot}, {1982, &ppc_fnmadd}, {1983, &ppc_fnmadddot}, - {2030, &ppc_fsel}, {2031, &ppc_fseldot}, {2034, &ppc_fmult}, {2035, &ppc_fmultdot}, - {2040, &ppc_fmsub}, {2041, &ppc_fmsubdot}, {2042, &ppc_fmadd}, {2043, &ppc_fmadddot}, - {2044, &ppc_fnmsub}, {2045, &ppc_fnmsubdot}, {2046, &ppc_fnmadd}, {2047, &ppc_fnmadddot}}; +PPCOpcode SubOpcode31Grabber[1024] = {ppc_illegalsubop19}; +PPCOpcode SubOpcode59Grabber[1024] = {ppc_illegalsubop19}; +PPCOpcode SubOpcode63Grabber[1024] = {ppc_illegalsubop19}; #define UPDATE_TBR_DEC \ @@ -427,6 +115,34 @@ void ppc_illegalop() { exit(-1); } +void ppc_illegalsubop19() { + uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; + uint32_t grab_it = (uint32_t)illegal_subcode; + LOG_F(ERROR, "Illegal subopcode for 19 reported: %d Report this! \n", grab_it); + exit(-1); +} + +void ppc_illegalsubop31() { + uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; + uint32_t grab_it = (uint32_t)illegal_subcode; + LOG_F(ERROR, "Illegal subopcode for 31 reported: %d Report this! \n", grab_it); + exit(-1); +} + +void ppc_illegalsubop59() { + uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; + uint32_t grab_it = (uint32_t)illegal_subcode; + LOG_F(ERROR, "Illegal subopcode for 59 reported: %d Report this! \n", grab_it); + exit(-1); +} + +void ppc_illegalsubop63() { + uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; + uint32_t grab_it = (uint32_t)illegal_subcode; + LOG_F(ERROR, "Illegal subopcode for 63 reported: %d Report this! \n", grab_it); + exit(-1); +} + void ppc_opcode4() { LOG_F(INFO, "Reading from Opcode 4 table \n"); uint8_t subop_grab = ppc_cur_instruction & 3; @@ -445,67 +161,92 @@ void ppc_opcode18() { } void ppc_opcode19() { - uint16_t subop_grab = ppc_cur_instruction & 2047; + uint16_t subop_grab = ppc_cur_instruction & 0x7FF; + #ifdef EXHAUSTIVE_DEBUG uint32_t regrab = (uint32_t)subop_grab; LOG_F(INFO, "Executing Opcode 19 table subopcode entry \n", regrab); - if (SubOpcode19Grabber.count(subop_grab) == 1) { - SubOpcode19Grabber[subop_grab](); - } else { - LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab); - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); - } -#else - SubOpcode19Grabber[subop_grab](); #endif // EXHAUSTIVE_DEBUG + + if (subop_grab == 32) { + ppc_bclr(); + } else if (subop_grab == 33) { + ppc_bclrl(); + } else if (subop_grab == 1056) { + ppc_bcctr(); + } else if (subop_grab == 1057) { + ppc_bcctrl(); + + } else { + switch (subop_grab) { + case 66: + ppc_crnor(); + break; + case 100: + ppc_rfi(); + break; + case 258: + ppc_crandc(); + break; + case 300: + ppc_isync(); + break; + case 386: + ppc_crxor(); + break; + case 450: + ppc_crnand(); + break; + case 514: + ppc_crand(); + break; + case 578: + ppc_creqv(); + break; + case 834: + ppc_crorc(); + break; + case 898: + ppc_cror(); + break; + default: // Illegal opcode - should never happen + ppc_illegalsubop19(); + } + } } void ppc_opcode31() { - uint16_t subop_grab = ppc_cur_instruction & 2047; -#ifdef EXHAUSTIVE_DEBUG - uint32_t regrab = (uint32_t)subop_grab; - LOG_F(INFO, "Executing Opcode 31 table subopcode entry \n", regrab); - if (SubOpcode31Grabber.count(subop_grab) == 1) { - SubOpcode31Grabber[subop_grab](); - } else { - LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab); - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); - } -#else - SubOpcode31Grabber[subop_grab](); -#endif // EXHAUSTIVE_DEBUG -} + uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1; -void ppc_opcode59() { - uint16_t subop_grab = ppc_cur_instruction & 2047; -#ifdef EXHAUSTIVE_DEBUG - uint32_t regrab = (uint32_t)subop_grab; - LOG_F(INFO, "Executing Opcode 59 table subopcode entry \n", regrab); - if (SubOpcode59Grabber.count(subop_grab) == 1) { - SubOpcode59Grabber[subop_grab](); - } else { - LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab); - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); - } -#else - SubOpcode59Grabber[subop_grab](); -#endif // EXHAUSTIVE_DEBUG -} + rc_flag = ppc_cur_instruction & 0x1; + oe_flag = ppc_cur_instruction & 0x400; -void ppc_opcode63() { - uint16_t subop_grab = ppc_cur_instruction & 2047; #ifdef EXHAUSTIVE_DEBUG uint32_t regrab = (uint32_t)subop_grab; LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab); - if (SubOpcode63Grabber.count(subop_grab) == 1) { - SubOpcode63Grabber[subop_grab](); - } else { - LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab); - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); - } -#else - SubOpcode63Grabber[subop_grab](); #endif // EXHAUSTIVE_DEBUG + + SubOpcode31Grabber[subop_grab](); +} + +void ppc_opcode59() { + uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1; + rc_flag = subop_grab & 1; +#ifdef EXHAUSTIVE_DEBUG + uint32_t regrab = (uint32_t)subop_grab; + LOG_F(INFO, "Executing Opcode 59 table subopcode entry \n", regrab); +#endif // EXHAUSTIVE_DEBUG + SubOpcode59Grabber[subop_grab](); +} + +void ppc_opcode63() { + uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1; + rc_flag = subop_grab & 1; +#ifdef EXHAUSTIVE_DEBUG + uint32_t regrab = (uint32_t)subop_grab; + LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab); +#endif // EXHAUSTIVE_DEBUG + SubOpcode63Grabber[subop_grab](); } /* Dispatch using main opcode */ @@ -704,6 +445,209 @@ void test_timebase_update() } +void initialize_ppc_opcode_tables() { + SubOpcode31Grabber[0] = ppc_cmp; + SubOpcode31Grabber[4] = ppc_tw; + SubOpcode31Grabber[32] = 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[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[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_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[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[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[26] = ppc_cntlzw; + + 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[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[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[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; + + SubOpcode63Grabber[18] = ppc_fdivs; + SubOpcode63Grabber[20] = ppc_fsubs; + SubOpcode63Grabber[22] = ppc_fsqrts; + SubOpcode63Grabber[24] = ppc_fres; + + for (int i = 25; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmults; + } + + for (int i = 28; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmsubs; + } + + for (int i = 29; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmadds; + } + + for (int i = 30; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fnmsubs; + } + + for (int i = 31; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fnmadds; + } + + 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; + + for (int i = 23; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fsel; + } + + for (int i = 25; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmult; + } + + for (int i = 28; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmsub; + } + + for (int i = 29; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fmadd; + } + + for (int i = 30; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fnmsub; + } + + for (int i = 31; i < 1024; i += 32) { + SubOpcode63Grabber[i] = ppc_fnmadd; + } +} + void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version) { int i; diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index eff138b..b0bfa3b 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -378,16 +378,9 @@ void ppc_fadd() { ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b; ppc_store_dfpresult(false); } -} -void ppc_fadddot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) { - ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b; - ppc_store_dfpresult(false); - } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fsub() { @@ -397,16 +390,9 @@ void ppc_fsub() { ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b; ppc_store_dfpresult(false); } -} -void ppc_fsubdot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) { - ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b; - ppc_store_dfpresult(false); - } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fdiv() { @@ -416,16 +402,9 @@ void ppc_fdiv() { ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b; ppc_store_dfpresult(false); } -} -void ppc_fdivdot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) { - ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b; - ppc_store_dfpresult(false); - } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmult() { @@ -435,17 +414,9 @@ void ppc_fmult() { ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b; ppc_store_dfpresult(false); } -} -void ppc_fmultdot() { - ppc_grab_regsfpdac(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 50)) { - ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b; - ppc_store_dfpresult(false); - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmadd() { @@ -459,20 +430,9 @@ void ppc_fmadd() { } ppc_store_dfpresult(false); -} -void ppc_fmadddot() { - ppc_grab_regsfpdabc(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c); - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) { - ppc_dblresult64_d += ppc_dblresult64_b; - } - } - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmsub() { @@ -486,20 +446,9 @@ void ppc_fmsub() { } ppc_store_dfpresult(false); -} -void ppc_fmsubdot() { - ppc_grab_regsfpdabc(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c); - if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) { - ppc_dblresult64_d -= ppc_dblresult64_b; - } - } - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fnmadd() { @@ -514,22 +463,9 @@ void ppc_fnmadd() { ppc_dblresult64_d = -ppc_dblresult64_d; ppc_store_dfpresult(false); -} -void ppc_fnmadddot() { - ppc_grab_regsfpdabc(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c); - if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) { - ppc_dblresult64_d += ppc_dblresult64_b; - } - } - - ppc_dblresult64_d = -ppc_dblresult64_d; - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fnmsub() { @@ -544,21 +480,9 @@ void ppc_fnmsub() { ppc_dblresult64_d = -ppc_dblresult64_d; ppc_store_dfpresult(false); -} -void ppc_fnmsubdot() { - ppc_grab_regsfpdabc(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c); - if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) { - ppc_dblresult64_d -= ppc_dblresult64_b; - } - } - ppc_dblresult64_d = -ppc_dblresult64_d; - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fadds() { @@ -569,18 +493,9 @@ void ppc_fadds() { ppc_dblresult64_d = static_cast(intermediate); ppc_store_dfpresult(false); } -} -void ppc_faddsdot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { - float intermediate = (float)ppc_dblresult64_a + (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - ppc_store_dfpresult(false); - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fsubs() { @@ -591,18 +506,9 @@ void ppc_fsubs() { ppc_dblresult64_d = static_cast(intermediate); ppc_store_dfpresult(false); } -} -void ppc_fsubsdot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) { - float intermediate = (float)ppc_dblresult64_a - (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - ppc_store_dfpresult(false); - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmults() { @@ -613,17 +519,9 @@ void ppc_fmults() { ppc_dblresult64_d = static_cast(intermediate); ppc_store_dfpresult(false); } -} -void ppc_fmultsdot() { - ppc_grab_regsfpdac(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 50)) { - float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - ppc_store_dfpresult(false); - } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fdivs() { @@ -634,18 +532,9 @@ void ppc_fdivs() { ppc_dblresult64_d = static_cast(intermediate); ppc_store_dfpresult(false); } -} -void ppc_fdivsdot() { - ppc_grab_regsfpdab(false); - - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) { - float intermediate = (float)ppc_dblresult64_a / (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - ppc_store_dfpresult(false); - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmadds() { @@ -662,24 +551,9 @@ void ppc_fmadds() { ppc_store_dfpresult(false); } } -} -void ppc_fmaddsdot() { - ppc_grab_regsfpdabc(false); - - float intermediate; - - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { - intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c; - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { - intermediate += (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - - ppc_store_dfpresult(false); - } - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fmsubs() { @@ -696,24 +570,9 @@ void ppc_fmsubs() { ppc_store_dfpresult(false); } } -} -void ppc_fmsubsdot() { - ppc_grab_regsfpdabc(false); - - float intermediate; - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c; - if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) { - intermediate -= (float)ppc_dblresult64_b; - ppc_dblresult64_d = static_cast(intermediate); - - ppc_store_dfpresult(false); - } - } - - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fnmadds() { @@ -721,24 +580,6 @@ void ppc_fnmadds() { float intermediate; - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { - intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c; - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { - intermediate += (float)ppc_dblresult64_b; - intermediate = -intermediate; - - ppc_dblresult64_d = static_cast(intermediate); - } - } - - ppc_store_dfpresult(false); -} - -void ppc_fnmaddsdot() { - ppc_grab_regsfpdabc(false); - - float intermediate; - if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c; if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { @@ -751,7 +592,8 @@ void ppc_fnmaddsdot() { } } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fnmsubs() { @@ -770,25 +612,9 @@ void ppc_fnmsubs() { ppc_store_dfpresult(false); } } -} -void ppc_fnmsubsdot() { - ppc_grab_regsfpdabc(false); - - float intermediate; - - if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { - intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c; - if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) { - intermediate -= (float)ppc_dblresult64_b; - intermediate = -intermediate; - - ppc_dblresult64_d = static_cast(intermediate); - - ppc_store_dfpresult(false); - } - } - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fabs() { @@ -797,15 +623,9 @@ void ppc_fabs() { ppc_dblresult64_d = abs(ppc_dblresult64_b); ppc_store_dfpresult(false); -} -void ppc_fabsdot() { - ppc_grab_regsfpdb(false); - - ppc_dblresult64_d = abs(ppc_dblresult64_b); - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fnabs() { @@ -815,16 +635,9 @@ void ppc_fnabs() { ppc_dblresult64_d = -ppc_dblresult64_d; ppc_store_dfpresult(false); -} -void ppc_fnabsdot() { - ppc_grab_regsfpdb(false); - - ppc_dblresult64_d = abs(ppc_dblresult64_b); - ppc_dblresult64_d = -ppc_dblresult64_d; - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fneg() { @@ -833,15 +646,9 @@ void ppc_fneg() { ppc_dblresult64_d = -ppc_dblresult64_d; ppc_store_dfpresult(false); -} -void ppc_fnegdot() { - ppc_grab_regsfpdb(false); - - ppc_dblresult64_d = -ppc_dblresult64_d; - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fsel() { @@ -854,32 +661,18 @@ void ppc_fsel() { } ppc_store_dfpresult(false); -} -void ppc_fseldot() { - ppc_grab_regsfpdabc(false); - - if (ppc_dblresult64_a >= 0.0) { - ppc_dblresult64_d = ppc_dblresult64_c; - } else { - ppc_dblresult64_d = ppc_dblresult64_b; - } - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fsqrt() { ppc_grab_regsfpdb(false); ppc_dblresult64_d = std::sqrt(ppc_dblresult64_b); ppc_store_dfpresult(false); -} -void ppc_fsqrtdot() { - ppc_grab_regsfpdb(false); - ppc_dblresult64_d = std::sqrt(ppc_dblresult64_b); - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fsqrts() { @@ -890,17 +683,9 @@ void ppc_fsqrts() { uint64_t* pre_final = (uint64_t*)&test; ppc_result64_d = *pre_final; ppc_store_dfpresult(true); -} -void ppc_fsqrtsdot() { - ppc_grab_regsfpdb(true); - uint32_t test = (uint32_t)ppc_result64_b; - test += 127 << 23; - test >>= 1; - uint64_t* pre_final = (uint64_t*)&test; - ppc_result64_d = *pre_final; - ppc_store_dfpresult(true); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_frsqrte() { @@ -912,18 +697,9 @@ void ppc_frsqrte() { ppc_dblresult64_d = testd2; ppc_store_dfpresult(false); -} -void ppc_frsqrtedot() { - ppc_grab_regsfpdb(false); - double testd2 = (double)ppc_result64_b; - for (int i = 0; i < 10; i++) { - testd2 = testd2 * (1.5 - (testd2 * .5) * testd2 * testd2); - } - ppc_dblresult64_d = testd2; - - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_frsp() { @@ -932,15 +708,9 @@ void ppc_frsp() { float testf2 = (float)testd2; ppc_dblresult64_d = (double)testf2; ppc_store_dfpresult(false); -} -void ppc_frspdot() { - ppc_grab_regsfpdb(false); - double testd2 = (double)ppc_result64_b; - float testf2 = (float)testd2; - ppc_dblresult64_d = (double)testf2; - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fres() { @@ -949,15 +719,9 @@ void ppc_fres() { testf2 = 1 / testf2; ppc_dblresult64_d = (double)testf2; ppc_store_dfpresult(false); -} -void ppc_fresdot() { - ppc_grab_regsfpdb(false); - float testf2 = (float)ppc_dblresult64_b; - testf2 = 1 / testf2; - ppc_dblresult64_d = (double)testf2; - ppc_store_dfpresult(false); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fctiw() { @@ -975,24 +739,9 @@ void ppc_fctiw() { } ppc_store_dfpresult(true); -} -void ppc_fctiwdot() { - ppc_grab_regsfpdb(false); - - switch (ppc_state.fpscr & 0x3) { - case 0: - ppc_result64_d = round_to_nearest(ppc_dblresult64_b); - case 1: - ppc_result64_d = round_to_zero(ppc_dblresult64_b); - case 2: - ppc_result64_d = round_to_pos_inf(ppc_dblresult64_b); - case 3: - ppc_result64_d = round_to_neg_inf(ppc_dblresult64_b); - } - - ppc_store_dfpresult(true); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } void ppc_fctiwz() { @@ -1000,14 +749,9 @@ void ppc_fctiwz() { ppc_result64_d = round_to_zero(ppc_dblresult64_b); ppc_store_result_regd(); -} -void ppc_fctiwzdot() { - ppc_grab_regsfpdb(false); - ppc_result64_d = round_to_zero(ppc_dblresult64_b); - - ppc_store_result_regd(); - ppc_changecrf1(); + if (rc_flag) + ppc_changecrf1(); } // Floating Point Store and Load diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index bcfd278..cd3bab1 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -227,29 +227,10 @@ void ppc_addis() { void ppc_add() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a + ppc_result_b; - ppc_store_result_regd(); -} - -void ppc_adddot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -// addo + addodot -void ppc_addo() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_addodot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_changecrf0(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_result_regd(); } @@ -257,31 +238,12 @@ void ppc_addc() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a + ppc_result_b; ppc_carry(ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} -void ppc_addcdot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_carry(ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_addco() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_carry(ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_addcodot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_a + ppc_result_b; - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_carry(ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -289,51 +251,18 @@ void ppc_adde() { ppc_grab_regsdab(); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; - if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_store_result_regd(); -} -void ppc_addedot() { - ppc_grab_regsdab(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) { ppc_state.spr[SPR::XER] |= 0x20000000UL; } else { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} -void ppc_addeo() { - ppc_grab_regsdab(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; - if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_addeodot() { - ppc_grab_regsdab(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; - if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -341,51 +270,18 @@ void ppc_addme() { ppc_grab_regsda(); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + xer_ca - 1; - if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_store_result_regd(); -} -void ppc_addmedot() { - ppc_grab_regsda(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + xer_ca - 1; if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) { ppc_state.spr[SPR::XER] |= 0x20000000UL; } else { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} -void ppc_addmeo() { - ppc_grab_regsda(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + xer_ca - 1; - ppc_setsoov(ppc_result_a, 0, ppc_result_d); - if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_a, 0, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_addmeodot() { - ppc_grab_regsda(); - uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + xer_ca - 1; - ppc_setsoov(ppc_result_a, 0, ppc_result_d); - ppc_changecrf0(ppc_result_d); - if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } ppc_store_result_regd(); } @@ -393,79 +289,30 @@ void ppc_addze() { ppc_grab_regsda(); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + grab_xer; - if (ppc_result_d < ppc_result_a) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_store_result_regd(); -} -void ppc_addzedot() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + grab_xer; if (ppc_result_d < ppc_result_a) { ppc_state.spr[SPR::XER] |= 0x20000000UL; } else { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + + if (oe_flag) + ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_addzeo() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + grab_xer; - ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d); - if (ppc_result_d < ppc_result_a) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_store_result_regd(); -} - -void ppc_addzeodot() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ppc_result_a + grab_xer; - ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d); - if (ppc_result_d < ppc_result_a) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } void ppc_subf() { ppc_grab_regsdab(); ppc_result_d = ppc_result_b - ppc_result_a; - ppc_store_result_regd(); -} -void ppc_subfdot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_subfo() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_subfodot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -473,31 +320,12 @@ void ppc_subfc() { ppc_grab_regsdab(); ppc_result_d = ppc_result_b - ppc_result_a; ppc_carry_sub(ppc_result_a, ppc_result_b); - ppc_store_result_regd(); -} -void ppc_subfcdot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_carry_sub(ppc_result_a, ppc_result_b); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_subfco() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry_sub(ppc_result_a, ppc_result_b); - ppc_store_result_regd(); -} - -void ppc_subfcodot() { - ppc_grab_regsdab(); - ppc_result_d = ppc_result_b - ppc_result_a; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry_sub(ppc_result_a, ppc_result_b); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -513,34 +341,12 @@ void ppc_subfe() { uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer; ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} -void ppc_subfedot() { - ppc_grab_regsdab(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer; - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_subfeo() { - ppc_grab_regsdab(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_subfeodot() { - ppc_grab_regsdab(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -549,34 +355,12 @@ void ppc_subfme() { uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ~ppc_result_a + grab_xer - 1; ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} + + if (oe_flag) + ppc_setsoov(0xFFFFFFFF, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_subfmedot() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + grab_xer - 1; - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_subfmeo() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + grab_xer - 1; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_subfmeodot() { - ppc_grab_regsda(); - uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); - ppc_result_d = ~ppc_result_a + grab_xer - 1; - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -584,31 +368,12 @@ void ppc_subfze() { ppc_grab_regsda(); ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000); ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} -void ppc_subfzedot() { - ppc_grab_regsda(); - ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) + ppc_setsoov(0, ppc_result_a, ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_subfzeo() { - ppc_grab_regsda(); - ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000); - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_subfzeodot() { - ppc_grab_regsda(); - ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000); - ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d); - ppc_carry(~ppc_result_a, ppc_result_d); - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -616,26 +381,20 @@ void ppc_subfzeodot() { void ppc_and() { ppc_grab_regssab(); ppc_result_a = ppc_result_d & ppc_result_b; - ppc_store_result_rega(); -} -void ppc_anddot() { - ppc_grab_regssab(); - ppc_result_a = ppc_result_d & ppc_result_b; - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } void ppc_andc() { ppc_grab_regssab(); ppc_result_a = ppc_result_d & ~(ppc_result_b); - ppc_store_result_rega(); -} -void ppc_andcdot() { - ppc_grab_regssab(); - ppc_result_a = ppc_result_d & ~(ppc_result_b); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -656,39 +415,30 @@ void ppc_andisdot() { void ppc_nand() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d & ppc_result_b); - ppc_store_result_rega(); -} -void ppc_nanddot() { - ppc_grab_regssab(); - ppc_result_a = ~(ppc_result_d & ppc_result_b); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } void ppc_or() { ppc_grab_regssab(); ppc_result_a = ppc_result_d | ppc_result_b; - ppc_store_result_rega(); -} -void ppc_ordot() { - ppc_grab_regssab(); - ppc_result_a = ppc_result_d | ppc_result_b; - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } void ppc_orc() { ppc_grab_regssab(); ppc_result_a = ppc_result_d | ~(ppc_result_b); - ppc_store_result_rega(); -} -void ppc_orcdot() { - ppc_grab_regssab(); - ppc_result_a = ppc_result_d | ~(ppc_result_b); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -707,39 +457,30 @@ void ppc_oris() { void ppc_eqv() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d ^ ppc_result_b); - ppc_store_result_rega(); -} -void ppc_eqvdot() { - ppc_grab_regssab(); - ppc_result_a = ~(ppc_result_d ^ ppc_result_b); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } void ppc_nor() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d | ppc_result_b); - ppc_store_result_rega(); -} -void ppc_nordot() { - ppc_grab_regssab(); - ppc_result_a = ~(ppc_result_d | ppc_result_b); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } void ppc_xor() { ppc_grab_regssab(); ppc_result_a = ppc_result_d ^ ppc_result_b; - ppc_store_result_rega(); -} -void ppc_xordot() { - ppc_grab_regssab(); - ppc_result_a = ppc_result_d ^ ppc_result_b; - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -758,34 +499,17 @@ void ppc_xoris() { void ppc_neg() { ppc_grab_regsda(); ppc_result_d = ~(ppc_result_a) + 1; - ppc_store_result_regd(); -} -void ppc_negdot() { - ppc_grab_regsda(); - ppc_result_d = ~(ppc_result_a) + 1; - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} + if (oe_flag) { + if (ppc_result_a == 0x80000000) + ppc_state.spr[SPR::XER] |= 0xC0000000; + else + ppc_state.spr[SPR::XER] &= 0xBFFFFFFF; + } + + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_nego() { - ppc_grab_regsda(); - ppc_result_d = ~(ppc_result_a) + 1; - if (ppc_result_a == 0x80000000) - ppc_state.spr[SPR::XER] |= 0xc0000000; - else - ppc_state.spr[SPR::XER] &= 0xBFFFFFFF; - ppc_store_result_regd(); -} - -void ppc_negodot() { - ppc_grab_regsda(); - ppc_result_d = ~(ppc_result_a) + 1; - if (ppc_result_a == 0x80000000) - ppc_state.spr[SPR::XER] |= 0xc0000000; - else - ppc_state.spr[SPR::XER] &= 0xBFFFFFFF; - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -806,27 +530,11 @@ void ppc_cntlzw() { } #endif ppc_result_a = lead; - ppc_store_result_rega(); -} -void ppc_cntlzwdot() { - ppc_grab_regssa(); - - uint32_t lead = 0; - uint32_t bit_check = ppc_result_d; - -#ifdef USE_GCC_BUILTINS - lead = __builtin_clz(bit_check); -#elif defined USE_VS_BUILTINS - lead = __lzcnt(bit_check); -#else - for (uint32_t mask = 0x80000000UL; mask; lead++, mask >>= 1) { - if (bit_check & mask) - break; + if (rc_flag) { + ppc_changecrf0(ppc_result_a); } -#endif - ppc_result_a = lead; - ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -834,14 +542,10 @@ void ppc_mulhwu() { ppc_grab_regsdab(); uint64_t product = (uint64_t)ppc_result_a * (uint64_t)ppc_result_b; ppc_result_d = (uint32_t)(product >> 32); - ppc_store_result_regd(); -} -void ppc_mulhwudot() { - ppc_grab_regsdab(); - uint64_t product = (uint64_t)ppc_result_a * (uint64_t)ppc_result_b; - ppc_result_d = (uint32_t)(product >> 32); - ppc_changecrf0(ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } @@ -849,54 +553,30 @@ void ppc_mulhw() { ppc_grab_regsdab(); int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; ppc_result_d = product >> 32; - ppc_store_result_regd(); -} -void ppc_mulhwdot() { - ppc_grab_regsdab(); - int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; - ppc_result_d = product >> 32; - ppc_changecrf0(ppc_result_d); + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } void ppc_mullw() { ppc_grab_regsdab(); int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; - ppc_result_d = (uint32_t)product; - ppc_store_result_regd(); -} -void ppc_mullwdot() { - ppc_grab_regsdab(); - int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; - ppc_result_d = (uint32_t)product; - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_mullwo() { - ppc_grab_regsdab(); - int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; - if (product != (int64_t)(int32_t)product) { - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; + if (oe_flag) { + if (product != (int64_t)(int32_t)product) { + ppc_state.spr[SPR::XER] |= 0xC0000000; + } else { + ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; + } } - ppc_result_d = (uint32_t)product; - ppc_store_result_regd(); -} -void ppc_mullwodot() { - ppc_grab_regsdab(); - int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; - if (product != (int64_t)(int32_t)product) { - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; - } - ppc_result_d = (uint32_t)product; - ppc_changecrf0(ppc_result_d); + ppc_result_d = (uint32_t)product; + + if (rc_flag) + ppc_changecrf0(ppc_result_d); + ppc_store_result_regd(); } @@ -907,68 +587,32 @@ void ppc_mulli() { ppc_store_result_regd(); } - void ppc_divw() { ppc_grab_regsdab(); if (!ppc_result_b) { /* handle the "anything / 0" case */ ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */ + + if (oe_flag) + ppc_state.spr[SPR::XER] |= 0xC0000000; + } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) { ppc_result_d = 0xFFFFFFFF; - } else { /* normal signed devision */ + + if (oe_flag) + 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) + ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; } - ppc_store_result_regd(); -} + if (rc_flag) + ppc_changecrf0(ppc_result_d); -void ppc_divwdot() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* handle the "anything / 0" case */ - ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */ - } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) { - ppc_result_d = 0xFFFFFFFF; - } else { /* normal signed devision */ - ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b; - } - - ppc_changecrf0(ppc_result_d); - ppc_store_result_regd(); -} - -void ppc_divwo() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* handle the "anything / 0" case */ - ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */ - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) { - ppc_result_d = 0xFFFFFFFF; - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { /* normal signed devision */ - ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b; - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; - } - - ppc_store_result_regd(); -} - -void ppc_divwodot() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* handle the "anything / 0" case */ - ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */ - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) { - ppc_result_d = 0xFFFFFFFF; - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { /* normal signed devision */ - ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b; - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; - } - - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -977,49 +621,22 @@ void ppc_divwu() { if (!ppc_result_b) { /* division by zero */ ppc_result_d = 0; + + if (oe_flag) + ppc_state.spr[SPR::XER] |= 0xC0000000; + + if (rc_flag) + ppc_state.cr |= 0x20000000; + } else { ppc_result_d = ppc_result_a / ppc_result_b; + + if (oe_flag) + ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; } - ppc_store_result_regd(); -} - -void ppc_divwudot() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* division by zero */ - ppc_result_d = 0; - ppc_state.cr |= 0x20000000; - } else { - ppc_result_d = ppc_result_a / ppc_result_b; + if (rc_flag) ppc_changecrf0(ppc_result_d); - } - ppc_store_result_regd(); -} -void ppc_divwuo() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* division by zero */ - ppc_result_d = 0; - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { - ppc_result_d = ppc_result_a / ppc_result_b; - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; - } - ppc_store_result_regd(); -} - -void ppc_divwuodot() { - ppc_grab_regsdab(); - - if (!ppc_result_b) { /* division by zero */ - ppc_result_d = 0; - ppc_state.spr[SPR::XER] |= 0xC0000000; - } else { - ppc_result_d = ppc_result_a / ppc_result_b; - ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL; - } - ppc_changecrf0(ppc_result_d); ppc_store_result_regd(); } @@ -1032,17 +649,10 @@ void ppc_slw() { } else { ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F); } - ppc_store_result_rega(); -} -void ppc_slwdot() { - ppc_grab_regssab(); - if (ppc_result_b & 0x20) { - ppc_result_a = 0; - } else { - ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F); - } - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -1053,17 +663,10 @@ void ppc_srw() { } else { ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F); } - ppc_store_result_rega(); -} -void ppc_srwdot() { - ppc_grab_regssab(); - if (ppc_result_b & 0x20) { - ppc_result_a = 0; - } else { - ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F); - } - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -1082,25 +685,10 @@ void ppc_sraw() { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } } - ppc_store_result_rega(); -} -void ppc_srawdot() { - ppc_grab_regssab(); - if (ppc_result_b & 0x20) { - ppc_result_a = (int32_t)ppc_result_d >> 31; - ppc_state.spr[SPR::XER] |= (ppc_result_a & 1) << 29; - } else { - uint32_t shift = ppc_result_b & 0x1F; - uint32_t mask = (1 << shift) - 1; - ppc_result_a = (int32_t)ppc_result_d >> shift; - if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - } - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -1114,20 +702,10 @@ void ppc_srawi() { } else { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - ppc_store_result_rega(); -} -void ppc_srawidot() { - ppc_grab_regssa(); - unsigned shift = (ppc_cur_instruction >> 11) & 0x1F; - uint32_t mask = (1 << shift) - 1; - ppc_result_a = (int32_t)ppc_result_d >> shift; - if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) { - ppc_state.spr[SPR::XER] |= 0x20000000UL; - } else { - ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; - } - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -1351,15 +929,10 @@ void ppc_extsb() { ppc_result_d = ppc_result_d & 0xFF; ppc_result_a = (ppc_result_d < 0x80) ? (ppc_result_d & 0x000000FF) : (0xFFFFFF00UL | (ppc_result_d & 0x000000FF)); - ppc_store_result_rega(); -} -void ppc_extsbdot() { - ppc_grab_regssa(); - ppc_result_d = ppc_result_d & 0xFF; - ppc_result_a = (ppc_result_d < 0x80) ? (ppc_result_d & 0x000000FF) - : (0xFFFFFF00UL | (ppc_result_d & 0x000000FF)); - ppc_changecrf0(ppc_result_a); + if (rc_flag) + ppc_changecrf0(ppc_result_a); + ppc_store_result_rega(); } @@ -1368,15 +941,9 @@ void ppc_extsh() { ppc_result_d = ppc_result_d & 0xFFFF; ppc_result_a = (ppc_result_d < 0x8000) ? (ppc_result_d & 0x0000FFFF) : (0xFFFF0000UL | (ppc_result_d & 0x0000FFFF)); - ppc_store_result_rega(); -} + if (rc_flag) + ppc_changecrf0(ppc_result_a); -void ppc_extshdot() { - ppc_grab_regssa(); - ppc_result_d = ppc_result_d & 0xFFFF; - ppc_result_a = (ppc_result_d < 0x8000) ? (ppc_result_d & 0x0000FFFF) - : (0xFFFF0000UL | (ppc_result_d & 0x0000FFFF)); - ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } @@ -1895,14 +1462,18 @@ void ppc_stwx() { void ppc_stwcx() { // PLACEHOLDER CODE FOR STWCX - We need to check for reserve memory - ppc_grab_regssab(); - ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); - if (ppc_state.reserve) { - mem_write_dword(ppc_effective_address, ppc_result_d); - ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000; - ppc_state.reserve = false; + if (rc_flag == 0) { + ppc_illegalsubop31(); } else { - ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0; + ppc_grab_regssab(); + ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); + if (ppc_state.reserve) { + mem_write_dword(ppc_effective_address, ppc_result_d); + ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000; + ppc_state.reserve = false; + } else { + ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0; + } } } diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp index 1e1a043..0f3b512 100644 --- a/cpu/ppc/test/ppctests.cpp +++ b/cpu/ppc/test/ppctests.cpp @@ -142,6 +142,8 @@ static void read_test_data() { } int main() { + initialize_ppc_opcode_tables(); //kludge + cout << "Running DingusPPC emulator tests..." << endl << endl; ntested = 0; diff --git a/main.cpp b/main.cpp index 7a66297..f2527ac 100644 --- a/main.cpp +++ b/main.cpp @@ -121,6 +121,8 @@ int main(int argc, char** argv) { loguru::init(argc, argv); } + initialize_ppc_opcode_tables(); //Temp location for initializing opcode tables + if (*machine_opt) { LOG_F(INFO, "Machine option was passed in: %s", machine_str.c_str()); } else { From 1fe9ffe3e5a1903b91de31c6d3a5b480757daf78 Mon Sep 17 00:00:00 2001 From: dingusdev Date: Sat, 17 Oct 2020 21:46:38 -0700 Subject: [PATCH 07/20] Further refactoring to clean up the interpreter --- cpu/ppc/poweropcodes.cpp | 56 +++---- cpu/ppc/ppcemu.h | 8 +- cpu/ppc/ppcexec.cpp | 41 ++--- cpu/ppc/ppcfpopcodes.cpp | 116 +++++++------- cpu/ppc/ppcgekkoopcodes.cpp | 46 ------ cpu/ppc/ppcopcodes.cpp | 282 ++++++++++++++++----------------- execution/interpreter_loop.cpp | 2 +- 7 files changed, 251 insertions(+), 300 deletions(-) delete mode 100644 cpu/ppc/ppcgekkoopcodes.cpp diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index 44b2135..6e2b3c1 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -42,7 +42,7 @@ inline void power_setsoov(uint32_t a, uint32_t b, uint32_t d) { } } -void power_abs() { +void dppc_interpreter::power_abs() { ppc_grab_regsda(); if (ppc_result_a == 0x80000000) { ppc_result_d = ppc_result_a; @@ -59,7 +59,7 @@ void power_abs() { ppc_store_result_regd(); } -void power_clcs() { +void dppc_interpreter::power_clcs() { ppc_grab_regsda(); switch (reg_a) { case 12: @@ -80,7 +80,7 @@ void power_clcs() { ppc_store_result_regd(); } -void power_div() { +void dppc_interpreter::power_div() { ppc_grab_regsdab(); ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b; ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b; @@ -93,7 +93,7 @@ void power_div() { ppc_store_result_regd(); } -void power_divs() { +void dppc_interpreter::power_divs() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a / ppc_result_b; ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b); @@ -106,7 +106,7 @@ void power_divs() { ppc_store_result_regd(); } -void power_doz() { +void dppc_interpreter::power_doz() { ppc_grab_regsdab(); if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) { ppc_result_d = 0; @@ -120,7 +120,7 @@ void power_doz() { ppc_store_result_rega(); } -void power_dozi() { +void dppc_interpreter::power_dozi() { ppc_grab_regsdab(); if (((int32_t)ppc_result_a) > simm) { ppc_result_d = 0; @@ -130,7 +130,7 @@ void power_dozi() { ppc_store_result_rega(); } -void power_lscbx() { +void dppc_interpreter::power_lscbx() { ppc_grab_regsdab(); uint32_t bytes_copied = 0; bool match_found = false; @@ -191,7 +191,7 @@ void power_lscbx() { ppc_store_result_regd(); } -void power_maskg() { +void dppc_interpreter::power_maskg() { ppc_grab_regssab(); uint32_t mask_start = ppc_result_d & 31; uint32_t mask_end = ppc_result_b & 31; @@ -218,7 +218,7 @@ void power_maskg() { ppc_store_result_rega(); } -void power_maskir() { +void dppc_interpreter::power_maskir() { ppc_grab_regssab(); uint32_t mask_insert = ppc_result_a; uint32_t insert_rot = 0x80000000; @@ -238,7 +238,7 @@ void power_maskir() { ppc_store_result_rega(); } -void power_mul() { +void dppc_interpreter::power_mul() { ppc_grab_regsdab(); uint64_t product; @@ -252,7 +252,7 @@ void power_mul() { ppc_store_result_regd(); } -void power_nabs() { +void dppc_interpreter::power_nabs() { ppc_grab_regsda(); ppc_result_d = (0x80000000 | ppc_result_a); @@ -262,7 +262,7 @@ void power_nabs() { ppc_store_result_regd(); } -void power_rlmi() { +void dppc_interpreter::power_rlmi() { ppc_grab_regssab(); unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; unsigned rot_me = (ppc_cur_instruction >> 1) & 31; @@ -287,7 +287,7 @@ void power_rlmi() { ppc_store_result_rega(); } -void power_rrib() { +void dppc_interpreter::power_rrib() { ppc_grab_regssab(); if (ppc_result_d & 0x80000000) { @@ -302,7 +302,7 @@ void power_rrib() { ppc_store_result_rega(); } -void power_sle() { +void dppc_interpreter::power_sle() { ppc_grab_regssa(); uint32_t insert_mask = 0; uint32_t rot_amt = ppc_result_b & 31; @@ -319,7 +319,7 @@ void power_sle() { ppc_store_result_rega(); } -void power_sleq() { +void dppc_interpreter::power_sleq() { ppc_grab_regssa(); uint32_t insert_mask = 0; uint32_t rot_amt = ppc_result_b & 31; @@ -345,7 +345,7 @@ void power_sleq() { ppc_store_result_rega(); } -void power_sliq() { +void dppc_interpreter::power_sliq() { ppc_grab_regssa(); uint32_t insert_mask = 0; unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -371,7 +371,7 @@ void power_sliq() { ppc_store_result_rega(); } -void power_slliq() { +void dppc_interpreter::power_slliq() { ppc_grab_regssa(); uint32_t insert_mask = 0; unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -397,23 +397,23 @@ void power_slliq() { ppc_store_result_rega(); } -void power_sllq() { +void dppc_interpreter::power_sllq() { LOG_F(WARNING, "OOPS! Placeholder for sllq!!! \n"); } -void power_slq() { +void dppc_interpreter::power_slq() { LOG_F(WARNING, "OOPS! Placeholder for slq!!! \n"); } -void power_sraiq() { +void dppc_interpreter::power_sraiq() { LOG_F(WARNING, "OOPS! Placeholder for sraiq!!! \n"); } -void power_sraq() { +void dppc_interpreter::power_sraq() { LOG_F(WARNING, "OOPS! Placeholder for sraq!!! \n"); } -void power_sre() { +void dppc_interpreter::power_sre() { ppc_grab_regssa(); uint32_t insert_mask = 0; uint32_t rot_amt = ppc_result_b & 31; @@ -428,11 +428,11 @@ void power_sre() { ppc_store_result_rega(); } -void power_srea() { +void dppc_interpreter::power_srea() { LOG_F(WARNING, "OOPS! Placeholder for srea!!! \n"); } -void power_sreq() { +void dppc_interpreter::power_sreq() { ppc_grab_regssa(); uint32_t insert_mask = 0; unsigned rot_sh = ppc_result_b & 31; @@ -458,7 +458,7 @@ void power_sreq() { ppc_store_result_rega(); } -void power_sriq() { +void dppc_interpreter::power_sriq() { ppc_grab_regssa(); uint32_t insert_mask = 0; unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; @@ -484,14 +484,14 @@ void power_sriq() { ppc_store_result_rega(); } -void power_srliq() { +void dppc_interpreter::power_srliq() { LOG_F(WARNING, "OOPS! Placeholder for slriq!!! \n"); } -void power_srlq() { +void dppc_interpreter::power_srlq() { LOG_F(WARNING, "OOPS! Placeholder for slrq!!! \n"); } -void power_srq() { +void dppc_interpreter::power_srq() { LOG_F(WARNING, "OOPS! Placeholder for srq!!! \n"); } \ No newline at end of file diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 64de5bd..628e164 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -303,6 +303,7 @@ void ppc_fp_changecrf1(); extern MemCtrlBase* mem_ctrl_instance; // The functions used by the PowerPC processor +namespace dppc_interpreter { extern void ppc_bcctr(); extern void ppc_bcctrl(); extern void ppc_bclr(); @@ -541,12 +542,7 @@ extern void power_sriq(); extern void power_srliq(); extern void power_srlq(); extern void power_srq(); - -// Gekko instructions -extern void ppc_psq_l(); -extern void ppc_psq_lu(); -extern void ppc_psq_st(); -extern void ppc_psq_stu(); +} // namespace dppc_interpreter // AltiVec instructions diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 582d202..807bc01 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -35,6 +35,7 @@ along with this program. If not, see . #define NEW_TBR_UPDATE_ALGO using namespace std; +using namespace dppc_interpreter; MemCtrlBase* mem_ctrl_instance = 0; @@ -72,17 +73,17 @@ uint8_t tbr_factor; /* cycles_count to TBR freq ratio in 2^x units */ /** Primary opcode (bits 0...5) lookup table. */ static PPCOpcode OpcodeGrabber[] = { - ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_opcode4, 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_psq_l, ppc_psq_lu, ppc_illegalop, ppc_illegalop, - ppc_psq_st, ppc_psq_stu, ppc_illegalop, ppc_opcode63}; + ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_opcode4, 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_illegalop, + ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode63}; /** Lookup tables for branch instructions. */ static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla}; @@ -577,29 +578,29 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[978] = ppc_tlbld; SubOpcode31Grabber[1010] = ppc_tlbli; - SubOpcode63Grabber[18] = ppc_fdivs; - SubOpcode63Grabber[20] = ppc_fsubs; - SubOpcode63Grabber[22] = ppc_fsqrts; - SubOpcode63Grabber[24] = ppc_fres; + SubOpcode59Grabber[18] = ppc_fdivs; + SubOpcode59Grabber[20] = ppc_fsubs; + SubOpcode59Grabber[22] = ppc_fsqrts; + SubOpcode59Grabber[24] = ppc_fres; for (int i = 25; i < 1024; i += 32) { - SubOpcode63Grabber[i] = ppc_fmults; + SubOpcode59Grabber[i] = ppc_fmults; } for (int i = 28; i < 1024; i += 32) { - SubOpcode63Grabber[i] = ppc_fmsubs; + SubOpcode59Grabber[i] = ppc_fmsubs; } for (int i = 29; i < 1024; i += 32) { - SubOpcode63Grabber[i] = ppc_fmadds; + SubOpcode59Grabber[i] = ppc_fmadds; } for (int i = 30; i < 1024; i += 32) { - SubOpcode63Grabber[i] = ppc_fnmsubs; + SubOpcode59Grabber[i] = ppc_fnmsubs; } for (int i = 31; i < 1024; i += 32) { - SubOpcode63Grabber[i] = ppc_fnmadds; + SubOpcode59Grabber[i] = ppc_fnmadds; } SubOpcode63Grabber[0] = ppc_fcmpu; diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index b0bfa3b..b3eb088 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -371,7 +371,7 @@ void ppc_changecrf1() { } // Floating Point Arithmetic -void ppc_fadd() { +void dppc_interpreter::ppc_fadd() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) { @@ -383,7 +383,7 @@ void ppc_fadd() { ppc_changecrf1(); } -void ppc_fsub() { +void dppc_interpreter::ppc_fsub() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) { @@ -395,7 +395,7 @@ void ppc_fsub() { ppc_changecrf1(); } -void ppc_fdiv() { +void dppc_interpreter::ppc_fdiv() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) { @@ -407,7 +407,7 @@ void ppc_fdiv() { ppc_changecrf1(); } -void ppc_fmult() { +void dppc_interpreter::ppc_fmult() { ppc_grab_regsfpdac(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 50)) { @@ -419,7 +419,7 @@ void ppc_fmult() { ppc_changecrf1(); } -void ppc_fmadd() { +void dppc_interpreter::ppc_fmadd() { ppc_grab_regsfpdabc(false); if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { @@ -435,7 +435,7 @@ void ppc_fmadd() { ppc_changecrf1(); } -void ppc_fmsub() { +void dppc_interpreter::ppc_fmsub() { ppc_grab_regsfpdabc(false); if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { @@ -451,7 +451,7 @@ void ppc_fmsub() { ppc_changecrf1(); } -void ppc_fnmadd() { +void dppc_interpreter::ppc_fnmadd() { ppc_grab_regsfpdabc(false); if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { @@ -468,7 +468,7 @@ void ppc_fnmadd() { ppc_changecrf1(); } -void ppc_fnmsub() { +void dppc_interpreter::ppc_fnmsub() { ppc_grab_regsfpdabc(false); if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) { @@ -485,7 +485,7 @@ void ppc_fnmsub() { ppc_changecrf1(); } -void ppc_fadds() { +void dppc_interpreter::ppc_fadds() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) { @@ -498,7 +498,7 @@ void ppc_fadds() { ppc_changecrf1(); } -void ppc_fsubs() { +void dppc_interpreter::ppc_fsubs() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) { @@ -511,7 +511,7 @@ void ppc_fsubs() { ppc_changecrf1(); } -void ppc_fmults() { +void dppc_interpreter::ppc_fmults() { ppc_grab_regsfpdac(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 50)) { @@ -524,7 +524,7 @@ void ppc_fmults() { ppc_changecrf1(); } -void ppc_fdivs() { +void dppc_interpreter::ppc_fdivs() { ppc_grab_regsfpdab(false); if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) { @@ -537,7 +537,7 @@ void ppc_fdivs() { ppc_changecrf1(); } -void ppc_fmadds() { +void dppc_interpreter::ppc_fmadds() { ppc_grab_regsfpdabc(false); float intermediate; @@ -556,7 +556,7 @@ void ppc_fmadds() { ppc_changecrf1(); } -void ppc_fmsubs() { +void dppc_interpreter::ppc_fmsubs() { ppc_grab_regsfpdabc(false); float intermediate; @@ -575,7 +575,7 @@ void ppc_fmsubs() { ppc_changecrf1(); } -void ppc_fnmadds() { +void dppc_interpreter::ppc_fnmadds() { ppc_grab_regsfpdabc(false); float intermediate; @@ -596,7 +596,7 @@ void ppc_fnmadds() { ppc_changecrf1(); } -void ppc_fnmsubs() { +void dppc_interpreter::ppc_fnmsubs() { ppc_grab_regsfpdabc(false); float intermediate; @@ -617,7 +617,7 @@ void ppc_fnmsubs() { ppc_changecrf1(); } -void ppc_fabs() { +void dppc_interpreter::ppc_fabs() { ppc_grab_regsfpdb(false); ppc_dblresult64_d = abs(ppc_dblresult64_b); @@ -628,7 +628,7 @@ void ppc_fabs() { ppc_changecrf1(); } -void ppc_fnabs() { +void dppc_interpreter::ppc_fnabs() { ppc_grab_regsfpdb(false); ppc_dblresult64_d = abs(ppc_dblresult64_b); @@ -640,7 +640,7 @@ void ppc_fnabs() { ppc_changecrf1(); } -void ppc_fneg() { +void dppc_interpreter::ppc_fneg() { ppc_grab_regsfpdb(false); ppc_dblresult64_d = -ppc_dblresult64_d; @@ -651,7 +651,7 @@ void ppc_fneg() { ppc_changecrf1(); } -void ppc_fsel() { +void dppc_interpreter::ppc_fsel() { ppc_grab_regsfpdabc(false); if (ppc_dblresult64_a >= 0.0) { @@ -666,7 +666,7 @@ void ppc_fsel() { ppc_changecrf1(); } -void ppc_fsqrt() { +void dppc_interpreter::ppc_fsqrt() { ppc_grab_regsfpdb(false); ppc_dblresult64_d = std::sqrt(ppc_dblresult64_b); ppc_store_dfpresult(false); @@ -675,7 +675,7 @@ void ppc_fsqrt() { ppc_changecrf1(); } -void ppc_fsqrts() { +void dppc_interpreter::ppc_fsqrts() { ppc_grab_regsfpdb(true); uint32_t test = (uint32_t)ppc_result64_b; test += 127 << 23; @@ -688,7 +688,7 @@ void ppc_fsqrts() { ppc_changecrf1(); } -void ppc_frsqrte() { +void dppc_interpreter::ppc_frsqrte() { ppc_grab_regsfpdb(false); double testd2 = (double)ppc_result64_b; for (int i = 0; i < 10; i++) { @@ -702,7 +702,7 @@ void ppc_frsqrte() { ppc_changecrf1(); } -void ppc_frsp() { +void dppc_interpreter::ppc_frsp() { ppc_grab_regsfpdb(false); double testd2 = (double)ppc_result64_b; float testf2 = (float)testd2; @@ -713,7 +713,7 @@ void ppc_frsp() { ppc_changecrf1(); } -void ppc_fres() { +void dppc_interpreter::ppc_fres() { ppc_grab_regsfpdb(false); float testf2 = (float)ppc_dblresult64_b; testf2 = 1 / testf2; @@ -724,7 +724,7 @@ void ppc_fres() { ppc_changecrf1(); } -void ppc_fctiw() { +void dppc_interpreter::ppc_fctiw() { ppc_grab_regsfpdb(false); switch (ppc_state.fpscr & 0x3) { @@ -744,7 +744,7 @@ void ppc_fctiw() { ppc_changecrf1(); } -void ppc_fctiwz() { +void dppc_interpreter::ppc_fctiwz() { ppc_grab_regsfpdb(false); ppc_result64_d = round_to_zero(ppc_dblresult64_b); @@ -756,7 +756,7 @@ void ppc_fctiwz() { // Floating Point Store and Load -void ppc_lfs() { +void dppc_interpreter::ppc_lfs() { ppc_grab_regsfpdia(true); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -765,7 +765,7 @@ void ppc_lfs() { } -void ppc_lfsu() { +void dppc_interpreter::ppc_lfsu() { ppc_grab_regsfpdia(true); if (reg_a == 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -779,14 +779,14 @@ void ppc_lfsu() { } } -void ppc_lfsx() { +void dppc_interpreter::ppc_lfsx() { ppc_grab_regsfpdiab(true); ppc_effective_address = (reg_a == 0) ? ppc_result_b : ppc_result_a + ppc_result_b; ppc_result64_d = mem_grab_dword(ppc_effective_address); ppc_store_dfpresult(true); } -void ppc_lfsux() { +void dppc_interpreter::ppc_lfsux() { ppc_grab_regsfpdiab(true); if (reg_a == 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -799,7 +799,7 @@ void ppc_lfsux() { } } -void ppc_lfd() { +void dppc_interpreter::ppc_lfd() { ppc_grab_regsfpdia(true); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -807,7 +807,7 @@ void ppc_lfd() { ppc_store_dfpresult(true); } -void ppc_lfdu() { +void dppc_interpreter::ppc_lfdu() { ppc_grab_regsfpdia(true); if (reg_a == 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -821,14 +821,14 @@ void ppc_lfdu() { } } -void ppc_lfdx() { +void dppc_interpreter::ppc_lfdx() { ppc_grab_regsfpdia(true); ppc_effective_address += (reg_a > 0) ? ppc_result_a + ppc_result_b : ppc_result_b; ppc_result64_d = mem_grab_qword(ppc_effective_address); ppc_store_dfpresult(true); } -void ppc_lfdux() { +void dppc_interpreter::ppc_lfdux() { ppc_grab_regsfpdiab(true); if (reg_a == 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -841,14 +841,14 @@ void ppc_lfdux() { } } -void ppc_stfs() { +void dppc_interpreter::ppc_stfs() { ppc_grab_regsfpsia(true); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; mem_write_dword(ppc_effective_address, uint32_t(ppc_state.fpr[reg_s].int64_r)); } -void ppc_stfsu() { +void dppc_interpreter::ppc_stfsu() { ppc_grab_regsfpsia(true); if (reg_a == 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -861,13 +861,13 @@ void ppc_stfsu() { } } -void ppc_stfsx() { +void dppc_interpreter::ppc_stfsx() { ppc_grab_regsfpsiab(true); ppc_effective_address = (reg_a == 0) ? ppc_result_b : ppc_result_a + ppc_result_b; mem_write_dword(ppc_effective_address, uint32_t(ppc_state.fpr[reg_s].int64_r)); } -void ppc_stfsux() { +void dppc_interpreter::ppc_stfsux() { ppc_grab_regsfpsiab(true); if (reg_a == 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -879,14 +879,14 @@ void ppc_stfsux() { } } -void ppc_stfd() { +void dppc_interpreter::ppc_stfd() { ppc_grab_regsfpsia(true); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; mem_write_qword(ppc_effective_address, ppc_state.fpr[reg_s].int64_r); } -void ppc_stfdu() { +void dppc_interpreter::ppc_stfdu() { ppc_grab_regsfpsia(true); if (reg_a == 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -899,13 +899,13 @@ void ppc_stfdu() { } } -void ppc_stfdx() { +void dppc_interpreter::ppc_stfdx() { ppc_grab_regsfpsiab(true); ppc_effective_address = (reg_a == 0) ? ppc_result_b : ppc_result_a + ppc_result_b; mem_write_qword(ppc_effective_address, ppc_state.fpr[reg_s].int64_r); } -void ppc_stfdux() { +void dppc_interpreter::ppc_stfdux() { ppc_grab_regsfpsiab(true); if (reg_a == 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -917,7 +917,7 @@ void ppc_stfdux() { } } -void ppc_stfiwx() { +void dppc_interpreter::ppc_stfiwx() { ppc_grab_regsfpsiab(true); ppc_effective_address = (reg_a == 0) ? ppc_result_b : ppc_result_a + ppc_result_b; mem_write_dword(ppc_effective_address, (uint32_t)(ppc_state.fpr[reg_s].int64_r)); @@ -925,14 +925,14 @@ void ppc_stfiwx() { // Floating Point Register Transfer -void ppc_fmr() { +void dppc_interpreter::ppc_fmr() { ppc_grab_regsfpdb(true); ppc_state.fpr[reg_d] = ppc_state.fpr[reg_b]; ppc_store_dfpresult(true); } -void ppc_mffs() { +void dppc_interpreter::ppc_mffs() { ppc_grab_regsda(); uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000; uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF; @@ -940,7 +940,7 @@ void ppc_mffs() { fp_save_uint64(fpstore1); } -void ppc_mffsdot() { +void dppc_interpreter::ppc_mffsdot() { ppc_grab_regsda(); uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000; uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF; @@ -949,7 +949,7 @@ void ppc_mffsdot() { ppc_fp_changecrf1(); } -void ppc_mtfsf() { +void dppc_interpreter::ppc_mtfsf() { reg_b = (ppc_cur_instruction >> 11) & 31; uint32_t fm_mask = (ppc_cur_instruction >> 17) & 255; crm += ((fm_mask & 1) == 1) ? 0xF0000000 : 0x00000000; @@ -964,7 +964,7 @@ void ppc_mtfsf() { ppc_state.fpscr = (quickfprval & crm) | (quickfprval & ~(crm)); } -void ppc_mtfsfdot() { +void dppc_interpreter::ppc_mtfsfdot() { reg_b = (ppc_cur_instruction >> 11) & 31; uint32_t fm_mask = (ppc_cur_instruction >> 17) & 255; crm += ((fm_mask & 1) == 1) ? 0xF0000000 : 0x00000000; @@ -980,7 +980,7 @@ void ppc_mtfsfdot() { ppc_fp_changecrf1(); } -void ppc_mtfsfi() { +void dppc_interpreter::ppc_mtfsfi() { ppc_result_b = (ppc_cur_instruction >> 11) & 15; crf_d = (ppc_cur_instruction >> 23) & 7; crf_d = crf_d << 2; @@ -988,7 +988,7 @@ void ppc_mtfsfi() { ((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d); } -void ppc_mtfsfidot() { +void dppc_interpreter::ppc_mtfsfidot() { ppc_result_b = (ppc_cur_instruction >> 11) & 15; crf_d = (ppc_cur_instruction >> 23) & 7; crf_d = crf_d << 2; @@ -997,14 +997,14 @@ void ppc_mtfsfidot() { ppc_fp_changecrf1(); } -void ppc_mtfsb0() { +void dppc_interpreter::ppc_mtfsb0() { crf_d = (ppc_cur_instruction >> 21) & 0x31; if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr &= ~(1 << (31 - crf_d)); } } -void ppc_mtfsb0dot() { +void dppc_interpreter::ppc_mtfsb0dot() { crf_d = (ppc_cur_instruction >> 21) & 0x31; if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr &= ~(1 << crf_d); @@ -1012,14 +1012,14 @@ void ppc_mtfsb0dot() { ppc_fp_changecrf1(); } -void ppc_mtfsb1() { +void dppc_interpreter::ppc_mtfsb1() { crf_d = (ppc_cur_instruction >> 21) & 0x31; if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr |= (1 << crf_d); } } -void ppc_mtfsb1dot() { +void dppc_interpreter::ppc_mtfsb1dot() { crf_d = ~(ppc_cur_instruction >> 21) & 0x31; if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr |= (1 << crf_d); @@ -1027,7 +1027,7 @@ void ppc_mtfsb1dot() { ppc_fp_changecrf1(); } -void ppc_mcrfs() { +void dppc_interpreter::ppc_mcrfs() { crf_d = (ppc_cur_instruction >> 23) & 7; crf_d = crf_d << 2; crf_s = (ppc_cur_instruction >> 18) & 7; @@ -1038,7 +1038,7 @@ void ppc_mcrfs() { // Floating Point Comparisons -void ppc_fcmpo() { +void dppc_interpreter::ppc_fcmpo() { ppc_grab_regsfpsab(true); crf_d = (ppc_cur_instruction >> 23) & 7; @@ -1072,7 +1072,7 @@ void ppc_fcmpo() { } } -void ppc_fcmpu() { +void dppc_interpreter::ppc_fcmpu() { ppc_grab_regsfpsab(true); crf_d = (ppc_cur_instruction >> 23) & 7; diff --git a/cpu/ppc/ppcgekkoopcodes.cpp b/cpu/ppc/ppcgekkoopcodes.cpp deleted file mode 100644 index a5d9e1e..0000000 --- a/cpu/ppc/ppcgekkoopcodes.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -DingusPPC - The Experimental PowerPC Macintosh emulator -Copyright (C) 2018-20 divingkatae and maximum - (theweirdo) spatium - -(Contact divingkatae#1017 or powermax#2286 on Discord for more info) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -// The uniquely Gekko opcodes for the processor - ppcgekkoopcodes.cpp - -#include "ppcemu.h" -#include -#include - -void ppc_psq_l() { - printf("Hello. There's no GameCube emulation...yet. Goodbye."); - exit(0); -} - -void ppc_psq_lu() { - printf("Hello. There's no GameCube emulation...yet. Goodbye."); - exit(0); -} - -void ppc_psq_st() { - printf("Hello. There's no GameCube emulation...yet. Goodbye."); - exit(0); -} - -void ppc_psq_stu() { - printf("Hello. There's no GameCube emulation...yet. Goodbye."); - exit(0); -} diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index cd3bab1..e1cf3b4 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -197,20 +197,20 @@ comparisons needed. This means loads of functions, but less CPU cycles needed to function (theoretically). **/ -void ppc_addi() { +void dppc_interpreter::ppc_addi() { ppc_grab_regsdasimm(); ppc_result_d = (reg_a == 0) ? simm : (ppc_result_a + simm); ppc_store_result_regd(); } -void ppc_addic() { +void dppc_interpreter::ppc_addic() { ppc_grab_regsdasimm(); ppc_result_d = (ppc_result_a + simm); ppc_carry(ppc_result_a, ppc_result_d); ppc_store_result_regd(); } -void ppc_addicdot() { +void dppc_interpreter::ppc_addicdot() { ppc_grab_regsdasimm(); ppc_result_d = (ppc_result_a + simm); ppc_changecrf0(ppc_result_d); @@ -218,13 +218,13 @@ void ppc_addicdot() { ppc_store_result_regd(); } -void ppc_addis() { +void dppc_interpreter::ppc_addis() { ppc_grab_regsdasimm(); ppc_result_d = (reg_a == 0) ? (simm << 16) : (ppc_result_a + (simm << 16)); ppc_store_result_regd(); } -void ppc_add() { +void dppc_interpreter::ppc_add() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a + ppc_result_b; if (oe_flag) @@ -234,7 +234,7 @@ void ppc_add() { ppc_store_result_regd(); } -void ppc_addc() { +void dppc_interpreter::ppc_addc() { ppc_grab_regsdab(); ppc_result_d = ppc_result_a + ppc_result_b; ppc_carry(ppc_result_a, ppc_result_d); @@ -247,7 +247,7 @@ void ppc_addc() { ppc_store_result_regd(); } -void ppc_adde() { +void dppc_interpreter::ppc_adde() { ppc_grab_regsdab(); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; @@ -266,7 +266,7 @@ void ppc_adde() { ppc_store_result_regd(); } -void ppc_addme() { +void dppc_interpreter::ppc_addme() { ppc_grab_regsda(); uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + xer_ca - 1; @@ -285,7 +285,7 @@ void ppc_addme() { ppc_store_result_regd(); } -void ppc_addze() { +void dppc_interpreter::ppc_addze() { ppc_grab_regsda(); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ppc_result_a + grab_xer; @@ -304,7 +304,7 @@ void ppc_addze() { ppc_store_result_regd(); } -void ppc_subf() { +void dppc_interpreter::ppc_subf() { ppc_grab_regsdab(); ppc_result_d = ppc_result_b - ppc_result_a; @@ -316,7 +316,7 @@ void ppc_subf() { ppc_store_result_regd(); } -void ppc_subfc() { +void dppc_interpreter::ppc_subfc() { ppc_grab_regsdab(); ppc_result_d = ppc_result_b - ppc_result_a; ppc_carry_sub(ppc_result_a, ppc_result_b); @@ -329,14 +329,14 @@ void ppc_subfc() { ppc_store_result_regd(); } -void ppc_subfic() { +void dppc_interpreter::ppc_subfic() { ppc_grab_regsdasimm(); ppc_result_d = simm - ppc_result_a; ppc_carry(~ppc_result_a, ppc_result_d); ppc_store_result_regd(); } -void ppc_subfe() { +void dppc_interpreter::ppc_subfe() { ppc_grab_regsdab(); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer; @@ -350,7 +350,7 @@ void ppc_subfe() { ppc_store_result_regd(); } -void ppc_subfme() { +void dppc_interpreter::ppc_subfme() { ppc_grab_regsda(); uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ~ppc_result_a + grab_xer - 1; @@ -364,7 +364,7 @@ void ppc_subfme() { ppc_store_result_regd(); } -void ppc_subfze() { +void dppc_interpreter::ppc_subfze() { ppc_grab_regsda(); ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000); ppc_carry(~ppc_result_a, ppc_result_d); @@ -378,7 +378,7 @@ void ppc_subfze() { } -void ppc_and() { +void dppc_interpreter::ppc_and() { ppc_grab_regssab(); ppc_result_a = ppc_result_d & ppc_result_b; @@ -388,7 +388,7 @@ void ppc_and() { ppc_store_result_rega(); } -void ppc_andc() { +void dppc_interpreter::ppc_andc() { ppc_grab_regssab(); ppc_result_a = ppc_result_d & ~(ppc_result_b); @@ -398,21 +398,21 @@ void ppc_andc() { ppc_store_result_rega(); } -void ppc_andidot() { +void dppc_interpreter::ppc_andidot() { ppc_grab_regssauimm(); ppc_result_a = ppc_result_d & uimm; ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } -void ppc_andisdot() { +void dppc_interpreter::ppc_andisdot() { ppc_grab_regssauimm(); ppc_result_a = ppc_result_d & (uimm << 16); ppc_changecrf0(ppc_result_a); ppc_store_result_rega(); } -void ppc_nand() { +void dppc_interpreter::ppc_nand() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d & ppc_result_b); @@ -422,7 +422,7 @@ void ppc_nand() { ppc_store_result_rega(); } -void ppc_or() { +void dppc_interpreter::ppc_or() { ppc_grab_regssab(); ppc_result_a = ppc_result_d | ppc_result_b; @@ -432,7 +432,7 @@ void ppc_or() { ppc_store_result_rega(); } -void ppc_orc() { +void dppc_interpreter::ppc_orc() { ppc_grab_regssab(); ppc_result_a = ppc_result_d | ~(ppc_result_b); @@ -442,19 +442,19 @@ void ppc_orc() { ppc_store_result_rega(); } -void ppc_ori() { +void dppc_interpreter::ppc_ori() { ppc_grab_regssauimm(); ppc_result_a = ppc_result_d | uimm; ppc_store_result_rega(); } -void ppc_oris() { +void dppc_interpreter::ppc_oris() { ppc_grab_regssauimm(); ppc_result_a = (uimm << 16) | ppc_result_d; ppc_store_result_rega(); } -void ppc_eqv() { +void dppc_interpreter::ppc_eqv() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d ^ ppc_result_b); @@ -464,7 +464,7 @@ void ppc_eqv() { ppc_store_result_rega(); } -void ppc_nor() { +void dppc_interpreter::ppc_nor() { ppc_grab_regssab(); ppc_result_a = ~(ppc_result_d | ppc_result_b); @@ -474,7 +474,7 @@ void ppc_nor() { ppc_store_result_rega(); } -void ppc_xor() { +void dppc_interpreter::ppc_xor() { ppc_grab_regssab(); ppc_result_a = ppc_result_d ^ ppc_result_b; @@ -484,19 +484,19 @@ void ppc_xor() { ppc_store_result_rega(); } -void ppc_xori() { +void dppc_interpreter::ppc_xori() { ppc_grab_regssauimm(); ppc_result_a = ppc_result_d ^ uimm; ppc_store_result_rega(); } -void ppc_xoris() { +void dppc_interpreter::ppc_xoris() { ppc_grab_regssauimm(); ppc_result_a = ppc_result_d ^ (uimm << 16); ppc_store_result_rega(); } -void ppc_neg() { +void dppc_interpreter::ppc_neg() { ppc_grab_regsda(); ppc_result_d = ~(ppc_result_a) + 1; @@ -513,7 +513,7 @@ void ppc_neg() { ppc_store_result_regd(); } -void ppc_cntlzw() { +void dppc_interpreter::ppc_cntlzw() { ppc_grab_regssa(); uint32_t lead = 0; @@ -538,7 +538,7 @@ void ppc_cntlzw() { ppc_store_result_rega(); } -void ppc_mulhwu() { +void dppc_interpreter::ppc_mulhwu() { ppc_grab_regsdab(); uint64_t product = (uint64_t)ppc_result_a * (uint64_t)ppc_result_b; ppc_result_d = (uint32_t)(product >> 32); @@ -549,7 +549,7 @@ void ppc_mulhwu() { ppc_store_result_regd(); } -void ppc_mulhw() { +void dppc_interpreter::ppc_mulhw() { ppc_grab_regsdab(); int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; ppc_result_d = product >> 32; @@ -560,7 +560,7 @@ void ppc_mulhw() { ppc_store_result_regd(); } -void ppc_mullw() { +void dppc_interpreter::ppc_mullw() { ppc_grab_regsdab(); int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b; @@ -580,14 +580,14 @@ void ppc_mullw() { ppc_store_result_regd(); } -void ppc_mulli() { +void dppc_interpreter::ppc_mulli() { ppc_grab_regsdasimm(); int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)simm; ppc_result_d = (uint32_t)product; ppc_store_result_regd(); } -void ppc_divw() { +void dppc_interpreter::ppc_divw() { ppc_grab_regsdab(); if (!ppc_result_b) { /* handle the "anything / 0" case */ @@ -616,7 +616,7 @@ void ppc_divw() { ppc_store_result_regd(); } -void ppc_divwu() { +void dppc_interpreter::ppc_divwu() { ppc_grab_regsdab(); if (!ppc_result_b) { /* division by zero */ @@ -642,7 +642,7 @@ void ppc_divwu() { // Value shifting -void ppc_slw() { +void dppc_interpreter::ppc_slw() { ppc_grab_regssab(); if (ppc_result_b & 0x20) { ppc_result_a = 0; @@ -656,7 +656,7 @@ void ppc_slw() { ppc_store_result_rega(); } -void ppc_srw() { +void dppc_interpreter::ppc_srw() { ppc_grab_regssab(); if (ppc_result_b & 0x20) { ppc_result_a = 0; @@ -670,7 +670,7 @@ void ppc_srw() { ppc_store_result_rega(); } -void ppc_sraw() { +void dppc_interpreter::ppc_sraw() { ppc_grab_regssab(); if (ppc_result_b & 0x20) { ppc_result_a = (int32_t)ppc_result_d >> 31; @@ -692,7 +692,7 @@ void ppc_sraw() { ppc_store_result_rega(); } -void ppc_srawi() { +void dppc_interpreter::ppc_srawi() { ppc_grab_regssa(); unsigned shift = (ppc_cur_instruction >> 11) & 0x1F; uint32_t mask = (1 << shift) - 1; @@ -716,7 +716,7 @@ static inline uint32_t rot_mask(unsigned rot_mb, unsigned rot_me) { return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2); } -void ppc_rlwimi() { +void dppc_interpreter::ppc_rlwimi() { ppc_grab_regssa(); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; @@ -730,7 +730,7 @@ void ppc_rlwimi() { ppc_store_result_rega(); } -void ppc_rlwinm() { +void dppc_interpreter::ppc_rlwinm() { ppc_grab_regssa(); unsigned rot_sh = (ppc_cur_instruction >> 11) & 31; unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; @@ -744,7 +744,7 @@ void ppc_rlwinm() { ppc_store_result_rega(); } -void ppc_rlwnm() { +void dppc_interpreter::ppc_rlwnm() { ppc_grab_regssab(); unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; unsigned rot_me = (ppc_cur_instruction >> 1) & 31; @@ -757,12 +757,12 @@ void ppc_rlwnm() { ppc_store_result_rega(); } -void ppc_mfcr() { +void dppc_interpreter::ppc_mfcr() { reg_d = (ppc_cur_instruction >> 21) & 31; ppc_state.gpr[reg_d] = ppc_state.cr; } -void ppc_mtsr() { +void dppc_interpreter::ppc_mtsr() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -773,7 +773,7 @@ void ppc_mtsr() { } } -void ppc_mtsrin() { +void dppc_interpreter::ppc_mtsrin() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -784,7 +784,7 @@ void ppc_mtsrin() { } } -void ppc_mfsr() { +void dppc_interpreter::ppc_mfsr() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -795,7 +795,7 @@ void ppc_mfsr() { } } -void ppc_mfsrin() { +void dppc_interpreter::ppc_mfsrin() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -806,7 +806,7 @@ void ppc_mfsrin() { } } -void ppc_mfmsr() { +void dppc_interpreter::ppc_mfmsr() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -817,7 +817,7 @@ void ppc_mfmsr() { ppc_state.gpr[reg_d] = ppc_state.msr; } -void ppc_mtmsr() { +void dppc_interpreter::ppc_mtmsr() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -828,7 +828,7 @@ void ppc_mtmsr() { ppc_state.msr = ppc_state.gpr[reg_s]; } -void ppc_mfspr() { +void dppc_interpreter::ppc_mfspr() { uint32_t ref_spr = (((ppc_cur_instruction >> 11) & 31) << 5) | ((ppc_cur_instruction >> 16) & 31); #ifdef PROFILER @@ -840,7 +840,7 @@ void ppc_mfspr() { ppc_state.gpr[reg_d] = ppc_state.spr[ref_spr]; } -void ppc_mtspr() { +void dppc_interpreter::ppc_mtspr() { uint32_t ref_spr = (((ppc_cur_instruction >> 11) & 31) << 5) | ((ppc_cur_instruction >> 16) & 31); reg_s = (ppc_cur_instruction >> 21) & 31; @@ -885,7 +885,7 @@ void ppc_mtspr() { } } -void ppc_mftb() { +void dppc_interpreter::ppc_mftb() { uint32_t ref_spr = (((ppc_cur_instruction >> 11) & 31) << 5) | ((ppc_cur_instruction >> 16) & 31); reg_d = (ppc_cur_instruction >> 21) & 31; switch (ref_spr) { @@ -900,7 +900,7 @@ void ppc_mftb() { } } -void ppc_mtcrf() { +void dppc_interpreter::ppc_mtcrf() { uint32_t cr_mask = 0; ppc_grab_regssa(); crm = ((ppc_cur_instruction >> 12) & 255); @@ -916,7 +916,7 @@ void ppc_mtcrf() { ppc_state.cr = (ppc_result_d & cr_mask) | (ppc_state.cr & ~(cr_mask)); } -void ppc_mcrxr() { +void dppc_interpreter::ppc_mcrxr() { crf_d = (ppc_cur_instruction >> 23) & 7; crf_d = crf_d << 2; ppc_state.cr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) | @@ -924,7 +924,7 @@ void ppc_mcrxr() { ppc_state.spr[SPR::XER] &= 0x0FFFFFFF; } -void ppc_extsb() { +void dppc_interpreter::ppc_extsb() { ppc_grab_regssa(); ppc_result_d = ppc_result_d & 0xFF; ppc_result_a = (ppc_result_d < 0x80) ? (ppc_result_d & 0x000000FF) @@ -936,7 +936,7 @@ void ppc_extsb() { ppc_store_result_rega(); } -void ppc_extsh() { +void dppc_interpreter::ppc_extsh() { ppc_grab_regssa(); ppc_result_d = ppc_result_d & 0xFFFF; ppc_result_a = (ppc_result_d < 0x8000) ? (ppc_result_d & 0x0000FFFF) @@ -953,14 +953,14 @@ void ppc_extsh() { // The middle 24 bytes are the 24-bit address to use for branching to. -void ppc_b() { +void dppc_interpreter::ppc_b() { uint32_t quick_test = (ppc_cur_instruction & 0x03FFFFFC); adr_li = (quick_test < 0x2000000) ? quick_test : (0xFC000000UL + quick_test); ppc_next_instruction_address = (uint32_t)(ppc_state.pc + adr_li); bb_kind = BB_end_kind::BB_BRANCH; } -void ppc_bl() { +void dppc_interpreter::ppc_bl() { uint32_t quick_test = (ppc_cur_instruction & 0x03FFFFFC); adr_li = (quick_test < 0x2000000) ? quick_test : (0xFC000000UL + quick_test); ppc_next_instruction_address = (uint32_t)(ppc_state.pc + adr_li); @@ -968,14 +968,14 @@ void ppc_bl() { bb_kind = BB_end_kind::BB_BRANCH; } -void ppc_ba() { +void dppc_interpreter::ppc_ba() { uint32_t quick_test = (ppc_cur_instruction & 0x03FFFFFC); adr_li = (quick_test < 0x2000000) ? quick_test : (0xFC000000UL + quick_test); ppc_next_instruction_address = adr_li; bb_kind = BB_end_kind::BB_BRANCH; } -void ppc_bla() { +void dppc_interpreter::ppc_bla() { uint32_t quick_test = (ppc_cur_instruction & 0x03FFFFFC); adr_li = (quick_test < 0x2000000) ? quick_test : (0xFC000000UL + quick_test); ppc_next_instruction_address = adr_li; @@ -983,7 +983,7 @@ void ppc_bla() { bb_kind = BB_end_kind::BB_BRANCH; } -void ppc_bc() { +void dppc_interpreter::ppc_bc() { uint32_t ctr_ok; uint32_t cnd_ok; uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; @@ -1002,7 +1002,7 @@ void ppc_bc() { } } -void ppc_bca() { +void dppc_interpreter::ppc_bca() { uint32_t ctr_ok; uint32_t cnd_ok; uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; @@ -1021,7 +1021,7 @@ void ppc_bca() { } } -void ppc_bcl() { +void dppc_interpreter::ppc_bcl() { uint32_t ctr_ok; uint32_t cnd_ok; uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; @@ -1041,7 +1041,7 @@ void ppc_bcl() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -void ppc_bcla() { +void dppc_interpreter::ppc_bcla() { uint32_t ctr_ok; uint32_t cnd_ok; uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; @@ -1061,7 +1061,7 @@ void ppc_bcla() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -void ppc_bcctr() { +void dppc_interpreter::ppc_bcctr() { uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; @@ -1074,7 +1074,7 @@ void ppc_bcctr() { } } -void ppc_bcctrl() { +void dppc_interpreter::ppc_bcctrl() { uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; @@ -1088,7 +1088,7 @@ void ppc_bcctrl() { ppc_state.spr[SPR::LR] = ppc_state.pc + 4; } -void ppc_bclr() { +void dppc_interpreter::ppc_bclr() { uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; uint32_t ctr_ok; @@ -1106,7 +1106,7 @@ void ppc_bclr() { } } -void ppc_bclrl() { +void dppc_interpreter::ppc_bclrl() { uint32_t br_bo = (ppc_cur_instruction >> 21) & 31; uint32_t br_bi = (ppc_cur_instruction >> 16) & 31; uint32_t ctr_ok; @@ -1126,7 +1126,7 @@ void ppc_bclrl() { } // Compare Instructions -void ppc_cmp() { +void dppc_interpreter::ppc_cmp() { #ifdef CHECK_INVALID if (ppc_cur_instruction & 0x200000) { LOG_F(WARNING, "Invalid CMP instruction form (L=1)!\n"); @@ -1144,7 +1144,7 @@ void ppc_cmp() { ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void ppc_cmpi() { +void dppc_interpreter::ppc_cmpi() { #ifdef CHECK_INVALID if (ppc_cur_instruction & 0x200000) { LOG_F(WARNING, "Invalid CMPI instruction form (L=1)!\n"); @@ -1162,7 +1162,7 @@ void ppc_cmpi() { ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void ppc_cmpl() { +void dppc_interpreter::ppc_cmpl() { #ifdef CHECK_INVALID if (ppc_cur_instruction & 0x200000) { LOG_F(WARNING, "Invalid CMPL instruction form (L=1)!\n"); @@ -1180,7 +1180,7 @@ void ppc_cmpl() { ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d)); } -void ppc_cmpli() { +void dppc_interpreter::ppc_cmpli() { #ifdef CHECK_INVALID if (ppc_cur_instruction & 0x200000) { LOG_F(WARNING, "Invalid CMPLI instruction form (L=1)!\n"); @@ -1199,7 +1199,7 @@ void ppc_cmpli() { // Condition Register Changes -void ppc_crand() { +void dppc_interpreter::ppc_crand() { ppc_grab_regsdab(); if ((ppc_state.cr & (0x80000000UL >> reg_a)) && (ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1207,7 +1207,7 @@ void ppc_crand() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_crandc() { +void dppc_interpreter::ppc_crandc() { ppc_grab_regsdab(); if ((ppc_state.cr & (0x80000000UL >> reg_a)) && !(ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1215,7 +1215,7 @@ void ppc_crandc() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_creqv() { +void dppc_interpreter::ppc_creqv() { ppc_grab_regsdab(); if (!((ppc_state.cr & (0x80000000UL >> reg_a)) ^ (ppc_state.cr & (0x80000000UL >> reg_b)))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1223,7 +1223,7 @@ void ppc_creqv() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_crnand() { +void dppc_interpreter::ppc_crnand() { ppc_grab_regsdab(); if (!((ppc_state.cr & (0x80000000UL >> reg_a)) && (ppc_state.cr & (0x80000000UL >> reg_b)))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1231,7 +1231,7 @@ void ppc_crnand() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_crnor() { +void dppc_interpreter::ppc_crnor() { ppc_grab_regsdab(); if (!((ppc_state.cr & (0x80000000UL >> reg_a)) || (ppc_state.cr & (0x80000000UL >> reg_b)))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1240,7 +1240,7 @@ void ppc_crnor() { } } -void ppc_cror() { +void dppc_interpreter::ppc_cror() { ppc_grab_regsdab(); if ((ppc_state.cr & (0x80000000UL >> reg_a)) || (ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1248,7 +1248,7 @@ void ppc_cror() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_crorc() { +void dppc_interpreter::ppc_crorc() { ppc_grab_regsdab(); if ((ppc_state.cr & (0x80000000UL >> reg_a)) || !(ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1256,7 +1256,7 @@ void ppc_crorc() { ppc_state.cr &= ~(0x80000000UL >> reg_d); } } -void ppc_crxor() { +void dppc_interpreter::ppc_crxor() { ppc_grab_regsdab(); if ((ppc_state.cr & (0x80000000UL >> reg_a)) ^ (ppc_state.cr & (0x80000000UL >> reg_b))) { ppc_state.cr |= (0x80000000UL >> reg_d); @@ -1267,7 +1267,7 @@ void ppc_crxor() { // Processor MGMT Fns. -void ppc_rfi() { +void dppc_interpreter::ppc_rfi() { #ifdef PROFILER supervisor_inst_num++; #endif @@ -1280,11 +1280,11 @@ void ppc_rfi() { bb_kind = BB_end_kind::BB_RFI; } -void ppc_sc() { +void dppc_interpreter::ppc_sc() { ppc_exception_handler(Except_Type::EXC_SYSCALL, 0x20000); } -void ppc_tw() { +void dppc_interpreter::ppc_tw() { reg_a = (ppc_cur_instruction >> 11) & 31; reg_b = (ppc_cur_instruction >> 16) & 31; ppc_to = (ppc_cur_instruction >> 21) & 31; @@ -1297,7 +1297,7 @@ void ppc_tw() { } } -void ppc_twi() { +void dppc_interpreter::ppc_twi() { simm = (int32_t)((int16_t)((ppc_cur_instruction)&0xFFFF)); reg_a = (ppc_cur_instruction >> 16) & 0x1F; ppc_to = (ppc_cur_instruction >> 21) & 0x1F; @@ -1310,48 +1310,48 @@ void ppc_twi() { } } -void ppc_eieio() { +void dppc_interpreter::ppc_eieio() { /* placeholder */ } -void ppc_isync() { +void dppc_interpreter::ppc_isync() { /* placeholder */ } -void ppc_sync() { +void dppc_interpreter::ppc_sync() { /* placeholder */ } -void ppc_icbi() { +void dppc_interpreter::ppc_icbi() { /* placeholder */ } -void ppc_dcbf() { +void dppc_interpreter::ppc_dcbf() { /* placeholder */ } -void ppc_dcbi() { +void dppc_interpreter::ppc_dcbi() { #ifdef PROFILER supervisor_inst_num++; #endif /* placeholder */ } -void ppc_dcbst() { +void dppc_interpreter::ppc_dcbst() { /* placeholder */ } -void ppc_dcbt() { +void dppc_interpreter::ppc_dcbt() { // Not needed, the HDI reg is touched to no-op this instruction. return; } -void ppc_dcbtst() { +void dppc_interpreter::ppc_dcbtst() { // Not needed, the HDI reg is touched to no-op this instruction. return; } -void ppc_dcbz() { +void dppc_interpreter::ppc_dcbz() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); if (!(ppc_state.pc & 32) && (ppc_state.pc < 0xFFFFFFE0UL)) { @@ -1369,20 +1369,20 @@ void ppc_dcbz() { // Integer Load and Store Functions -void ppc_stb() { +void dppc_interpreter::ppc_stb() { ppc_grab_regssa(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; mem_write_byte(ppc_effective_address, ppc_result_d); } -void ppc_stbx() { +void dppc_interpreter::ppc_stbx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); mem_write_byte(ppc_effective_address, ppc_result_d); } -void ppc_stbu() { +void dppc_interpreter::ppc_stbu() { ppc_grab_regssa(); if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -1394,7 +1394,7 @@ void ppc_stbu() { } } -void ppc_stbux() { +void dppc_interpreter::ppc_stbux() { ppc_grab_regssab(); if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1405,14 +1405,14 @@ void ppc_stbux() { } } -void ppc_sth() { +void dppc_interpreter::ppc_sth() { ppc_grab_regssa(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; mem_write_word(ppc_effective_address, ppc_result_d); } -void ppc_sthu() { +void dppc_interpreter::ppc_sthu() { ppc_grab_regssa(); if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -1424,7 +1424,7 @@ void ppc_sthu() { } } -void ppc_sthux() { +void dppc_interpreter::ppc_sthux() { ppc_grab_regssab(); if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1435,32 +1435,32 @@ void ppc_sthux() { } } -void ppc_sthx() { +void dppc_interpreter::ppc_sthx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); mem_write_word(ppc_effective_address, ppc_result_d); } -void ppc_sthbrx() { +void dppc_interpreter::ppc_sthbrx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = (uint32_t)(BYTESWAP_16((uint16_t)ppc_result_d)); mem_write_word(ppc_effective_address, ppc_result_d); } -void ppc_stw() { +void dppc_interpreter::ppc_stw() { ppc_grab_regssa(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; mem_write_dword(ppc_effective_address, ppc_result_d); } -void ppc_stwx() { +void dppc_interpreter::ppc_stwx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); mem_write_dword(ppc_effective_address, ppc_result_d); } -void ppc_stwcx() { +void dppc_interpreter::ppc_stwcx() { // PLACEHOLDER CODE FOR STWCX - We need to check for reserve memory if (rc_flag == 0) { ppc_illegalsubop31(); @@ -1477,7 +1477,7 @@ void ppc_stwcx() { } } -void ppc_stwu() { +void dppc_interpreter::ppc_stwu() { ppc_grab_regssa(); if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -1489,7 +1489,7 @@ void ppc_stwu() { } } -void ppc_stwux() { +void dppc_interpreter::ppc_stwux() { ppc_grab_regssab(); if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1500,14 +1500,14 @@ void ppc_stwux() { } } -void ppc_stwbrx() { +void dppc_interpreter::ppc_stwbrx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = BYTESWAP_32(ppc_result_d); mem_write_dword(ppc_effective_address, ppc_result_d); } -void ppc_stmw() { +void dppc_interpreter::ppc_stmw() { ppc_grab_regssa(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1523,7 +1523,7 @@ void ppc_stmw() { } } -void ppc_lbz() { +void dppc_interpreter::ppc_lbz() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1531,7 +1531,7 @@ void ppc_lbz() { ppc_store_result_regd(); } -void ppc_lbzu() { +void dppc_interpreter::ppc_lbzu() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); if ((reg_a != reg_d) || reg_a != 0) { @@ -1545,14 +1545,14 @@ void ppc_lbzu() { } } -void ppc_lbzx() { +void dppc_interpreter::ppc_lbzx() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = mem_grab_byte(ppc_effective_address); ppc_store_result_regd(); } -void ppc_lbzux() { +void dppc_interpreter::ppc_lbzux() { ppc_grab_regsdab(); if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1566,7 +1566,7 @@ void ppc_lbzux() { } -void ppc_lhz() { +void dppc_interpreter::ppc_lhz() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1574,7 +1574,7 @@ void ppc_lhz() { ppc_store_result_regd(); } -void ppc_lhzu() { +void dppc_interpreter::ppc_lhzu() { ppc_grab_regsda(); if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -1588,14 +1588,14 @@ void ppc_lhzu() { } } -void ppc_lhzx() { +void dppc_interpreter::ppc_lhzx() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = mem_grab_word(ppc_effective_address); ppc_store_result_regd(); } -void ppc_lhzux() { +void dppc_interpreter::ppc_lhzux() { ppc_grab_regsdab(); if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1608,7 +1608,7 @@ void ppc_lhzux() { } } -void ppc_lha() { +void dppc_interpreter::ppc_lha() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1621,7 +1621,7 @@ void ppc_lha() { ppc_store_result_regd(); } -void ppc_lhau() { +void dppc_interpreter::ppc_lhau() { ppc_grab_regsda(); if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); @@ -1640,7 +1640,7 @@ void ppc_lhau() { } } -void ppc_lhaux() { +void dppc_interpreter::ppc_lhaux() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); uint16_t val = mem_grab_word(ppc_effective_address); @@ -1654,7 +1654,7 @@ void ppc_lhaux() { ppc_store_result_rega(); } -void ppc_lhax() { +void dppc_interpreter::ppc_lhax() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); uint16_t val = mem_grab_word(ppc_effective_address); @@ -1666,14 +1666,14 @@ void ppc_lhax() { ppc_store_result_regd(); } -void ppc_lhbrx() { +void dppc_interpreter::ppc_lhbrx() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = (uint32_t)(BYTESWAP_16(mem_grab_word(ppc_effective_address))); ppc_store_result_regd(); } -void ppc_lwz() { +void dppc_interpreter::ppc_lwz() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1681,14 +1681,14 @@ void ppc_lwz() { ppc_store_result_regd(); } -void ppc_lwbrx() { +void dppc_interpreter::ppc_lwbrx() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = BYTESWAP_32(mem_grab_dword(ppc_effective_address)); ppc_store_result_regd(); } -void ppc_lwzu() { +void dppc_interpreter::ppc_lwzu() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); if ((reg_a != reg_d) || reg_a != 0) { @@ -1702,14 +1702,14 @@ void ppc_lwzu() { } } -void ppc_lwzx() { +void dppc_interpreter::ppc_lwzx() { ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); ppc_result_d = mem_grab_dword(ppc_effective_address); ppc_store_result_regd(); } -void ppc_lwzux() { +void dppc_interpreter::ppc_lwzux() { ppc_grab_regsdab(); if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; @@ -1722,7 +1722,7 @@ void ppc_lwzux() { ppc_store_result_rega(); } -void ppc_lwarx() { +void dppc_interpreter::ppc_lwarx() { // Placeholder - Get the reservation of memory implemented! ppc_grab_regsdab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); @@ -1731,7 +1731,7 @@ void ppc_lwarx() { ppc_store_result_regd(); } -void ppc_lmw() { +void dppc_interpreter::ppc_lmw() { ppc_grab_regsda(); ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; @@ -1743,7 +1743,7 @@ void ppc_lmw() { } while (reg_d < 32); } -void ppc_lswi() { +void dppc_interpreter::ppc_lswi() { ppc_grab_regsda(); ppc_effective_address = ppc_result_a; grab_inb = (ppc_cur_instruction >> 11) & 31; @@ -1786,7 +1786,7 @@ void ppc_lswi() { } } -void ppc_lswx() { +void dppc_interpreter::ppc_lswx() { ppc_grab_regsdab(); // Invalid instruction forms if ((ppc_result_d == 0) && (ppc_result_a == 0)) { @@ -1833,7 +1833,7 @@ void ppc_lswx() { } } -void ppc_stswi() { +void dppc_interpreter::ppc_stswi() { ppc_grab_regssa(); ppc_effective_address = (reg_a == 0) ? 0 : ppc_result_a; grab_inb = (ppc_cur_instruction >> 11) & 31; @@ -1871,7 +1871,7 @@ void ppc_stswi() { } } -void ppc_stswx() { +void dppc_interpreter::ppc_stswx() { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); grab_inb = ppc_state.spr[SPR::XER] & 127; @@ -1910,35 +1910,35 @@ void ppc_stswx() { // TLB Instructions -void ppc_tlbie() { +void dppc_interpreter::ppc_tlbie() { #ifdef PROFILER supervisor_inst_num++; #endif /* placeholder */ } -void ppc_tlbia() { +void dppc_interpreter::ppc_tlbia() { #ifdef PROFILER supervisor_inst_num++; #endif /* placeholder */ } -void ppc_tlbld() { +void dppc_interpreter::ppc_tlbld() { #ifdef PROFILER supervisor_inst_num++; #endif /* placeholder */ } -void ppc_tlbli() { +void dppc_interpreter::ppc_tlbli() { #ifdef PROFILER supervisor_inst_num++; #endif /* placeholder */ } -void ppc_tlbsync() { +void dppc_interpreter::ppc_tlbsync() { #ifdef PROFILER supervisor_inst_num++; #endif diff --git a/execution/interpreter_loop.cpp b/execution/interpreter_loop.cpp index d9cb245..8b70ed2 100644 --- a/execution/interpreter_loop.cpp +++ b/execution/interpreter_loop.cpp @@ -51,7 +51,7 @@ void round_robin_bench() { std::chrono::high_resolution_clock::time_point dummy = std::chrono::high_resolution_clock::now(); for (int i = 0; i < 4096; i++) { - ppc_ori(); //execute NOPs as a basic test + dppc_interpreter::ppc_ori(); //execute NOPs as a basic test } std::chrono::high_resolution_clock::time_point dummy2 = std::chrono::high_resolution_clock::now(); From 2b19b0b23709bf3eb4822c295fa7a260b8b1c460 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 14 Nov 2020 02:57:21 +0100 Subject: [PATCH 08/20] ppcmmu: better initialization of last used entries. --- cpu/ppc/ppcmmu.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 5439fb5..43cc0bd 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -48,11 +48,11 @@ PPC_BAT_entry ibat_array[4] = {{0}}; PPC_BAT_entry dbat_array[4] = {{0}}; /** remember recently used physical memory regions for quicker translation. */ -AddressMapEntry last_read_area = {0}; -AddressMapEntry last_write_area = {0}; -AddressMapEntry last_exec_area = {0}; -AddressMapEntry last_ptab_area = {0}; -AddressMapEntry last_dma_area = {0}; +AddressMapEntry last_read_area = {0xFFFFFFFF, 0xFFFFFFFF}; +AddressMapEntry last_write_area = {0xFFFFFFFF, 0xFFFFFFFF}; +AddressMapEntry last_exec_area = {0xFFFFFFFF, 0xFFFFFFFF}; +AddressMapEntry last_ptab_area = {0xFFFFFFFF, 0xFFFFFFFF}; +AddressMapEntry last_dma_area = {0xFFFFFFFF, 0xFFFFFFFF}; /* macro for generating code reading from physical memory */ From b81de4af486b509d0fabea0945271413df80dc72 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 14 Nov 2020 02:59:49 +0100 Subject: [PATCH 09/20] ppcexec: initialize interpreter lookup tables. --- cpu/ppc/ppcexec.cpp | 4 +++- main.cpp | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 807bc01..23ce493 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -90,7 +90,7 @@ static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla}; static PPCOpcode SubOpcode18Grabber[] = {ppc_b, ppc_bl, ppc_ba, ppc_bla}; -/** Instructions decoding tables for integer, +/** Instructions decoding tables for integer, single floating-point, and double-floating point ops respectively */ PPCOpcode SubOpcode31Grabber[1024] = {ppc_illegalsubop19}; @@ -656,6 +656,8 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version) { //test_timebase_update(); + initialize_ppc_opcode_tables(); + /* initialize timer variables */ #ifdef NEW_TBR_UPDATE_ALGO cycles_count = 0; diff --git a/main.cpp b/main.cpp index f2527ac..7a66297 100644 --- a/main.cpp +++ b/main.cpp @@ -121,8 +121,6 @@ int main(int argc, char** argv) { loguru::init(argc, argv); } - initialize_ppc_opcode_tables(); //Temp location for initializing opcode tables - if (*machine_opt) { LOG_F(INFO, "Machine option was passed in: %s", machine_str.c_str()); } else { From 6124dfd8977f5e0d1e73ccbd818554e393e8d624 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 14 Nov 2020 03:05:06 +0100 Subject: [PATCH 10/20] Add virtual CPU benchmarking code. --- CMakeLists.txt | 10 +++++ benchmark/bench1.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 benchmark/bench1.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d9dd0e9..c7b6bb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,16 @@ else() target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() +file(GLOB BENCH_SOURCES "${PROJECT_SOURCE_DIR}/benchmark/*.cpp") +add_executable(bench1 ${BENCH_SOURCES} $ + $ + $ + $ + $ + $) + +target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + add_custom_command( TARGET testppc POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy diff --git a/benchmark/bench1.cpp b/benchmark/bench1.cpp new file mode 100644 index 0000000..b994b32 --- /dev/null +++ b/benchmark/bench1.cpp @@ -0,0 +1,91 @@ +#include +#include +#include "cpu/ppc/ppcemu.h" +#include "cpu/ppc/ppcmmu.h" +#include "devices/mpc106.h" +#include + +uint32_t cs_code[] = { + 0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002, 0x41E2001C, 0xA0030004, + 0x3884FFFE, 0x38630002, 0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003, + 0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114, 0x4200FFF8, 0x5486E13F, + 0x41820050, 0x80030004, 0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C, + 0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028, 0x80030004, 0x7CA54114, + 0x80C30008, 0x7CA50114, 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914, + 0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, 0xA0030004, 0x38630002, + 0x7CA50114, 0x70800001, 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114, + 0x7C650194, 0x4E800020 +}; + + +int main(int argc, char** argv) { + int i; + + /* initialize logging */ + loguru::g_preamble_date = false; + loguru::g_preamble_time = false; + loguru::g_preamble_thread = false; + + loguru::g_stderr_verbosity = 0; + loguru::init(argc, argv); + + MPC106* grackle_obj = new MPC106; + + /* we need some RAM */ + if (!grackle_obj->add_ram_region(0, 0x9000)) { + LOG_F(ERROR, "Could not create RAM region"); + delete(grackle_obj); + return -1; + } + + ppc_cpu_init(grackle_obj, PPC_VER::MPC750); + + /* load executable code into RAM at address 0 */ + for (i = 0; i < sizeof(cs_code); i++) { + mem_write_dword(i*4, cs_code[i]); + } + + srand(0xCAFEBABE); + + for (i = 0; i < 32768; i++) { + mem_write_byte(0x1000+i, rand() % 256); + } + + /* prepare benchmark code execution */ + ppc_state.pc = 0; + ppc_state.gpr[3] = 0x1000; // buf + ppc_state.gpr[4] = 0x8000; // len + ppc_state.gpr[5] = 0; // sum + + ppc_exec_until(0xC4); + + LOG_F(INFO, "Checksum: 0x%08X", ppc_state.gpr[3]); + + // run the clock once for cache fill etc. + auto start_time = std::chrono::steady_clock::now(); + auto end_time = std::chrono::steady_clock::now(); + auto time_elapsed = std::chrono::duration_cast(end_time - start_time); + LOG_F(INFO, "Time elapsed (dry run): %lld ns", time_elapsed.count()); + + for (i = 0; i < 5; i++) { + ppc_state.pc = 0; + ppc_state.gpr[3] = 0x1000; // buf + ppc_state.gpr[4] = 0x8000; // len + ppc_state.gpr[5] = 0; // sum + + auto start_time = std::chrono::steady_clock::now(); + + ppc_exec_until(0xC4); + + auto end_time = std::chrono::steady_clock::now(); + + LOG_F(INFO, "Checksum: 0x%08X", ppc_state.gpr[3]); + + auto time_elapsed = std::chrono::duration_cast(end_time - start_time); + LOG_F(INFO, "Time elapsed (run #%d): %lld ns", i, time_elapsed.count()); + } + + delete(grackle_obj); + + return 0; +} From 81b3c3c4a0c9f63802357e78f74fbaefb6a9d6c4 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 26 Nov 2020 03:03:52 +0100 Subject: [PATCH 11/20] Default initialization of Heathrow registers. --- devices/macio.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/devices/macio.h b/devices/macio.h index 7138c6c..f06bd77 100644 --- a/devices/macio.h +++ b/devices/macio.h @@ -135,13 +135,13 @@ private: 0x00 // unknown defaults }; - uint32_t int_mask2; - uint32_t int_clear2; - uint32_t int_levels2; - uint32_t int_mask1; - uint32_t int_clear1; - uint32_t int_levels1; - uint32_t feat_ctrl; // features control register + uint32_t int_mask2 = 0; + uint32_t int_clear2 = 0; + uint32_t int_levels2 = 0; + uint32_t int_mask1 = 0; + uint32_t int_clear1 = 0; + uint32_t int_levels1 = 0; + uint32_t feat_ctrl = 0; // features control register /* device cells */ ViaCuda* viacuda; /* VIA cell with Cuda MCU attached to it */ From 0e83ffe435590c7287ce17fce89c522c9f74e278 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 28 Nov 2020 01:08:34 +0100 Subject: [PATCH 12/20] Fix broken CMakeLists.txt to work on MacOS. --- CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99c1839..db9ec8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ link_directories(${CAPSTONE_LIBRARY_DIRS}) add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/") add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/") add_subdirectory("${PROJECT_SOURCE_DIR}/devices/") +add_subdirectory("${PROJECT_SOURCE_DIR}/execution") add_subdirectory("${PROJECT_SOURCE_DIR}/machines/") add_subdirectory("${PROJECT_SOURCE_DIR}/thirdparty/loguru/") @@ -40,6 +41,8 @@ set(BUILD_TOOLS OFF CACHE BOOL "Build Cubeb tools") add_subdirectory(thirdparty/cubeb EXCLUDE_FROM_ALL) +set(CLI11_ROOT ${PROJECT_SOURCE_DIR}/thirdparty/CLI11) + include_directories("${PROJECT_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}/devices" "${PROJECT_SOURCE_DIR}/cpu/ppc" "${PROJECT_SOURCE_DIR}/debugger" @@ -60,6 +63,7 @@ file(GLOB TEST_SOURCES "${PROJECT_SOURCE_DIR}/cpu/ppc/test/*.cpp") add_executable(dingusppc ${SOURCES} $ $ $ + $ $ $) @@ -70,12 +74,14 @@ target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/S else() #target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_include_directories(dingusppc PRIVATE ${CLI11_ROOT}) endif() add_executable(testppc ${TEST_SOURCES} $ $ $ + $ $ $) @@ -88,6 +94,16 @@ else() target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() +file(GLOB BENCH_SOURCES "${PROJECT_SOURCE_DIR}/benchmark/*.cpp") +add_executable(bench1 ${BENCH_SOURCES} $ + $ + $ + $ + $ + $) + +target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + add_custom_command( TARGET testppc POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy From 2be8e7b542d57c4bd2980d5f7774045fea4cc020 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 28 Nov 2020 02:22:37 +0100 Subject: [PATCH 13/20] Set minimum Capstone version to 4.0.2 This version has fixed a bug with Capstone's main header. --- CMakeLists.txt | 2 +- debugger/debugger.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db9ec8d..84e8ded 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() endif() find_package(PkgConfig REQUIRED) -pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.1) +pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.2) include_directories(${CAPSTONE_INCLUDE_DIRS}) link_directories(${CAPSTONE_LIBRARY_DIRS}) diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index bf1b4c9..b646fba 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include #include #include -#include +#include #include "../cpu/ppc/ppcdisasm.h" #include "../cpu/ppc/ppcemu.h" #include "../cpu/ppc/ppcmmu.h" From a775007d3a0ccef29cbf6b89498b2cabd3fe1488 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sun, 29 Nov 2020 00:23:30 +0100 Subject: [PATCH 14/20] MMU: implement misaligned cross-page accesses. --- cpu/ppc/ppcmmu.cpp | 54 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 43cc0bd..6ad185f 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -55,6 +55,8 @@ AddressMapEntry last_ptab_area = {0xFFFFFFFF, 0xFFFFFFFF}; AddressMapEntry last_dma_area = {0xFFFFFFFF, 0xFFFFFFFF}; +#define WRITE_BYTE(addr, val) (*(addr) = val) + /* macro for generating code reading from physical memory */ #define READ_PHYS_MEM(ENTRY, ADDR, OP, SIZE, UNVAL) \ { \ @@ -371,13 +373,32 @@ static uint32_t ppc_mmu_addr_translate(uint32_t la, int is_write) { } static void mem_write_unaligned(uint32_t addr, uint32_t value, uint32_t size) { +#ifdef MMU_DEBUG LOG_F(WARNING, "Attempt to write unaligned %d bytes to 0x%08X\n", size, addr); +#endif if (((addr & 0xFFF) + size) > 0x1000) { - LOG_F(ERROR, "SOS! Cross-page unaligned write, addr=%08X, size=%d\n", addr, size); - exit(-1); // FIXME! + // Special case: unaligned cross-page writes + LOG_F(WARNING, "Cross-page unaligned write, addr=%08X, size=%d\n", + addr, size); + + uint32_t phys_addr; + uint32_t shift = (size - 1) * 8; + + // Break misaligned memory accesses into multiple, smaller accesses + // and retranslate on page boundary. + // Because such accesses suffer a performance penalty, they will be + // presumably very rare so don't care much about performance. + for (int i = 0; i < size; shift -= 8, addr++, phys_addr++, i++) { + if ((ppc_state.msr & 0x10) && (!i || !(addr & 0xFFF))) { + phys_addr = ppc_mmu_addr_translate(addr, 0); + } + + WRITE_PHYS_MEM(last_write_area, phys_addr, WRITE_BYTE, + (value >> shift) & 0xFF, 1); + } } else { - /* data address translation if enabled */ + // data address translation if enabled if (ppc_state.msr & 0x10) { addr = ppc_mmu_addr_translate(addr, 0); } @@ -396,8 +417,6 @@ void mem_write_byte(uint32_t addr, uint8_t value) { addr = ppc_mmu_addr_translate(addr, 1); } -#define WRITE_BYTE(addr, val) (*(addr) = val) - WRITE_PHYS_MEM(last_write_area, addr, WRITE_BYTE, value, 1); } @@ -444,11 +463,32 @@ void mem_write_qword(uint32_t addr, uint64_t value) { static uint32_t mem_grab_unaligned(uint32_t addr, uint32_t size) { uint32_t ret = 0; +#ifdef MMU_DEBUG LOG_F(WARNING, "Attempt to read unaligned %d bytes from 0x%08X\n", size, addr); +#endif if (((addr & 0xFFF) + size) > 0x1000) { - LOG_F(ERROR, "SOS! Cross-page unaligned read, addr=%08X, size=%d\n", addr, size); - exit(-1); // FIXME! + // Special case: misaligned cross-page reads + LOG_F(WARNING, "Cross-page unaligned read, addr=%08X, size=%d\n", + addr, size); + + uint32_t phys_addr; + uint32_t res = 0; + + // Break misaligned memory accesses into multiple, smaller accesses + // and retranslate on page boundary. + // Because such accesses suffer a performance penalty, they will be + // presumably very rare so don't care much about performance. + for (int i = 0; i < size; addr++, phys_addr++, i++) { + if ((ppc_state.msr & 0x10) && (!i || !(addr & 0xFFF))) { + phys_addr = ppc_mmu_addr_translate(addr, 0); + } + + READ_PHYS_MEM(last_read_area, phys_addr, *, 1, 0xFFU); + res = (res << 8) | ret; + } + return res; + } else { /* data address translation if enabled */ if (ppc_state.msr & 0x10) { From 54fcfca8e9a9ffc9ae9512f2afcf8b4c0ffa348b Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 29 Nov 2020 06:52:01 -0700 Subject: [PATCH 15/20] Fixed floating point loading and storing instructions --- cpu/ppc/ppcfpopcodes.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index b3eb088..5a22354 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -767,7 +767,7 @@ void dppc_interpreter::ppc_lfs() { void dppc_interpreter::ppc_lfsu() { ppc_grab_regsfpdia(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0; ppc_result64_d = mem_grab_dword(ppc_effective_address); @@ -788,7 +788,7 @@ void dppc_interpreter::ppc_lfsx() { void dppc_interpreter::ppc_lfsux() { ppc_grab_regsfpdiab(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; ppc_result64_d = mem_grab_dword(ppc_effective_address); ppc_result_a = ppc_effective_address; @@ -809,7 +809,7 @@ void dppc_interpreter::ppc_lfd() { void dppc_interpreter::ppc_lfdu() { ppc_grab_regsfpdia(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += ppc_result_a; ppc_result64_d = mem_grab_qword(ppc_effective_address); @@ -823,14 +823,14 @@ void dppc_interpreter::ppc_lfdu() { void dppc_interpreter::ppc_lfdx() { ppc_grab_regsfpdia(true); - ppc_effective_address += (reg_a > 0) ? ppc_result_a + ppc_result_b : ppc_result_b; + ppc_effective_address = (reg_a > 0) ? ppc_result_a + ppc_result_b : ppc_result_b; ppc_result64_d = mem_grab_qword(ppc_effective_address); ppc_store_dfpresult(true); } void dppc_interpreter::ppc_lfdux() { ppc_grab_regsfpdiab(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; ppc_result64_d = mem_grab_qword(ppc_effective_address); ppc_store_dfpresult(true); @@ -850,7 +850,7 @@ void dppc_interpreter::ppc_stfs() { void dppc_interpreter::ppc_stfsu() { ppc_grab_regsfpsia(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += ppc_result_a; mem_write_dword(ppc_effective_address, uint32_t(ppc_state.fpr[reg_s].int64_r)); @@ -869,7 +869,7 @@ void dppc_interpreter::ppc_stfsx() { void dppc_interpreter::ppc_stfsux() { ppc_grab_regsfpsiab(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; mem_write_dword(ppc_effective_address, uint32_t(ppc_state.fpr[reg_s].int64_r)); ppc_result_a = ppc_effective_address; @@ -888,7 +888,7 @@ void dppc_interpreter::ppc_stfd() { void dppc_interpreter::ppc_stfdu() { ppc_grab_regsfpsia(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)); ppc_effective_address += ppc_result_a; mem_write_qword(ppc_effective_address, ppc_state.fpr[reg_s].int64_r); @@ -907,7 +907,7 @@ void dppc_interpreter::ppc_stfdx() { void dppc_interpreter::ppc_stfdux() { ppc_grab_regsfpsiab(true); - if (reg_a == 0) { + if (reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; mem_write_qword(ppc_effective_address, ppc_state.fpr[reg_s].int64_r); ppc_result_a = ppc_effective_address; From acfa09af65802fe3823c22d4865953fb5fa6f145 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sun, 29 Nov 2020 23:53:03 +0100 Subject: [PATCH 16/20] Illegal opcodes raise program exception. --- cpu/ppc/ppcemu.h | 3 +- cpu/ppc/ppcexec.cpp | 64 +++++++++++------------------------------- cpu/ppc/ppcopcodes.cpp | 10 +++---- 3 files changed, 23 insertions(+), 54 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 848048e..aeba5a9 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -246,7 +246,8 @@ extern uint32_t supervisor_inst_num; extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version); extern void ppc_mmu_init(); -void ppc_illegalop(); +[[noreturn]] void ppc_illegalop(); +[[noreturn]] void ppc_fpu_off(); void ppc_illegalsubop19(); void ppc_illegalsubop31(); void ppc_illegalsubop59(); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 8d792f2..14df672 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -73,7 +73,7 @@ uint8_t tbr_factor; /* cycles_count to TBR freq ratio in 2^x units */ /** Primary opcode (bits 0...5) lookup table. */ static PPCOpcode OpcodeGrabber[] = { - ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_opcode4, ppc_illegalop, + 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, @@ -101,9 +101,9 @@ static PPCOpcode SubOpcode18Grabber[] = { /** Instructions decoding tables for integer, single floating-point, and double-floating point ops respectively */ -PPCOpcode SubOpcode31Grabber[1024] = {ppc_illegalsubop19}; -PPCOpcode SubOpcode59Grabber[1024] = {ppc_illegalsubop19}; -PPCOpcode SubOpcode63Grabber[1024] = {ppc_illegalsubop19}; +PPCOpcode SubOpcode31Grabber[1024] = { ppc_illegalop }; +PPCOpcode SubOpcode59Grabber[1024] = { ppc_fpu_off }; +PPCOpcode SubOpcode63Grabber[1024] = { ppc_fpu_off }; #define UPDATE_TBR_DEC \ @@ -117,50 +117,18 @@ PPCOpcode SubOpcode63Grabber[1024] = {ppc_illegalsubop19}; old_cycles_count += delta << tbr_factor; \ } +/** Exception helpers. */ + +[[noreturn]] void ppc_illegalop() { + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00080000); +} + +[[noreturn]] void ppc_fpu_off() { + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00100000); +} + /** Opcode decoding functions. */ -void ppc_illegalop() { - LOG_F(ERROR, "Illegal opcode reported: 0x%X Report this! \n", ppc_cur_instruction); - exit(-1); -} - -void ppc_illegalsubop19() { - uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; - uint32_t grab_it = (uint32_t)illegal_subcode; - LOG_F(ERROR, "Illegal subopcode for 19 reported: %d Report this! \n", grab_it); - exit(-1); -} - -void ppc_illegalsubop31() { - uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; - uint32_t grab_it = (uint32_t)illegal_subcode; - LOG_F(ERROR, "Illegal subopcode for 31 reported: %d Report this! \n", grab_it); - exit(-1); -} - -void ppc_illegalsubop59() { - uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; - uint32_t grab_it = (uint32_t)illegal_subcode; - LOG_F(ERROR, "Illegal subopcode for 59 reported: %d Report this! \n", grab_it); - exit(-1); -} - -void ppc_illegalsubop63() { - uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF; - uint32_t grab_it = (uint32_t)illegal_subcode; - LOG_F(ERROR, "Illegal subopcode for 63 reported: %d Report this! \n", grab_it); - exit(-1); -} - -void ppc_opcode4() { - LOG_F(INFO, "Reading from Opcode 4 table \n"); - uint8_t subop_grab = ppc_cur_instruction & 3; - uint32_t regrab = (uint32_t)subop_grab; - LOG_F(ERROR, "Executing subopcode entry %d \n" - ".. or would if I bothered to implement it. SORRY!", regrab); - exit(-1); -} - void ppc_opcode16() { SubOpcode16Grabber[ppc_cur_instruction & 3](); } @@ -218,8 +186,8 @@ void ppc_opcode19() { case 898: ppc_cror(); break; - default: // Illegal opcode - should never happen - ppc_illegalsubop19(); + default: + ppc_illegalop(); } } } diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index e1cf3b4..3d0d2da 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -295,7 +295,7 @@ void dppc_interpreter::ppc_addze() { } else { ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL; } - + if (oe_flag) ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d); if (rc_flag) @@ -355,7 +355,7 @@ void dppc_interpreter::ppc_subfme() { uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000); ppc_result_d = ~ppc_result_a + grab_xer - 1; ppc_carry(~ppc_result_a, ppc_result_d); - + if (oe_flag) ppc_setsoov(0xFFFFFFFF, ppc_result_a, ppc_result_d); if (rc_flag) @@ -506,7 +506,7 @@ void dppc_interpreter::ppc_neg() { else ppc_state.spr[SPR::XER] &= 0xBFFFFFFF; } - + if (rc_flag) ppc_changecrf0(ppc_result_d); @@ -602,7 +602,7 @@ void dppc_interpreter::ppc_divw() { if (oe_flag) ppc_state.spr[SPR::XER] |= 0xC0000000; - } + } else { /* normal signed devision */ ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b; @@ -1463,7 +1463,7 @@ void dppc_interpreter::ppc_stwx() { void dppc_interpreter::ppc_stwcx() { // PLACEHOLDER CODE FOR STWCX - We need to check for reserve memory if (rc_flag == 0) { - ppc_illegalsubop31(); + ppc_illegalop(); } else { ppc_grab_regssab(); ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); From 6c6247b94faf40db2824571ad6f3102c4784ee13 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 30 Nov 2020 20:59:36 +0100 Subject: [PATCH 17/20] Clean up program exceptions. --- cpu/ppc/ppcemu.h | 8 ++++++++ cpu/ppc/ppcexec.cpp | 4 ++-- cpu/ppc/ppcfpopcodes.cpp | 16 ++++++++-------- cpu/ppc/ppcopcodes.cpp | 38 +++++++++++++++++++------------------- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index aeba5a9..481be6c 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -215,6 +215,14 @@ enum class Except_Type { EXC_TRACE = 13 }; +/** Programm Exception subclasses. */ +enum Exc_Cause : uint32_t { + FPU_OFF = 1 << (31 - 11), + ILLEGAL_OP = 1 << (31 - 12), + NOT_ALLOWED = 1 << (31 - 13), + TRAP = 1 << (31 - 14), +}; + // extern bool bb_end; extern BB_end_kind bb_kind; diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 14df672..0bd71b8 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -120,11 +120,11 @@ PPCOpcode SubOpcode63Grabber[1024] = { ppc_fpu_off }; /** Exception helpers. */ [[noreturn]] void ppc_illegalop() { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00080000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } [[noreturn]] void ppc_fpu_off() { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00100000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_OFF); } /** Opcode decoding functions. */ diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index 5a22354..c2ff2bc 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -775,7 +775,7 @@ void dppc_interpreter::ppc_lfsu() { ppc_store_dfpresult(true); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -795,7 +795,7 @@ void dppc_interpreter::ppc_lfsux() { ppc_store_dfpresult(true); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -817,7 +817,7 @@ void dppc_interpreter::ppc_lfdu() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -837,7 +837,7 @@ void dppc_interpreter::ppc_lfdux() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -857,7 +857,7 @@ void dppc_interpreter::ppc_stfsu() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -875,7 +875,7 @@ void dppc_interpreter::ppc_stfsux() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -895,7 +895,7 @@ void dppc_interpreter::ppc_stfdu() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -913,7 +913,7 @@ void dppc_interpreter::ppc_stfdux() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 3d0d2da..82ecf96 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -811,7 +811,7 @@ void dppc_interpreter::ppc_mfmsr() { supervisor_inst_num++; #endif if (ppc_state.msr & 0x4000) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } reg_d = (ppc_cur_instruction >> 21) & 31; ppc_state.gpr[reg_d] = ppc_state.msr; @@ -822,7 +822,7 @@ void dppc_interpreter::ppc_mtmsr() { supervisor_inst_num++; #endif if (ppc_state.msr & 0x4000) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED); } reg_s = (ppc_cur_instruction >> 21) & 31; ppc_state.msr = ppc_state.gpr[reg_s]; @@ -1293,7 +1293,7 @@ void dppc_interpreter::ppc_tw() { (((int32_t)ppc_state.gpr[reg_a] == (int32_t)ppc_state.gpr[reg_b]) & (ppc_to & 0x04)) || ((ppc_state.gpr[reg_a] < ppc_state.gpr[reg_b]) & (ppc_to & 0x02)) || ((ppc_state.gpr[reg_a] > ppc_state.gpr[reg_b]) & (ppc_to & 0x01))) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::TRAP); } } @@ -1306,7 +1306,7 @@ void dppc_interpreter::ppc_twi() { (((int32_t)ppc_state.gpr[reg_a] == simm) && (ppc_to & 0x04)) || ((ppc_state.gpr[reg_a] < (uint32_t)simm) && (ppc_to & 0x02)) || ((ppc_state.gpr[reg_a] > (uint32_t)simm) && (ppc_to & 0x01))) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::TRAP); } } @@ -1390,7 +1390,7 @@ void dppc_interpreter::ppc_stbu() { mem_write_byte(ppc_effective_address, ppc_result_d); ppc_state.gpr[reg_a] = ppc_effective_address; } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1401,7 +1401,7 @@ void dppc_interpreter::ppc_stbux() { mem_write_byte(ppc_effective_address, ppc_result_d); ppc_state.gpr[reg_a] = ppc_effective_address; } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1420,7 +1420,7 @@ void dppc_interpreter::ppc_sthu() { 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, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1431,7 +1431,7 @@ void dppc_interpreter::ppc_sthux() { 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, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1485,7 +1485,7 @@ void dppc_interpreter::ppc_stwu() { 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, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1496,7 +1496,7 @@ void dppc_interpreter::ppc_stwux() { 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, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1541,7 +1541,7 @@ void dppc_interpreter::ppc_lbzu() { ppc_store_result_regd(); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1561,7 +1561,7 @@ void dppc_interpreter::ppc_lbzux() { ppc_store_result_regd(); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1584,7 +1584,7 @@ void dppc_interpreter::ppc_lhzu() { ppc_store_result_regd(); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1604,7 +1604,7 @@ void dppc_interpreter::ppc_lhzux() { ppc_store_result_regd(); ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1636,7 +1636,7 @@ void dppc_interpreter::ppc_lhau() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1698,7 +1698,7 @@ void dppc_interpreter::ppc_lwzu() { ppc_result_a = ppc_effective_address; ppc_store_result_rega(); } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } } @@ -1714,7 +1714,7 @@ void dppc_interpreter::ppc_lwzux() { if ((reg_a != reg_d) || reg_a != 0) { ppc_effective_address = ppc_result_a + ppc_result_b; } else { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } ppc_result_d = mem_grab_dword(ppc_effective_address); ppc_result_a = ppc_effective_address; @@ -1790,10 +1790,10 @@ void dppc_interpreter::ppc_lswx() { ppc_grab_regsdab(); // Invalid instruction forms if ((ppc_result_d == 0) && (ppc_result_a == 0)) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } if ((ppc_result_d == ppc_result_a) || (ppc_result_a == ppc_result_b)) { - ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b); grab_inb = ppc_state.spr[SPR::XER] & 127; From f0315e98eeccd61be139a70f550081640f463cae Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 3 Dec 2020 00:53:28 +0100 Subject: [PATCH 18/20] Add Capstone submodule. --- .gitmodules | 4 ++++ CMakeLists.txt | 45 ++++++++++++++++++++++++++++++++++------- debugger/CMakeLists.txt | 6 ++++-- debugger/debugger.cpp | 2 +- thirdparty/capstone | 1 + 5 files changed, 48 insertions(+), 10 deletions(-) create mode 160000 thirdparty/capstone diff --git a/.gitmodules b/.gitmodules index 0516be6..94932bc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "thirdparty/cubeb"] path = thirdparty/cubeb url = https://github.com/DingusDevOrg/cubeb.git +[submodule "thirdparty/capstone"] + path = thirdparty/capstone + url = https://github.com/maximumspatium/capstone.git + branch = next diff --git a/CMakeLists.txt b/CMakeLists.txt index 84e8ded..fdad362 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,41 @@ if (UNIX AND NOT APPLE) endif() endif() -find_package(PkgConfig REQUIRED) -pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.2) -include_directories(${CAPSTONE_INCLUDE_DIRS}) -link_directories(${CAPSTONE_LIBRARY_DIRS}) +#find_package(PkgConfig REQUIRED) +#pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.2) +#include_directories(${CAPSTONE_INCLUDE_DIRS}) +#link_directories(${CAPSTONE_LIBRARY_DIRS}) + +# Build capstone as static library, static runtime (MSVC), and with default allocator. +set(CAPSTONE_BUILD_STATIC OFF CACHE BOOL "") +#set(CAPSTONE_BUILD_STATIC_RUNTIME ON CACHE BOOL "") +#set(CAPSTONE_USE_DEFAULT_ALLOC ON CACHE BOOL "") + +# Turn off anything unnecessary. +set(CAPSTONE_BUILD_SHARED ON CACHE BOOL "") +set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "") +set(CAPSTONE_BUILD_CSTOOL OFF CACHE BOOL "") +set(CAPSTONE_BUILD_DIET OFF CACHE BOOL "") +#set(CAPSTONE_OSXKERNEL_SUPPORT OFF CACHE BOOL "") + +# Disable unused Capstone architectures. +set(CAPSTONE_ARM_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_ARM64_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_MIPS_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_PPC_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_SPARC_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_SYSZ_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_XCORE_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_X86_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_TMS320C64X_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_M680X_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_EVM_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_MOS65XX_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_WASM_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_BPF_SUPPORT OFF CACHE BOOL "") +set(CAPSTONE_RISCV_SUPPORT OFF CACHE BOOL "") + +add_subdirectory(thirdparty/capstone EXCLUDE_FROM_ALL) add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/") add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/") @@ -73,7 +104,7 @@ target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/S cubeb) else() #target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) target_include_directories(dingusppc PRIVATE ${CLI11_ROOT}) endif() @@ -91,7 +122,7 @@ target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL cubeb) else() #target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() file(GLOB BENCH_SOURCES "${PROJECT_SOURCE_DIR}/benchmark/*.cpp") @@ -102,7 +133,7 @@ add_executable(bench1 ${BENCH_SOURCES} $ $ $) -target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) add_custom_command( TARGET testppc POST_BUILD diff --git a/debugger/CMakeLists.txt b/debugger/CMakeLists.txt index 42459a4..acdf045 100644 --- a/debugger/CMakeLists.txt +++ b/debugger/CMakeLists.txt @@ -1,5 +1,7 @@ -include_directories("${PROJECT_SOURCE_DIR}") +include_directories("${PROJECT_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}/thirdparty/capstone/include") file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") -add_library(debugger OBJECT ${SOURCES}) \ No newline at end of file +add_library(debugger OBJECT ${SOURCES}) +target_link_libraries(debugger PRIVATE capstone) diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index b646fba..bf1b4c9 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include #include #include -#include +#include #include "../cpu/ppc/ppcdisasm.h" #include "../cpu/ppc/ppcemu.h" #include "../cpu/ppc/ppcmmu.h" diff --git a/thirdparty/capstone b/thirdparty/capstone new file mode 160000 index 0000000..bfb2e45 --- /dev/null +++ b/thirdparty/capstone @@ -0,0 +1 @@ +Subproject commit bfb2e45d76dd3dda08b40dfad6da94db01bd27ad From df39a591906800e158ae60e6581d4d3b1315dcba Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 3 Dec 2020 01:39:39 +0100 Subject: [PATCH 19/20] Build Capstone as static library. --- CMakeLists.txt | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fdad362..cc5b218 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,18 +16,11 @@ if (UNIX AND NOT APPLE) endif() endif() -#find_package(PkgConfig REQUIRED) -#pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.2) -#include_directories(${CAPSTONE_INCLUDE_DIRS}) -#link_directories(${CAPSTONE_LIBRARY_DIRS}) - -# Build capstone as static library, static runtime (MSVC), and with default allocator. -set(CAPSTONE_BUILD_STATIC OFF CACHE BOOL "") -#set(CAPSTONE_BUILD_STATIC_RUNTIME ON CACHE BOOL "") -#set(CAPSTONE_USE_DEFAULT_ALLOC ON CACHE BOOL "") +# Build capstone as static library. +set(CAPSTONE_BUILD_STATIC ON CACHE BOOL "") # Turn off anything unnecessary. -set(CAPSTONE_BUILD_SHARED ON CACHE BOOL "") +set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "") set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "") set(CAPSTONE_BUILD_CSTOOL OFF CACHE BOOL "") set(CAPSTONE_BUILD_DIET OFF CACHE BOOL "") @@ -101,10 +94,10 @@ add_executable(dingusppc ${SOURCES} $ if (WIN32) target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2.lib" "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2main.lib" - cubeb) + cubeb capstone-static) else() #target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) target_include_directories(dingusppc PRIVATE ${CLI11_ROOT}) endif() @@ -119,10 +112,10 @@ add_executable(testppc ${TEST_SOURCES} $ if (WIN32) target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2.lib" "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2main.lib" - cubeb) + cubeb capstone-static) else() #target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() file(GLOB BENCH_SOURCES "${PROJECT_SOURCE_DIR}/benchmark/*.cpp") @@ -133,7 +126,7 @@ add_executable(bench1 ${BENCH_SOURCES} $ $ $) -target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} capstone-shared ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) add_custom_command( TARGET testppc POST_BUILD From 180cb0d25f701cb4d2524b35311ca93e09321e39 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 3 Dec 2020 02:18:13 +0100 Subject: [PATCH 20/20] Make 68k debugger optional and disabled by default. --- CMakeLists.txt | 78 ++++++++++++++++++++-------------- debugger/CMakeLists.txt | 1 - debugger/debugger.cpp | 92 +++++++++++++++++++++++++---------------- 3 files changed, 104 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc5b218..e5241d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,34 +16,40 @@ if (UNIX AND NOT APPLE) endif() endif() -# Build capstone as static library. -set(CAPSTONE_BUILD_STATIC ON CACHE BOOL "") +option(ENABLE_68K_DEBUGGER "Enable 68k debugging" OFF) -# Turn off anything unnecessary. -set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "") -set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "") -set(CAPSTONE_BUILD_CSTOOL OFF CACHE BOOL "") -set(CAPSTONE_BUILD_DIET OFF CACHE BOOL "") -#set(CAPSTONE_OSXKERNEL_SUPPORT OFF CACHE BOOL "") +if (ENABLE_68K_DEBUGGER) + # Build capstone as static library. + set(CAPSTONE_BUILD_STATIC ON CACHE BOOL "") -# Disable unused Capstone architectures. -set(CAPSTONE_ARM_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_ARM64_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_MIPS_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_PPC_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_SPARC_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_SYSZ_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_XCORE_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_X86_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_TMS320C64X_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_M680X_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_EVM_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_MOS65XX_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_WASM_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_BPF_SUPPORT OFF CACHE BOOL "") -set(CAPSTONE_RISCV_SUPPORT OFF CACHE BOOL "") + # Turn off anything unnecessary. + set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "") + set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "") + set(CAPSTONE_BUILD_CSTOOL OFF CACHE BOOL "") + set(CAPSTONE_BUILD_DIET OFF CACHE BOOL "") + set(CAPSTONE_OSXKERNEL_SUPPORT OFF CACHE BOOL "") -add_subdirectory(thirdparty/capstone EXCLUDE_FROM_ALL) + # Disable unused Capstone architectures. + set(CAPSTONE_ARM_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_ARM64_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_MIPS_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_PPC_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_SPARC_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_SYSZ_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_XCORE_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_X86_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_TMS320C64X_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_M680X_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_EVM_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_MOS65XX_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_WASM_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_BPF_SUPPORT OFF CACHE BOOL "") + set(CAPSTONE_RISCV_SUPPORT OFF CACHE BOOL "") + + ADD_DEFINITIONS(-DENABLE_68K_DEBUGGER) + + add_subdirectory(thirdparty/capstone EXCLUDE_FROM_ALL) +endif() add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/") add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/") @@ -94,13 +100,17 @@ add_executable(dingusppc ${SOURCES} $ if (WIN32) target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2.lib" "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2main.lib" - cubeb capstone-static) + cubeb) else() #target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) target_include_directories(dingusppc PRIVATE ${CLI11_ROOT}) endif() +if (ENABLE_68K_DEBUGGER) + target_link_libraries(dingusppc capstone-static) +endif() + add_executable(testppc ${TEST_SOURCES} $ $ @@ -112,10 +122,14 @@ add_executable(testppc ${TEST_SOURCES} $ if (WIN32) target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2.lib" "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL2main.lib" - cubeb capstone-static) + cubeb) else() #target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES}) -target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif() + +if (ENABLE_68K_DEBUGGER) + target_link_libraries(testppc capstone-static) endif() file(GLOB BENCH_SOURCES "${PROJECT_SOURCE_DIR}/benchmark/*.cpp") @@ -126,7 +140,11 @@ add_executable(bench1 ${BENCH_SOURCES} $ $ $) -target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} capstone-static ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(bench1 cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + +if (ENABLE_68K_DEBUGGER) + target_link_libraries(bench1 capstone-static) +endif() add_custom_command( TARGET testppc POST_BUILD diff --git a/debugger/CMakeLists.txt b/debugger/CMakeLists.txt index acdf045..50d4d11 100644 --- a/debugger/CMakeLists.txt +++ b/debugger/CMakeLists.txt @@ -4,4 +4,3 @@ include_directories("${PROJECT_SOURCE_DIR}" file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") add_library(debugger OBJECT ${SOURCES}) -target_link_libraries(debugger PRIVATE capstone) diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index bf1b4c9..b7abb20 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -27,11 +27,13 @@ along with this program. If not, see . #include #include #include -#include #include "../cpu/ppc/ppcdisasm.h" #include "../cpu/ppc/ppcemu.h" #include "../cpu/ppc/ppcmmu.h" +#ifdef ENABLE_68K_DEBUGGER // optionally defined in CMakeLists.txt + #include +#endif using namespace std; @@ -72,25 +74,16 @@ static void show_help() { cout << " disas N,X -- disassemble N instructions starting at address X" << endl; cout << " X can be any number or a known register name" << endl; cout << " disas with no arguments defaults to disas 1,pc" << endl; +#ifdef ENABLE_68K_DEBUGGER cout << " context X -- switch to the debugging context X." << endl; cout << " X can be either 'ppc' (default) or '68k'" << endl; cout << " Use 68k for debugging emulated 68k code only." << endl; +#endif cout << " quit -- quit the debugger" << endl << endl; cout << "Pressing ENTER will repeat last command." << endl; } -static void disasm(uint32_t count, uint32_t address) { - PPCDisasmContext ctx; - - ctx.instr_addr = address; - ctx.simplified = true; - - for (int i = 0; i < count; i++) { - ctx.instr_code = mem_read_dbg(ctx.instr_addr, 4); - cout << uppercase << hex << ctx.instr_addr; - cout << " " << disassemble_single(&ctx) << endl; - } -} +#ifdef ENABLE_68K_DEBUGGER static void disasm_68k(uint32_t count, uint32_t address) { csh cs_handle; @@ -199,6 +192,35 @@ void exec_until_68k(uint32_t target_addr) } } +void print_68k_regs() +{ + int i; + string reg; + + for (i = 0; i < 8; i++) { + reg = "R" + to_string(i + 8); + cout << "D" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; + } + + for (i = 0; i < 7; i++) { + reg = "R" + to_string(i + 16); + cout << "A" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; + } + reg = "R1"; + cout << "A7 : " << uppercase << hex << get_reg(reg) << endl; + + reg = "R24"; + cout << "PC: " << uppercase << hex << get_reg(reg) - 2 << endl; + + reg = "R25"; + cout << "SR: " << uppercase << hex << ((get_reg(reg) & 0xFF) << 8) << endl; + + reg = "R26"; + cout << "CCR: " << uppercase << hex << get_reg(reg) << endl; +} + +#endif // ENABLE_68K_DEBUGGER + static void dump_mem(string& params) { int cell_size, chars_per_line; bool is_char; @@ -293,31 +315,17 @@ static void dump_mem(string& params) { cout << endl << endl; } -void print_68k_regs() -{ - int i; - string reg; +static void disasm(uint32_t count, uint32_t address) { + PPCDisasmContext ctx; - for (i = 0; i < 8; i++) { - reg = "R" + to_string(i + 8); - cout << "D" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; + ctx.instr_addr = address; + ctx.simplified = true; + + for (int i = 0; i < count; i++) { + ctx.instr_code = mem_read_dbg(ctx.instr_addr, 4); + cout << uppercase << hex << ctx.instr_addr; + cout << " " << disassemble_single(&ctx) << endl; } - - for (i = 0; i < 7; i++) { - reg = "R" + to_string(i + 16); - cout << "A" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl; - } - reg = "R1"; - cout << "A7 : " << uppercase << hex << get_reg(reg) << endl; - - reg = "R24"; - cout << "PC: " << uppercase << hex << get_reg(reg) - 2 << endl; - - reg = "R25"; - cout << "SR: " << uppercase << hex << ((get_reg(reg) & 0xFF) << 8) << endl; - - reg = "R26"; - cout << "CCR: " << uppercase << hex << get_reg(reg) << endl; } void enter_debugger() { @@ -362,7 +370,9 @@ void enter_debugger() { #endif else if (cmd == "regs") { if (context == 2) { +#ifdef ENABLE_68K_DEBUGGER print_68k_regs(); +#endif } else { print_gprs(); } @@ -394,7 +404,9 @@ void enter_debugger() { } } else if (cmd == "step" || cmd == "si") { if (context == 2) { +#ifdef ENABLE_68K_DEBUGGER exec_single_68k(); +#endif } else { ppc_exec_single(); } @@ -407,7 +419,9 @@ void enter_debugger() { try { addr = str2addr(addr_str); if (context == 2) { +#ifdef ENABLE_68K_DEBUGGER exec_until_68k(addr); +#endif } else { ppc_exec_until(addr); } @@ -444,7 +458,9 @@ void enter_debugger() { } try { if (context == 2) { +#ifdef ENABLE_68K_DEBUGGER disasm_68k(inst_grab, addr); +#endif } else { disasm(inst_grab, addr); } @@ -454,9 +470,11 @@ void enter_debugger() { } else { /* disas without arguments defaults to disas 1,pc */ if (context == 2) { +#ifdef ENABLE_68K_DEBUGGER addr_str = "R24"; addr = get_reg(addr_str); disasm_68k(1, addr - 2); +#endif } else { addr_str = "PC"; addr = get_reg(addr_str); @@ -467,6 +485,7 @@ void enter_debugger() { expr_str = ""; ss >> expr_str; dump_mem(expr_str); +#ifdef ENABLE_68K_DEBUGGER } else if (cmd == "context") { expr_str = ""; ss >> expr_str; @@ -477,6 +496,7 @@ void enter_debugger() { } else { cout << "Unknown debugging context: " << expr_str << endl; } +#endif } else { cout << "Unknown command: " << cmd << endl; continue;