From 700683468a362d039644207620ef8e01b0e78419 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 9 Dec 2015 10:25:40 +0100 Subject: [PATCH] Removed dead PPC code (nw) --- scripts/src/cpu.lua | 10 - src/devices/cpu/powerpc/drc_ops.cpp | 3800 --------------------------- src/devices/cpu/powerpc/drc_ops.h | 145 - src/devices/cpu/powerpc/ppc.cpp | 2135 --------------- src/devices/cpu/powerpc/ppc.h | 3 - src/devices/cpu/powerpc/ppc403.inc | 947 ------- src/devices/cpu/powerpc/ppc602.inc | 279 -- src/devices/cpu/powerpc/ppc603.inc | 285 -- src/devices/cpu/powerpc/ppc_mem.inc | 421 --- src/devices/cpu/powerpc/ppc_ops.h | 152 -- src/devices/cpu/powerpc/ppc_ops.inc | 2810 -------------------- 11 files changed, 10987 deletions(-) delete mode 100644 src/devices/cpu/powerpc/drc_ops.cpp delete mode 100644 src/devices/cpu/powerpc/drc_ops.h delete mode 100644 src/devices/cpu/powerpc/ppc.cpp delete mode 100644 src/devices/cpu/powerpc/ppc403.inc delete mode 100644 src/devices/cpu/powerpc/ppc602.inc delete mode 100644 src/devices/cpu/powerpc/ppc603.inc delete mode 100644 src/devices/cpu/powerpc/ppc_mem.inc delete mode 100644 src/devices/cpu/powerpc/ppc_ops.h delete mode 100644 src/devices/cpu/powerpc/ppc_ops.inc diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 985d47c0611..0c2882df5e5 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -1463,17 +1463,7 @@ if (CPUS["POWERPC"]~=null) then MAME_DIR .. "src/devices/cpu/powerpc/ppcfe.cpp", MAME_DIR .. "src/devices/cpu/powerpc/ppcfe.h", MAME_DIR .. "src/devices/cpu/powerpc/ppcdrc.cpp", - - --MAME_DIR .. "src/devices/cpu/powerpc/drc_ops.cpp", - MAME_DIR .. "src/devices/cpu/powerpc/drc_ops.h", - --MAME_DIR .. "src/devices/cpu/powerpc/ppc.cpp", MAME_DIR .. "src/devices/cpu/powerpc/ppc.h", - MAME_DIR .. "src/devices/cpu/powerpc/ppc403.inc", - MAME_DIR .. "src/devices/cpu/powerpc/ppc602.inc", - MAME_DIR .. "src/devices/cpu/powerpc/ppc603.inc", - MAME_DIR .. "src/devices/cpu/powerpc/ppc_mem.inc", - MAME_DIR .. "src/devices/cpu/powerpc/ppc_ops.h", - MAME_DIR .. "src/devices/cpu/powerpc/ppc_ops.inc", } end diff --git a/src/devices/cpu/powerpc/drc_ops.cpp b/src/devices/cpu/powerpc/drc_ops.cpp deleted file mode 100644 index cfe3614fb5a..00000000000 --- a/src/devices/cpu/powerpc/drc_ops.cpp +++ /dev/null @@ -1,3800 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/* PowerPC common opcodes */ - -// it really seems like this should be elsewhere - like maybe the floating point checks can hang out someplace else -#include - -#define USE_SSE2 0 -#define COMPILE_FPU 0 - -/* recompiler flags */ -#define RECOMPILE_UNIMPLEMENTED 0x0000 -#define RECOMPILE_SUCCESSFUL 0x0001 -#define RECOMPILE_SUCCESSFUL_CP(c,p) (RECOMPILE_SUCCESSFUL | (((c) & 0xff) << 16) | (((p) & 0xff) << 24)) -#define RECOMPILE_END_OF_STRING 0x0002 -#define RECOMPILE_ADD_DISPATCH 0x0004 - -INLINE void emit_mov_r64_m64(x86code **emitptr, UINT8 reghi, UINT8 reglo, DECLARE_MEMPARAMS) -{ - emit_mov_r32_m32(emitptr, reglo, MEMPARAMS); - emit_mov_r32_m32(emitptr, reghi, base, index, scale, disp+4); -} - -INLINE void emit_mov_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 reghi, UINT8 reglo) -{ - emit_mov_m32_r32(emitptr, MEMPARAMS, reglo); - emit_mov_m32_r32(emitptr, base, index, scale, disp+4, reghi); -} - - -static UINT32 compile_one(drc_core *drc, UINT32 pc); - -static void append_generate_exception(drc_core *drc, UINT8 exception); -static void append_check_interrupts(drc_core *drc, int inline_generate); -static UINT32 recompile_instruction(drc_core *drc, UINT32 pc, UINT32 *opptr); - -static UINT32 temp_ppc_pc; - -static void ppcdrc_init(void) -{ - drc_config drconfig; - - /* fill in the config */ - memset(&drconfig, 0, sizeof(drconfig)); - drconfig.cache_size = CACHE_SIZE; - drconfig.max_instructions = MAX_INSTRUCTIONS; - drconfig.address_bits = 32; - drconfig.lsbs_to_ignore = 2; - drconfig.uses_fp = 1; - drconfig.uses_sse = USE_SSE2; - drconfig.pc_in_memory = 0; - drconfig.icount_in_memory = 0; - drconfig.pcptr = (UINT32 *)&ppc.pc; - drconfig.icountptr = (UINT32 *)&ppc_icount; - drconfig.esiptr = NULL; - drconfig.cb_reset = CPU_RESET_NAME(ppcdrc); - drconfig.cb_recompile = ppcdrc_recompile; - drconfig.cb_entrygen = ppcdrc_entrygen; - - /* initialize the compiler */ - ppc.drc = drc_init(cpunum_get_active(), &drconfig); - ppc.drcoptions = 0; -} - -static void ppcdrc_reset(drc_core *drc) -{ - code_log_reset(); - - code_log("entry_point:", (x86code *)drc->entry_point, drc->out_of_cycles); - code_log("out_of_cycles:", drc->out_of_cycles, drc->recompile); - code_log("recompile:", drc->recompile, drc->dispatch); - code_log("dispatch:", drc->dispatch, drc->flush); - code_log("flush:", drc->flush, drc->cache_top); - - ppc.invoke_exception_handler = drc->cache_top; - drc_append_restore_volatiles(drc); - emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 4)); - emit_mov_r32_m32(DRCTOP, REG_ESP, MABS(&ppc.host_esp)); - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_jmp_r32(DRCTOP, REG_EAX); - code_log("invoke_exception_handler:", ppc.invoke_exception_handler, drc->cache_top); - - ppc.generate_interrupt_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_IRQ); - code_log("generate_interrupt_exception:", ppc.generate_interrupt_exception, drc->cache_top); - - ppc.generate_syscall_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_SYSTEM_CALL); - code_log("generate_syscall_exception:", ppc.generate_syscall_exception, drc->cache_top); - - ppc.generate_decrementer_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_DECREMENTER); - code_log("generate_decrementer_exception:", ppc.generate_decrementer_exception, drc->cache_top); - - ppc.generate_trap_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_TRAP); - code_log("generate_trap_exception:", ppc.generate_trap_exception, drc->cache_top); - - ppc.generate_dsi_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_DSI); - code_log("generate_dsi_exception:", ppc.generate_dsi_exception, drc->cache_top); - - ppc.generate_isi_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_ISI); - code_log("generate_isi_exception:", ppc.generate_isi_exception, drc->cache_top); - - if (!ppc.is603 && !ppc.is602) - { - ppc.generate_fit_exception = drc->cache_top; - append_generate_exception(drc, EXCEPTION_FIXED_INTERVAL_TIMER); - code_log("generate_fit_exception:", ppc.generate_fit_exception, drc->cache_top); - } -} - -static CPU_EXIT( ppcdrc ) -{ - drc_exit(ppc.drc); -} - -static UINT32 *ppcdrc_getopptr(UINT32 address) -{ - UINT32 *result; - UINT32 offset = 0; - - if (ppc.is603 || ppc.is602) - { - if (MSR & MSR_IR) - { - if (!ppc_translate_address(&address, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION)) - return NULL; - } - address = DWORD_XOR_BE(address); - offset = (address & 0x07) / sizeof(*result); - address &= ~0x07; - } - - result = (UINT32 *) memory_decrypted_read_ptr(ppc.core->program, address); - if (result) - result += offset; - return result; -} - -static void ppcdrc_recompile(drc_core *drc) -{ - int remaining = MAX_INSTRUCTIONS; - x86code *start = drc->cache_top; - UINT32 pc = ppc.pc; - UINT32 *opptr; - - (void)start; - - /* begin the sequence */ - drc_begin_sequence(drc, pc); - code_log_reset(); - - /* loose verification case: one verification here only */ - if (!(ppc.drcoptions & PPCDRC_OPTIONS_CHECK_SELFMOD_CODE)) - { - opptr = ppcdrc_getopptr(pc); - if (opptr) - drc_append_verify_code(drc, opptr, 4); - } - - /* loop until we hit an unconditional branch */ - while (--remaining != 0) - { - UINT32 result; - - /* compile one instruction */ - result = compile_one(drc, pc); - pc += (INT8)(result >> 24); - if (result & RECOMPILE_END_OF_STRING) - break; - - /* do not recompile across MMU page boundaries */ - if ((pc & 0x0FFF) == 0) - { - remaining = 0; - break; - } - } - - /* add dispatcher just in case */ - if (remaining == 0) - drc_append_dispatcher(drc); - - /* end the sequence */ - drc_end_sequence(drc); - -if (0) -{ - char label[40]; - sprintf(label, "Code @ %08X", ppc.pc); - code_log(label, start, drc->cache_top); -} -} - -static void update_counters(drc_core *drc) -{ - emit_link link1; - - /* decrementer */ - if (ppc.is603 || ppc.is602) - { - emit_cmp_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_dec_trigger_cycle)); - emit_jcc_short_link(DRCTOP, COND_NZ, &link1); - emit_or_m32_imm(DRCTOP, MABS(&ppc.exception_pending), 0x2); - resolve_link(DRCTOP, &link1); - } - - /* FIT */ - if (!ppc.is603 && !ppc.is602) - { - emit_link link2; - emit_cmp_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_fit_trigger_cycle)); - emit_jcc_short_link(DRCTOP, COND_NZ, &link1); - emit_cmp_r32_m32(DRCTOP, REG_EBP, MABS(&ppc.fit_int_enable)); - emit_jcc_short_link(DRCTOP, COND_Z, &link2); - emit_or_m32_imm(DRCTOP, MABS(&ppc.exception_pending), 0x4); - resolve_link(DRCTOP, &link1); - resolve_link(DRCTOP, &link2); - } -} - -static void ppcdrc_entrygen(drc_core *drc) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc.host_esp), REG_ESP); - append_check_interrupts(drc, 0); -} - -static UINT32 compile_one(drc_core *drc, UINT32 pc) -{ - int pcdelta, cycles; - UINT32 *opptr; - UINT32 result; - - /* register this instruction */ - drc_register_code_at_cache_top(drc, pc); - - /* get a pointer to the current instruction */ - opptr = ppcdrc_getopptr(pc); - - //log_symbol(drc, ~2); - //log_symbol(drc, pc); - - /* emit debugging call */ - drc_append_call_debugger(drc); - - /* null opptr? if legit, we need to generate an ISI exception */ - if (!opptr) - { - /* first check to see if the code is up to date; if not, recompile */ - emit_push_imm(DRCTOP, pc); - emit_call(DRCTOP, (x86code *)ppcdrc_getopptr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_cmp_r32_imm(DRCTOP, REG_EAX, 0); - emit_jcc(DRCTOP, COND_NZ, drc->recompile); - - /* code is up to date; do the exception */ - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.generate_isi_exception)); - emit_jmp_r32(DRCTOP, REG_EAX); - return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING; - } - - /* emit self-modifying code checks */ - if (ppc.drcoptions & PPCDRC_OPTIONS_CHECK_SELFMOD_CODE) - { - drc_append_verify_code(drc, opptr, 4); - } - - /* compile the instruction */ - result = recompile_instruction(drc, pc, opptr); - - /* handle the results */ - if (!(result & RECOMPILE_SUCCESSFUL)) - fatalerror("Unimplemented op %08X\n", *opptr); - - pcdelta = (INT8)(result >> 24); - cycles = (INT8)(result >> 16); - - /* epilogue */ - update_counters(drc); - drc_append_standard_epilogue(drc, cycles, pcdelta, 1); - - if (result & RECOMPILE_ADD_DISPATCH) - drc_append_dispatcher(drc); - - return (result & 0xffff) | ((UINT8)cycles << 16) | ((UINT8)pcdelta << 24); -} - -static UINT32 recompile_instruction(drc_core *drc, UINT32 pc, UINT32 *opptr) -{ - UINT32 opcode; - temp_ppc_pc = pc; - - opcode = *opptr; - - code_log_add_entry(pc, opcode, drc->cache_top); - - if (opcode != 0) { // this is a little workaround for VF3 - switch(opcode >> 26) - { - case 19: return ppc.optable19[(opcode >> 1) & 0x3ff](drc, opcode); - case 31: return ppc.optable31[(opcode >> 1) & 0x3ff](drc, opcode); - case 59: return ppc.optable59[(opcode >> 1) & 0x3ff](drc, opcode); - case 63: return ppc.optable63[(opcode >> 1) & 0x3ff](drc, opcode); - default: return ppc.optable[opcode >> 26](drc, opcode); - } - } - return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING; -} - - -static const UINT32 exception_vector[32] = -{ - 0x0000, 0x0500, 0x0900, 0x0700, 0x0c00, 0x1400, 0x0300, 0x0400, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1010, 0x1020 -}; - -static void append_generate_exception(drc_core *drc, UINT8 exception) -{ - emit_link link1, link2, link3; - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.msr)); - emit_and_r32_imm(DRCTOP, REG_EAX, 0xff73); - emit_mov_m32_r32(DRCTOP, MABS(&SRR1), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.msr)); - - // Clear POW, EE, PR, FP, FE0, SE, BE, FE1, IR, DR, RI - emit_and_r32_imm(DRCTOP, REG_EAX, ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI)); - // Set LE to ILE - emit_and_r32_imm(DRCTOP, REG_EAX, ~MSR_LE); // clear LE first - emit_test_r32_imm(DRCTOP, REG_EAX, MSR_ILE); - emit_jcc_short_link(DRCTOP, COND_Z, &link1); // if Z == 0, bit == 1 - emit_or_r32_imm(DRCTOP, REG_EAX, MSR_LE); // set LE - resolve_link(DRCTOP, &link1); - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)ppc_set_msr); - emit_pop_r32(DRCTOP, REG_EDX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - if (ppc.is603) - { - emit_mov_r32_imm(DRCTOP, REG_EDI, exception_vector[exception]); // first move the exception handler offset - emit_test_r32_imm(DRCTOP, REG_EDX, MSR_IP); // test if the base should be 0xfff0 or EVPR - emit_jcc_short_link(DRCTOP, COND_Z, &link2); // if Z == 1, bit == 0 means base == 0x00000000 - emit_or_r32_imm(DRCTOP, REG_EDI, 0xfff00000); // else base == 0xfff00000 - resolve_link(DRCTOP, &link2); - } - else if (ppc.is602) - { - emit_mov_r32_imm(DRCTOP, REG_EDI, exception_vector[exception]); // first move the exception handler offset - emit_test_r32_imm(DRCTOP, REG_EDX, MSR_IP); // test if the base should be 0xfff0 or IBR - emit_jcc_short_link(DRCTOP, COND_NZ, &link2); // if Z == 0, bit == 1 means base == 0xfff00000 - emit_or_r32_m32(DRCTOP, REG_EDI, MABS(&ppc.ibr)); // else base == IBR - emit_jmp_short_link(DRCTOP, &link3); - resolve_link(DRCTOP, &link2); - emit_or_r32_imm(DRCTOP, REG_EDI, 0xfff00000); - resolve_link(DRCTOP, &link3); - } - else - { - emit_mov_r32_imm(DRCTOP, REG_EDI, exception_vector[exception]); // first move the exception handler offset - emit_test_r32_imm(DRCTOP, REG_EDX, MSR_IP); // test if the base should be 0xfff0 or EVPR - emit_jcc_short_link(DRCTOP, COND_NZ, &link2); // if Z == 0, bit == 1 means base == 0xfff00000 - emit_or_r32_m32(DRCTOP, REG_EDI, MABS(&EVPR)); // else base == EVPR - emit_jmp_short_link(DRCTOP, &link3); - resolve_link(DRCTOP, &link2); - emit_or_r32_imm(DRCTOP, REG_EDI, 0xfff00000); - resolve_link(DRCTOP, &link3); - } - - if (exception == EXCEPTION_IRQ) - { - emit_and_m32_imm(DRCTOP, MABS(&ppc.exception_pending), ~0x1); // clear pending irq - } - if (exception == EXCEPTION_DECREMENTER) - { - emit_and_m32_imm(DRCTOP, MABS(&ppc.exception_pending), ~0x2); // clear pending decrementer exception - } - if (exception == EXCEPTION_FIXED_INTERVAL_TIMER) - { - emit_and_m32_imm(DRCTOP, MABS(&ppc.exception_pending), ~0x4); // clear pending fit exception - } - - drc_append_dispatcher(drc); -} - -static void append_check_interrupts(drc_core *drc, int inline_generate) -{ - if (ppc.is602 || ppc.is603) - { - emit_link link1, link2, link3, link4; - emit_test_m32_imm(DRCTOP, MABS(&ppc.msr), MSR_EE); /* no interrupt if external interrupts are not enabled */ - emit_jcc_short_link(DRCTOP, COND_Z, &link1); /* ZF = 1 if bit == 0 */ - - /* else check if any interrupt are pending */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.exception_pending)); - emit_cmp_r32_imm(DRCTOP, REG_EAX, 0); - emit_jcc_short_link(DRCTOP, COND_Z, &link2); /* reg == 0, no exceptions are pending */ - - /* else handle the first pending exception */ - emit_test_r32_imm(DRCTOP, REG_EAX, 0x1); /* is it a IRQ? */ - emit_jcc_short_link(DRCTOP, COND_Z, &link3); - - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.generate_interrupt_exception)); - emit_jmp_r32(DRCTOP, REG_EAX); - resolve_link(DRCTOP, &link3); - - emit_test_r32_imm(DRCTOP, REG_EAX, 0x2); /* is it a decrementer exception */ - emit_jcc_short_link(DRCTOP, COND_Z, &link4); - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.generate_decrementer_exception)); - emit_jmp_r32(DRCTOP, REG_EAX); - resolve_link(DRCTOP, &link4); - - resolve_link(DRCTOP, &link1); - resolve_link(DRCTOP, &link2); - } - else - { - emit_link link1, link2, link3, link4, link5, link6; - emit_test_m32_imm(DRCTOP, MABS(&ppc.msr), MSR_EE); /* no interrupt if external interrupts are not enabled */ - emit_jcc_short_link(DRCTOP, COND_Z, &link1); /* ZF = 1 if bit == 0 */ - - /* else check if any interrupt are pending */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.exception_pending)); - emit_cmp_r32_imm(DRCTOP, REG_EAX, 0); - emit_jcc_short_link(DRCTOP, COND_Z, &link2); /* reg == 0, no exceptions are pending */ - - /* else handle the first pending exception */ - emit_test_r32_imm(DRCTOP, REG_EAX, 0x1); /* is it a IRQ? */ - emit_jcc_short_link(DRCTOP, COND_Z, &link3); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.exisr)); - emit_and_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.exier)); - emit_cmp_r32_imm(DRCTOP, REG_EAX, 0); - emit_jcc_short_link(DRCTOP, COND_Z, &link4); - - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.generate_interrupt_exception)); - emit_jmp_r32(DRCTOP, REG_EAX); - - /* check if it's FIT exception */ - resolve_link(DRCTOP, &link3); - emit_test_r32_imm(DRCTOP, REG_EAX, 0x4); - emit_jcc_short_link(DRCTOP, COND_Z, &link5); - - // check if FIT interrupts are enabled - emit_test_m32_imm(DRCTOP, MABS(&ppc.fit_int_enable), 0x1); - emit_jcc_short_link(DRCTOP, COND_Z, &link6); - - // calculate the next trigger cycle for FIT - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc_fit_trigger_cycle)); - emit_sub_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.fit_bit)); - emit_mov_m32_r32(DRCTOP, MABS(&ppc_fit_trigger_cycle), REG_EAX); - - emit_mov_m32_r32(DRCTOP, MABS(&SRR0), REG_EDI); /* save return address */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.generate_fit_exception)); - emit_jmp_r32(DRCTOP, REG_EAX); - - resolve_link(DRCTOP, &link1); - resolve_link(DRCTOP, &link2); - resolve_link(DRCTOP, &link4); - resolve_link(DRCTOP, &link5); - resolve_link(DRCTOP, &link6); - } -} - -static void append_branch_or_dispatch(drc_core *drc, UINT32 newpc, int cycles) -{ - void *code = drc_get_code_at_pc(drc, newpc); - emit_mov_r32_imm(DRCTOP, REG_EDI, newpc); - - update_counters(drc); - append_check_interrupts(drc, 0); - - drc_append_standard_epilogue(drc, cycles, 0, 1); - - - if (code) - emit_jmp(DRCTOP, code); - else - drc_append_tentative_fixed_dispatcher(drc, newpc); -} - -/* -// this table translates x86 SF and ZF flags to PPC CR values -static const UINT8 condition_table[4] = -{ - 0x4, // x86 SF == 0, ZF == 0 --> PPC GT (positive) - 0x2, // x86 SF == 0, ZF == 1 --> PPC EQ (zero) - 0x8, // x86 SF == 1, ZF == 0 --> PPC LT (negative) - 0x0, // x86 SF == 1, ZF == 1 (impossible) -}; -*/ - -// expects the result value in EDX!!! -static void append_set_cr0(drc_core *drc) -{ - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_cmp_r32_imm(DRCTOP, REG_EDX, 0); -/* - _lahf(); - - _shr_r32_imm(REG_EAX, 14); - - _add_r32_imm(REG_EAX, &condition_table); - _mov_r8_m8bd(REG_BL, REG_EAX, 0); -*/ - emit_setcc_r8(DRCTOP, COND_Z, REG_AL); - emit_setcc_r8(DRCTOP, COND_L, REG_AH); - emit_setcc_r8(DRCTOP, COND_G, REG_BL); - emit_shl_r8_imm(DRCTOP, REG_AL, 1); - emit_shl_r8_imm(DRCTOP, REG_AH, 3); - emit_shl_r8_imm(DRCTOP, REG_BL, 2); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AH); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AL); - - emit_bt_m32_imm(DRCTOP, MABS(&XER), 31); // set XER SO bit to carry - emit_adc_r32_imm(DRCTOP, REG_EBX, 0); // effectively sets bit 0 to carry - - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[0]), REG_BL); -} - -#ifdef UNUSED_FUNCTION -static void append_set_cr1(drc_core *drc) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.fpscr)); - emit_shr_r32_imm(DRCTOP, REG_EAX, 28); - emit_and_r32_imm(DRCTOP, REG_EAX, 0xf); - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[1]), REG_AL); -} -#endif - -static UINT32 recompile_addx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (OEBIT) { - osd_printf_debug("recompile_addx: OE bit set !\n"); - return RECOMPILE_UNIMPLEMENTED; - } - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addcx(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - emit_setcc_r8(DRCTOP, COND_C, REG_AL); // carry to AL - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // shift to carry bit - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - if (OEBIT) { - osd_printf_debug("recompile_addcx: OE bit set !\n"); - return RECOMPILE_UNIMPLEMENTED; - } - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_addex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addi(drc_core *drc, UINT32 op) -{ - if (RA == 0) - { - emit_mov_m32_imm(DRCTOP, MABS(®(RT)), SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addic(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry bit - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - emit_setcc_r8(DRCTOP, COND_C, REG_AL); // carry to AL - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // shift to carry bit - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addic_rc(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry bit - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - emit_setcc_r8(DRCTOP, COND_C, REG_AL); // carry to AL - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // shift to carry bit - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - append_set_cr0(drc); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addis(drc_core *drc, UINT32 op) -{ - if (RA == 0) - { - emit_mov_m32_imm(DRCTOP, MABS(®(RT)), UIMM16 << 16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, UIMM16 << 16); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addmex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_addmex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_addzex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_addzex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_andx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_and_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_andcx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - emit_not_r32(DRCTOP, REG_EAX); - emit_and_r32_r32(DRCTOP, REG_EDX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_andi_rc(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_and_r32_imm(DRCTOP, REG_EDX, UIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - append_set_cr0(drc); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_andis_rc(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_and_r32_imm(DRCTOP, REG_EDX, UIMM16 << 16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - append_set_cr0(drc); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_bx(drc_core *drc, UINT32 op) -{ - UINT32 newpc; - INT32 li = op & 0x3fffffc; - if( li & 0x2000000 ) - li |= 0xfc000000; - - if( AABIT ) { - newpc = li; - } else { - newpc = temp_ppc_pc + li; - } - - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - - append_branch_or_dispatch(drc, newpc, 1); - - return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING; -} - -static UINT32 recompile_bcx(drc_core *drc, UINT32 op) -{ - emit_link link1 = {0}, link2 = {0}; - int do_link1 = 0, do_link2 = 0; - UINT32 newpc; - - if( AABIT ) { - newpc = SIMM16 & ~0x3; - } else { - newpc = temp_ppc_pc + (SIMM16 & ~0x3); - } - - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - - if (BO == 20) /* condition is always true, so the basic block ends here */ - { - append_branch_or_dispatch(drc, newpc, 1); - - return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING; - } - else - { - // if BO[2] == 0, update CTR and check CTR condition - if ((BO & 0x4) == 0) - { - do_link1 = 1; - //_dec_m32abs(&CTR); - emit_sub_m32_imm(DRCTOP, MABS(&CTR), 1); - - // if BO[1] == 0, branch if CTR != 0 - if ((BO & 0x2) == 0) - { - emit_jcc_near_link(DRCTOP, COND_Z, &link1); - } - else - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link1); - } - } - - // if BO[0] == 0, check condition - if ((BO & 0x10) == 0) - { - do_link2 = 1; - emit_movzx_r32_m8(DRCTOP, REG_EAX, MABS(&ppc.cr[(BI)/4])); - emit_test_r32_imm(DRCTOP, REG_EAX, 1 << (3 - ((BI) & 0x3))); // test if condition register bit is set - - // if BO[3] == 0, branch if condition == FALSE (bit zero) - if ((BO & 0x8) == 0) - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link2); // bit not zero, skip branch - } - // if BO[3] == 1, branch if condition == TRUE (bit not zero) - else - { - emit_jcc_near_link(DRCTOP, COND_Z, &link2); // bit zero, skip branch - } - } - - // take the branch - append_branch_or_dispatch(drc, newpc, 1); - - // skip the branch - if (do_link1) { - resolve_link(DRCTOP, &link1); - } - if (do_link2) { - resolve_link(DRCTOP, &link2); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); - } -} - -static UINT32 recompile_bcctrx(drc_core *drc, UINT32 op) -{ - emit_link link1 = {0} ,link2 = {0}; - int do_link1 = 0, do_link2 = 0; - - if (BO == 20) /* condition is always true, so the basic block ends here */ - { - emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&CTR)); // mov edi, CTR - - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - return RECOMPILE_SUCCESSFUL_CP(1,0) | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH; - } - else - { - // if BO[2] == 0, update CTR and check CTR condition - if ((BO & 0x4) == 0) - { - do_link1 = 1; - //_dec_m32abs(&CTR); - emit_sub_m32_imm(DRCTOP, MABS(&CTR), 1); - - // if BO[1] == 0, branch if CTR != 0 - if ((BO & 0x2) == 0) - { - emit_jcc_near_link(DRCTOP, COND_Z, &link1); - } - else - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link1); - } - } - - // if BO[0] == 0, check condition - if ((BO & 0x10) == 0) - { - do_link2 = 1; - emit_movzx_r32_m8(DRCTOP, REG_EAX, MABS(&ppc.cr[(BI)/4])); - emit_test_r32_imm(DRCTOP, REG_EAX, 1 << (3 - ((BI) & 0x3))); // test if condition register bit is set - - // if BO[3] == 0, branch if condition == FALSE (bit zero) - if ((BO & 0x8) == 0) - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link2); // bit not zero, skip branch - } - // if BO[3] == 1, branch if condition == TRUE (bit not zero) - else - { - emit_jcc_near_link(DRCTOP, COND_Z, &link2); // bit zero, skip branch - } - } - - // take the branch - emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&CTR)); // mov edi, CTR - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - append_check_interrupts(drc, 0); - drc_append_standard_epilogue(drc, 1, 0, 1); - drc_append_dispatcher(drc); - - // skip the branch - if (do_link1) { - resolve_link(DRCTOP, &link1); - } - if (do_link2) { - resolve_link(DRCTOP, &link2); - } - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); - } -} - -static UINT32 recompile_bclrx(drc_core *drc, UINT32 op) -{ - emit_link link1 = {0}, link2 = {0}; - int do_link1 = 0, do_link2 = 0; - - if (BO == 20) /* condition is always true, so the basic block ends here */ - { - emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&LR)); // mov edi, LR - - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - return RECOMPILE_SUCCESSFUL_CP(1,0) | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH; - } - else - { - // if BO[2] == 0, update CTR and check CTR condition - if ((BO & 0x4) == 0) - { - do_link1 = 1; - //_dec_m32abs(&CTR); - emit_sub_m32_imm(DRCTOP, MABS(&CTR), 1); - - // if BO[1] == 0, branch if CTR != 0 - if ((BO & 0x2) == 0) - { - emit_jcc_near_link(DRCTOP, COND_Z, &link1); - } - else - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link1); - } - } - - // if BO[0] == 0, check condition - if ((BO & 0x10) == 0) - { - do_link2 = 1; - emit_movzx_r32_m8(DRCTOP, REG_EAX, MABS(&ppc.cr[(BI)/4])); - emit_test_r32_imm(DRCTOP, REG_EAX, 1 << (3 - ((BI) & 0x3))); // test if condition register bit is set - - // if BO[3] == 0, branch if condition == FALSE (bit zero) - if ((BO & 0x8) == 0) - { - emit_jcc_near_link(DRCTOP, COND_NZ, &link2); // bit not zero, skip branch - } - // if BO[3] == 1, branch if condition == TRUE (bit not zero) - else - { - emit_jcc_near_link(DRCTOP, COND_Z, &link2); // bit zero, skip branch - } - } - - // take the branch - emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&LR)); // mov edi, LR - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - append_check_interrupts(drc, 0); - drc_append_standard_epilogue(drc, 1, 0, 1); - drc_append_dispatcher(drc); - - // skip the branch - if (do_link1) { - resolve_link(DRCTOP, &link1); - } - if (do_link2) { - resolve_link(DRCTOP, &link2); - } - if( LKBIT ) { - emit_mov_m32_imm(DRCTOP, MABS(&LR), temp_ppc_pc + 4); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); - } -} - -static UINT32 recompile_cmp(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RA))); - emit_cmp_r32_m32(DRCTOP, REG_ECX, MABS(®(RB))); - - emit_setcc_r8(DRCTOP, COND_Z, REG_AL); - emit_setcc_r8(DRCTOP, COND_L, REG_AH); - emit_setcc_r8(DRCTOP, COND_G, REG_BL); - emit_shl_r8_imm(DRCTOP, REG_AL, 1); - emit_shl_r8_imm(DRCTOP, REG_AH, 3); - emit_shl_r8_imm(DRCTOP, REG_BL, 2); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AH); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AL); - - emit_bt_m32_imm(DRCTOP, MABS(&XER), 31); // set XER SO bit to carry - emit_adc_r32_imm(DRCTOP, REG_EBX, 0); // effectively sets bit 0 to carry - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[CRFD]), REG_BL); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_cmpi(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RA))); - emit_cmp_r32_imm(DRCTOP, REG_ECX, SIMM16); - - emit_setcc_r8(DRCTOP, COND_Z, REG_AL); - emit_setcc_r8(DRCTOP, COND_L, REG_AH); - emit_setcc_r8(DRCTOP, COND_G, REG_BL); - emit_shl_r8_imm(DRCTOP, REG_AL, 1); - emit_shl_r8_imm(DRCTOP, REG_AH, 3); - emit_shl_r8_imm(DRCTOP, REG_BL, 2); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AH); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AL); - - emit_bt_m32_imm(DRCTOP, MABS(&XER), 31); // set XER SO bit to carry - emit_adc_r32_imm(DRCTOP, REG_EBX, 0); // effectively sets bit 0 to carry - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[CRFD]), REG_BL); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_cmpl(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RA))); - emit_cmp_r32_m32(DRCTOP, REG_ECX, MABS(®(RB))); - - emit_setcc_r8(DRCTOP, COND_Z, REG_AL); - emit_setcc_r8(DRCTOP, COND_B, REG_AH); - emit_setcc_r8(DRCTOP, COND_A, REG_BL); - emit_shl_r8_imm(DRCTOP, REG_AL, 1); - emit_shl_r8_imm(DRCTOP, REG_AH, 3); - emit_shl_r8_imm(DRCTOP, REG_BL, 2); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AH); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AL); - - emit_bt_m32_imm(DRCTOP, MABS(&XER), 31); // set XER SO bit to carry - emit_adc_r32_imm(DRCTOP, REG_EBX, 0); // effectively sets bit 0 to carry - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[CRFD]), REG_BL); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_cmpli(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RA))); - emit_cmp_r32_imm(DRCTOP, REG_ECX, UIMM16); - - emit_setcc_r8(DRCTOP, COND_Z, REG_AL); - emit_setcc_r8(DRCTOP, COND_B, REG_AH); - emit_setcc_r8(DRCTOP, COND_A, REG_BL); - emit_shl_r8_imm(DRCTOP, REG_AL, 1); - emit_shl_r8_imm(DRCTOP, REG_AH, 3); - emit_shl_r8_imm(DRCTOP, REG_BL, 2); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AH); - emit_or_r8_r8(DRCTOP, REG_BL, REG_AL); - - emit_bt_m32_imm(DRCTOP, MABS(&XER), 31); // set XER SO bit to carry - emit_adc_r32_imm(DRCTOP, REG_EBX, 0); // effectively sets bit 0 to carry - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[CRFD]), REG_BL); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_cntlzw(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX); - emit_mov_r32_imm(DRCTOP, REG_EDX, 31); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RT))); - emit_bsr_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_setcc_r8(DRCTOP, COND_Z, REG_BL); // if all zeros, set BL to 1, so result becomes 32 - emit_sub_r32_r32(DRCTOP, REG_EDX, REG_EAX); - emit_add_r32_r32(DRCTOP, REG_EDX, REG_EBX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crand(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crand); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crandc(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crandc); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_creqv(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_creqv); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crnand(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crnand); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crnor(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crnor); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_cror(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_cror); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crorc(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crorc); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_crxor(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_crxor); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbf(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbi(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbst(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbt(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbtst(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcbz(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_divwx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_divwx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_divwux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_divwux); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_eieio(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_eqvx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_xor_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_not_r32(DRCTOP, REG_EDX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_extsbx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_movsx_r32_r8(DRCTOP, REG_EDX, REG_DL); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_extshx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_movsx_r32_r16(DRCTOP, REG_EDX, REG_DX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_icbi(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_isync(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lbz(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)READ8); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lbzu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ8); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lbzux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ8); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lbzx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ8); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lha(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movsx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhau(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movsx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhaux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movsx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhax(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movsx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhbrx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_imm(DRCTOP, REG_ECX, 8); - emit_rol_r16_cl(DRCTOP, REG_AX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhz(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhzu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhzux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lhzx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ16); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lmw(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lmw); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lswi(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lswi); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lswx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lswx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwarx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lwarx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwbrx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_bswap_r32(DRCTOP, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwz(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwzu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwzux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lwzx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mcrf(drc_core *drc, UINT32 op) -{ - emit_mov_r8_m8(DRCTOP, REG_AL, MABS(&ppc.cr[RA >> 2])); - emit_mov_m8_r8(DRCTOP, MABS(&ppc.cr[RT >> 2]), REG_AL); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mcrxr(drc_core *drc, UINT32 op) -{ - osd_printf_debug("PPCDRC: recompile mcrxr\n"); - return RECOMPILE_UNIMPLEMENTED; -} - -static UINT32 recompile_mfcr(drc_core *drc, UINT32 op) -{ - int i; - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - - // generate code for each condition register - for (i=0; i < 8; i++) - { - emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX); - emit_mov_r8_m8(DRCTOP, REG_DL, MABS(&ppc.cr[i])); - emit_shl_r32_imm(DRCTOP, REG_EDX, ((7-i) * 4)); - emit_or_r32_r32(DRCTOP, REG_EAX, REG_EDX); - } - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mfmsr(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.msr)); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mfspr(drc_core *drc, UINT32 op) -{ - if (SPR == SPR_LR) // optimized case, LR - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&LR)); - } - else if(SPR == SPR_CTR) // optimized case, CTR - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&CTR)); - } - else - { - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, SPR); - emit_call(DRCTOP, (x86code *)ppc_get_spr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - } - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtcrf(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtcrf); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtmsr(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)ppc_set_msr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtspr(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - if (SPR == SPR_LR) // optimized case, LR - { - emit_mov_m32_r32(DRCTOP, MABS(&LR), REG_EAX); - } - else if(SPR == SPR_CTR) // optimized case, CTR - { - emit_mov_m32_r32(DRCTOP, MABS(&CTR), REG_EAX); - } - else - { - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_r32(DRCTOP, REG_EAX); - emit_push_imm(DRCTOP, SPR); - emit_call(DRCTOP, (x86code *)ppc_set_spr); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mulhwx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(®(RB))); - emit_imul_r32(DRCTOP, REG_EBX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mulhwux(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(®(RB))); - emit_mul_r32(DRCTOP, REG_EBX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mulli(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_imm(DRCTOP, REG_EBX, SIMM16); - emit_imul_r32(DRCTOP, REG_EBX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mullwx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(®(RB))); - emit_mul_r32(DRCTOP, REG_EBX); - emit_mov_r32_r32(DRCTOP, REG_EDX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (OEBIT) { - osd_printf_debug("recompile_mullwx: OEBIT set!\n"); - return RECOMPILE_UNIMPLEMENTED; - } - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_nandx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_and_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_not_r32(DRCTOP, REG_EDX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_negx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_neg_r32(DRCTOP, REG_EDX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_norx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_or_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_not_r32(DRCTOP, REG_EDX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_orx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_or_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_orcx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_not_r32(DRCTOP, REG_EDX); - emit_or_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_ori(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_or_r32_imm(DRCTOP, REG_EAX, UIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_oris(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_or_r32_imm(DRCTOP, REG_EAX, UIMM16 << 16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_rfi(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&ppc.srr0)); /* get saved PC from SRR0 */ - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&ppc.srr1)); /* get saved MSR from SRR1 */ - - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)ppc_set_msr); /* set MSR */ - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,0) | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH; -} - -static UINT32 recompile_rlwimix(drc_core *drc, UINT32 op) -{ - UINT32 mask = GET_ROTATE_MASK(MB, ME); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_rol_r32_imm(DRCTOP, REG_EDX, (SH)); - emit_and_r32_imm(DRCTOP, REG_EDX, mask); - emit_and_r32_imm(DRCTOP, REG_EAX, ~mask); - emit_or_r32_r32(DRCTOP, REG_EDX, REG_EAX); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_rlwinmx(drc_core *drc, UINT32 op) -{ - UINT32 mask = GET_ROTATE_MASK(MB, ME); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_rol_r32_imm(DRCTOP, REG_EDX, (SH)); - emit_and_r32_imm(DRCTOP, REG_EDX, mask); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_rlwnmx(drc_core *drc, UINT32 op) -{ - UINT32 mask = GET_ROTATE_MASK(MB, ME); - - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RB))); // x86 rotate instruction use only 5 bits, so no need to mask this - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_rol_r32_cl(DRCTOP, REG_EDX); - emit_and_r32_imm(DRCTOP, REG_EDX, mask); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sc(drc_core *drc, UINT32 op) -{ - emit_mov_m32_imm(DRCTOP, MABS(&SRR0), temp_ppc_pc + 4); - emit_jmp(DRCTOP, ppc.generate_syscall_exception); - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_slwx(drc_core *drc, UINT32 op) -{ -#if USE_SSE2 - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RB))); - emit_and_r32_imm(DRCTOP, REG_ECX, 0x3f); - emit_movd_r128_m32(DRCTOP, REG_XMM0, MABS(®(RS))); - emit_movd_r128_r32(DRCTOP, REG_XMM1, REG_ECX); - emit_psllq_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movd_r32_r128(DRCTOP, REG_EDX, REG_XMM0); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } -#else - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_slwx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_srawx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_srawx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_srawix(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_srawix); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_srwx(drc_core *drc, UINT32 op) -{ -#if USE_SSE2 - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RB))); - emit_and_r32_imm(DRCTOP, REG_ECX, 0x3f); - emit_movd_r128_m32(DRCTOP, REG_XMM0, MABS(®(RS))); - emit_movd_r128_r32(DRCTOP, REG_XMM1, REG_ECX); - emit_psrlq_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movd_r32_r128(DRCTOP, REG_EDX, REG_XMM0); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } -#else - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_srwx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stb(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_push_r32(DRCTOP, REG_EAX); - - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)WRITE8); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stbu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE8); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stbux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE8); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stbx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE8); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sth(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_push_r32(DRCTOP, REG_EAX); - - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_push_r32(DRCTOP, REG_EDX); - } - emit_call(DRCTOP, (x86code *)WRITE16); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sthbrx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_mov_r32_imm(DRCTOP, REG_ECX, 8); - emit_rol_r16_cl(DRCTOP, REG_AX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE16); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sthu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE16); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sthux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE16); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sthx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE16); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stmw(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stmw); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stswi(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stswi); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stswx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stswx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stw(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_m32(DRCTOP, MABS(®(RS))); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stwbrx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RS))); - emit_bswap_r32(DRCTOP, REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stwcx_rc(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stwcx_rc); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stwu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_m32(DRCTOP, MABS(®(RS))); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stwux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_m32(DRCTOP, MABS(®(RS))); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stwx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_m32(DRCTOP, MABS(®(RS))); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_sub_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - - if (OEBIT) { - osd_printf_debug("recompile_subfx: OEBIT set !\n"); - return RECOMPILE_UNIMPLEMENTED; - } - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfcx(drc_core *drc, UINT32 op) -{ - if (OEBIT) - { - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_subfcx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - } - else - { - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_sub_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - emit_setcc_r8(DRCTOP, COND_NC, REG_AL); // subtract carry is inverse - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // move carry to correct location in XER - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); // insert carry to XER - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - //if (OEBIT) { - // osd_printf_debug("recompile_subfcx: OEBIT set !\n"); - // return RECOMPILE_UNIMPLEMENTED; - //} - if (RCBIT) { - append_set_cr0(drc); - } - } - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfex(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_r32_m32(DRCTOP, REG_ECX, MABS(®(RA))); - emit_bt_r32_imm(DRCTOP, REG_EBX, 29); // XER carry to carry flag - emit_cmc(DRCTOP); // invert carry - emit_adc_r32_imm(DRCTOP, REG_ECX, 0); - emit_sub_r32_r32(DRCTOP, REG_EDX, REG_ECX); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - emit_setcc_r8(DRCTOP, COND_NC, REG_AL); // subtract carry is inverse - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // move carry to correct location in XER - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); // insert carry to XER - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - if (OEBIT) { - osd_printf_debug("recompile_subfex: OEBIT set !\n"); - return RECOMPILE_UNIMPLEMENTED; - } - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfic(drc_core *drc, UINT32 op) -{ - emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBX, MABS(&XER)); - emit_and_r32_imm(DRCTOP, REG_EBX, ~0x20000000); // clear carry - emit_mov_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_sub_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_mov_m32_r32(DRCTOP, MABS(®(RT)), REG_EDX); - emit_setcc_r8(DRCTOP, COND_NC, REG_AL); // subtract carry is inverse - emit_shl_r32_imm(DRCTOP, REG_EAX, 29); // move carry to correct location in XER - emit_or_r32_r32(DRCTOP, REG_EBX, REG_EAX); // insert carry to XER - emit_mov_m32_r32(DRCTOP, MABS(&XER), REG_EBX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfmex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_subfmex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_subfzex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_subfzex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_sync(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tw(drc_core *drc, UINT32 op) -{ - emit_link link1 = {0}, link2 = {0}, link3 = {0}, link4 = {0}, link5 = {0}, link6 = {0}; - int do_link1 = 0; - int do_link2 = 0; - int do_link3 = 0; - int do_link4 = 0; - int do_link5 = 0; - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_cmp_r32_r32(DRCTOP, REG_EAX, REG_EDX); - - if (RT & 0x10) { - emit_jcc_near_link(DRCTOP, COND_L, &link1); // less than = signed < - do_link1 = 1; - } - if (RT & 0x08) { - emit_jcc_near_link(DRCTOP, COND_G, &link2); // greater = signed > - do_link2 = 1; - } - if (RT & 0x04) { - emit_jcc_near_link(DRCTOP, COND_E, &link3); // equal - do_link3 = 1; - } - if (RT & 0x02) { - emit_jcc_near_link(DRCTOP, COND_B, &link4); // below = unsigned < - do_link4 = 1; - } - if (RT & 0x01) { - emit_jcc_near_link(DRCTOP, COND_A, &link5); // above = unsigned > - do_link5 = 1; - } - emit_jmp_near_link(DRCTOP, &link6); - - if (do_link1) { - resolve_link(DRCTOP, &link1); - } - if (do_link2) { - resolve_link(DRCTOP, &link2); - } - if (do_link3) { - resolve_link(DRCTOP, &link3); - } - if (do_link4) { - resolve_link(DRCTOP, &link4); - } - if (do_link5) { - resolve_link(DRCTOP, &link5); - } - // generate exception - emit_mov_m32_imm(DRCTOP, MABS(&SRR0), temp_ppc_pc + 4); - emit_jmp(DRCTOP, ppc.generate_trap_exception); - - // no exception - resolve_link(DRCTOP, &link6); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_twi(drc_core *drc, UINT32 op) -{ - emit_link link1 = {0}, link2 = {0}, link3 = {0}, link4 = {0}, link5 = {0}, link6 = {0}; - int do_link1 = 0; - int do_link2 = 0; - int do_link3 = 0; - int do_link4 = 0; - int do_link5 = 0; - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_mov_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_cmp_r32_r32(DRCTOP, REG_EAX, REG_EDX); - - if (RT & 0x10) { - emit_jcc_near_link(DRCTOP, COND_L, &link1); // less than = signed < - do_link1 = 1; - } - if (RT & 0x08) { - emit_jcc_near_link(DRCTOP, COND_G, &link2); // greater = signed > - do_link2 = 1; - } - if (RT & 0x04) { - emit_jcc_near_link(DRCTOP, COND_E, &link3); // equal - do_link3 = 1; - } - if (RT & 0x02) { - emit_jcc_near_link(DRCTOP, COND_B, &link4); // below = unsigned < - do_link4 = 1; - } - if (RT & 0x01) { - emit_jcc_near_link(DRCTOP, COND_A, &link5); // above = unsigned > - do_link5 = 1; - } - emit_jmp_near_link(DRCTOP, &link6); - - if (do_link1) { - resolve_link(DRCTOP, &link1); - } - if (do_link2) { - resolve_link(DRCTOP, &link2); - } - if (do_link3) { - resolve_link(DRCTOP, &link3); - } - if (do_link4) { - resolve_link(DRCTOP, &link4); - } - if (do_link5) { - resolve_link(DRCTOP, &link5); - } - // generate exception - emit_mov_m32_imm(DRCTOP, MABS(&SRR0), temp_ppc_pc + 4); - emit_jmp(DRCTOP, ppc.generate_trap_exception); - - // no exception - resolve_link(DRCTOP, &link6); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_xorx(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_xor_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - if (RCBIT) { - append_set_cr0(drc); - } - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_xori(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_xor_r32_imm(DRCTOP, REG_EDX, UIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_xoris(drc_core *drc, UINT32 op) -{ - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RS))); - emit_xor_r32_imm(DRCTOP, REG_EDX, UIMM16 << 16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dccci(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcread(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_icbt(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_iccci(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_icread(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_rfci(drc_core *drc, UINT32 op) -{ - osd_printf_debug("PPCDRC: recompile rfci\n"); - return RECOMPILE_UNIMPLEMENTED; -} - -static UINT32 recompile_mfdcr(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mfdcr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtdcr(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtdcr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_wrtee(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_wrtee); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_wrteei(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_wrteei); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} -#endif - - - -static UINT32 recompile_invalid(drc_core *drc, UINT32 op) -{ - osd_printf_debug("PPCDRC: Invalid opcode %08X PC : %X\n", op, ppc.pc); - return RECOMPILE_UNIMPLEMENTED; -} - - - -/* PowerPC 60x Recompilers */ - -static UINT32 recompile_lfs(drc_core *drc,UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (genf*)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movd_r128_r32(DRCTOP, REG_XMM0, REG_EAX); - emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert float to double - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM1); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lfs); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfsu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movd_r128_r32(DRCTOP, REG_XMM0, REG_EAX); - emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert float to double - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM1); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lfsu); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfd(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)READ64); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfdu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EDX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ64); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfs(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RT))); - emit_cvtsd2ss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert double to float - emit_movd_r32_r128(DRCTOP, REG_EAX, REG_XMM1); - emit_push_r32(DRCTOP, REG_EAX); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfs); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfsu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RT))); - emit_cvtsd2ss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert double to float - emit_movd_r32_r128(DRCTOP, REG_EAX, REG_XMM1); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfsu); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfd(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RT))); - emit_push_r32(DRCTOP, REG_EDX); - emit_push_r32(DRCTOP, REG_EAX); - if (RA == 0) - { - emit_push_imm(DRCTOP, SIMM16); - } - else - { - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_push_r32(DRCTOP, REG_EAX); - } - emit_call(DRCTOP, (x86code *)WRITE64); - emit_add_r32_imm(DRCTOP, REG_ESP, 12); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfdu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RT))); - emit_push_r32(DRCTOP, REG_EDX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_imm(DRCTOP, REG_EAX, SIMM16); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE64); - emit_add_r32_imm(DRCTOP, REG_ESP, 12); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfdux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ64); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfdx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ64); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfsux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_mov_r32_m32(DRCTOP, REG_EDX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EDX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EDX); - emit_push_r32(DRCTOP, REG_EDX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movd_r128_r32(DRCTOP, REG_XMM0, REG_EAX); - emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert float to double - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM1); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lfsux); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_lfsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)READ32); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_movd_r128_r32(DRCTOP, REG_XMM0, REG_EAX); - emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert float to double - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM1); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_lfsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mfsr(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mfsr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mfsrin(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mfsrin); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mftb(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mftb); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtsr(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtsr); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtsrin(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtsrin); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dcba(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfdux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RT))); - emit_push_r32(DRCTOP, REG_EDX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE64); - emit_add_r32_imm(DRCTOP, REG_ESP, 12); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfdx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RT))); - emit_push_r32(DRCTOP, REG_EDX); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE64); - emit_add_r32_imm(DRCTOP, REG_ESP, 12); - - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfdx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfiwx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RT))); - emit_movd_r32_r128(DRCTOP, REG_EAX, REG_XMM0); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfiwx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfsux(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RT))); - emit_cvtsd2ss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert double to float - emit_movd_r32_r128(DRCTOP, REG_EAX, REG_XMM1); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - emit_mov_m32_r32(DRCTOP, MABS(®(RA)), REG_EAX); - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfsux); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_stfsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RT))); - emit_cvtsd2ss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0); // convert double to float - emit_movd_r32_r128(DRCTOP, REG_EAX, REG_XMM1); - emit_push_r32(DRCTOP, REG_EAX); - - emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(®(RB))); - if (RA != 0) - { - emit_add_r32_m32(DRCTOP, REG_EAX, MABS(®(RA))); - } - emit_push_r32(DRCTOP, REG_EAX); - emit_call(DRCTOP, (x86code *)WRITE32); - emit_add_r32_imm(DRCTOP, REG_ESP, 8); -#else - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_stfsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); -#endif - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tlbia(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tlbie(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tlbsync(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_eciwx(drc_core *drc, UINT32 op) -{ - osd_printf_debug("PPCDRC: eciwx unimplemented\n"); - return RECOMPILE_UNIMPLEMENTED; -} - -static UINT32 recompile_ecowx(drc_core *drc, UINT32 op) -{ - osd_printf_debug("PPCDRC: ecowx unimplemented\n"); - return RECOMPILE_UNIMPLEMENTED; -} - -static UINT32 recompile_fabsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fabsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RB))); - emit_and_r32_imm(DRCTOP, REG_EDX, 0x7fffffff); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_faddx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_faddx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_addsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fcmpo(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fcmpo); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fcmpu(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fcmpu); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fctiwx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fctiwx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fctiwzx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fctiwzx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fdivx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fdivx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_divsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmrx(drc_core *drc, UINT32 op) -{ -#if USE_SSE2 - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RB))); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#else - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmrx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnabsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnabsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RB))); - emit_or_r32_imm(DRCTOP, REG_EDX, 0x80000000); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnegx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnegx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MABS(&FPR(RB))); - emit_xor_r32_imm(DRCTOP, REG_EDX, 0x80000000); - emit_mov_m64_r64(DRCTOP, MABS(&FPR(RT)), REG_EDX, REG_EAX); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_frspx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_frspx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -/* - _movq_r128_m64(REG_XMM0, MABS(&FPR(RB))); - _movq_m64abs_r128(&FPR(RT), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -*/ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_frsqrtex(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_frsqrtex); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fsqrtx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fsqrtx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fsubx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fsubx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_subsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mffsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mffsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtfsb0x(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtfsb0x); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtfsb1x(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtfsb1x); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtfsfx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtfsfx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mtfsfix(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mtfsfix); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_mcrfs(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_mcrfs); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_faddsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_faddsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_addsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fdivsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fdivsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_divsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fresx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fresx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fsqrtsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fsqrtsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fsubsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fsubsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RB))); - emit_subsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmaddx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmaddx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_movq_r128_m64(DRCTOP, REG_XMM2, MABS(&FPR(RB))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_addsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM2); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmsubx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmsubx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_movq_r128_m64(DRCTOP, REG_XMM2, MABS(&FPR(RB))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_subsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM2); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmulx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmulx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnmaddx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnmaddx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnmsubx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnmsubx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fselx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fselx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmaddsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmaddsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_movq_r128_m64(DRCTOP, REG_XMM2, MABS(&FPR(RB))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_addsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM2); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmsubsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmsubsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_movq_r128_m64(DRCTOP, REG_XMM2, MABS(&FPR(RB))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_subsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM2); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fmulsx(drc_core *drc, UINT32 op) -{ -#if !COMPILE_FPU || !USE_SSE2 - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fmulsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); -#else - emit_movq_r128_m64(DRCTOP, REG_XMM0, MABS(&FPR(RA))); - emit_movq_r128_m64(DRCTOP, REG_XMM1, MABS(&FPR(RC))); - emit_mulsd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1); - emit_movq_m64_r128(DRCTOP, MABS(&FPR(RT)), REG_XMM0); - - if (RCBIT) { - append_set_cr1(drc); - } -#endif - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnmaddsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnmaddsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_fnmsubsx(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_fnmsubsx); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} -#endif - -// PPC602 - -static UINT32 recompile_esa(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_esa); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_dsa(drc_core *drc, UINT32 op) -{ - emit_mov_m32_r32(DRCTOP, MABS(&ppc_icount), REG_EBP); - emit_push_imm(DRCTOP, op); - emit_call(DRCTOP, (x86code *)ppc_dsa); - emit_add_r32_imm(DRCTOP, REG_ESP, 4); - emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(&ppc_icount)); - - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tlbli(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} - -static UINT32 recompile_tlbld(drc_core *drc, UINT32 op) -{ - return RECOMPILE_SUCCESSFUL_CP(1,4); -} diff --git a/src/devices/cpu/powerpc/drc_ops.h b/src/devices/cpu/powerpc/drc_ops.h deleted file mode 100644 index 792cdd6260a..00000000000 --- a/src/devices/cpu/powerpc/drc_ops.h +++ /dev/null @@ -1,145 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -static const PPC_OPCODE ppcdrc_opcode_common[] = -{ - /*code subcode handler */ - { 31, 266, recompile_addx }, - { 31, 266 | 512, recompile_addx }, - { 31, 10, recompile_addcx }, - { 31, 10 | 512, recompile_addcx }, - { 31, 138, recompile_addex }, - { 31, 138 | 512, recompile_addex }, - { 14, -1, recompile_addi }, - { 12, -1, recompile_addic }, - { 13, -1, recompile_addic_rc }, - { 15, -1, recompile_addis }, - { 31, 234, recompile_addmex }, - { 31, 234 | 512, recompile_addmex }, - { 31, 202, recompile_addzex }, - { 31, 202 | 512, recompile_addzex }, - { 31, 28, recompile_andx }, - { 31, 28 | 512, recompile_andx }, - { 31, 60, recompile_andcx }, - { 28, -1, recompile_andi_rc }, - { 29, -1, recompile_andis_rc }, - { 18, -1, recompile_bx }, - { 16, -1, recompile_bcx }, - { 19, 528, recompile_bcctrx }, - { 19, 16, recompile_bclrx }, - { 31, 0, recompile_cmp }, - { 11, -1, recompile_cmpi }, - { 31, 32, recompile_cmpl }, - { 10, -1, recompile_cmpli }, - { 31, 26, recompile_cntlzw }, - { 19, 257, recompile_crand }, - { 19, 129, recompile_crandc }, - { 19, 289, recompile_creqv }, - { 19, 225, recompile_crnand }, - { 19, 33, recompile_crnor }, - { 19, 449, recompile_cror }, - { 19, 417, recompile_crorc }, - { 19, 193, recompile_crxor }, - { 31, 86, recompile_dcbf }, - { 31, 470, recompile_dcbi }, - { 31, 54, recompile_dcbst }, - { 31, 278, recompile_dcbt }, - { 31, 246, recompile_dcbtst }, - { 31, 1014, recompile_dcbz }, - { 31, 491, recompile_divwx }, - { 31, 491 | 512, recompile_divwx }, - { 31, 459, recompile_divwux }, - { 31, 459 | 512, recompile_divwux }, - { 31, 854, recompile_eieio }, - { 31, 284, recompile_eqvx }, - { 31, 954, recompile_extsbx }, - { 31, 922, recompile_extshx }, - { 31, 982, recompile_icbi }, - { 19, 150, recompile_isync }, - { 34, -1, recompile_lbz }, - { 35, -1, recompile_lbzu }, - { 31, 119, recompile_lbzux }, - { 31, 87, recompile_lbzx }, - { 42, -1, recompile_lha }, - { 43, -1, recompile_lhau }, - { 31, 375, recompile_lhaux }, - { 31, 343, recompile_lhax }, - { 31, 790, recompile_lhbrx }, - { 40, -1, recompile_lhz }, - { 41, -1, recompile_lhzu }, - { 31, 311, recompile_lhzux }, - { 31, 279, recompile_lhzx }, - { 46, -1, recompile_lmw }, - { 31, 597, recompile_lswi }, - { 31, 533, recompile_lswx }, - { 31, 20, recompile_lwarx }, - { 31, 534, recompile_lwbrx }, - { 32, -1, recompile_lwz }, - { 33, -1, recompile_lwzu }, - { 31, 55, recompile_lwzux }, - { 31, 23, recompile_lwzx }, - { 19, 0, recompile_mcrf }, - { 31, 512, recompile_mcrxr }, - { 31, 19, recompile_mfcr }, - { 31, 83, recompile_mfmsr }, - { 31, 339, recompile_mfspr }, - { 31, 144, recompile_mtcrf }, - { 31, 146, recompile_mtmsr }, - { 31, 467, recompile_mtspr }, - { 31, 75, recompile_mulhwx }, - { 31, 11, recompile_mulhwux }, - { 7, -1, recompile_mulli }, - { 31, 235, recompile_mullwx }, - { 31, 235 | 512, recompile_mullwx }, - { 31, 476, recompile_nandx }, - { 31, 104, recompile_negx }, - { 31, 104 | 512, recompile_negx }, - { 31, 124, recompile_norx }, - { 31, 444, recompile_orx }, - { 31, 412, recompile_orcx }, - { 24, -1, recompile_ori }, - { 25, -1, recompile_oris }, - { 19, 50, recompile_rfi }, - { 20, -1, recompile_rlwimix }, - { 21, -1, recompile_rlwinmx }, - { 23, -1, recompile_rlwnmx }, - { 17, -1, recompile_sc }, - { 31, 24, recompile_slwx }, - { 31, 792, recompile_srawx }, - { 31, 824, recompile_srawix }, - { 31, 536, recompile_srwx }, - { 38, -1, recompile_stb }, - { 39, -1, recompile_stbu }, - { 31, 247, recompile_stbux }, - { 31, 215, recompile_stbx }, - { 44, -1, recompile_sth }, - { 31, 918, recompile_sthbrx }, - { 45, -1, recompile_sthu }, - { 31, 439, recompile_sthux }, - { 31, 407, recompile_sthx }, - { 47, -1, recompile_stmw }, - { 31, 725, recompile_stswi }, - { 31, 661, recompile_stswx }, - { 36, -1, recompile_stw }, - { 31, 662, recompile_stwbrx }, - { 31, 150, recompile_stwcx_rc }, - { 37, -1, recompile_stwu }, - { 31, 183, recompile_stwux }, - { 31, 151, recompile_stwx }, - { 31, 40, recompile_subfx }, - { 31, 40 | 512, recompile_subfx }, - { 31, 8, recompile_subfcx }, - { 31, 8 | 512, recompile_subfcx }, - { 31, 136, recompile_subfex }, - { 31, 136 | 512, recompile_subfex }, - { 8, -1, recompile_subfic }, - { 31, 232, recompile_subfmex }, - { 31, 232 | 512, recompile_subfmex }, - { 31, 200, recompile_subfzex }, - { 31, 200 | 512, recompile_subfzex }, - { 31, 598, recompile_sync }, - { 31, 4, recompile_tw }, - { 3, -1, recompile_twi }, - { 31, 316, recompile_xorx }, - { 26, -1, recompile_xori }, - { 27, -1, recompile_xoris } -}; diff --git a/src/devices/cpu/powerpc/ppc.cpp b/src/devices/cpu/powerpc/ppc.cpp deleted file mode 100644 index cb85522177d..00000000000 --- a/src/devices/cpu/powerpc/ppc.cpp +++ /dev/null @@ -1,2135 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/* IBM/Motorola PowerPC 4xx/6xx Emulator */ - -#include -#include "emu.h" -#include "debugger.h" - -/* avoid including setjmp.h and defining jump buffer if not included from here */ -#define PPC_H_INCLUDED_FROM_PPC_C -#include "ppc.h" - -// PLL Configuration based on the table in MPC603EUM page 7-31 -static const int mpc603e_pll_config[12][9] = -{ - // 16, 20, 25, 33, 40, 50, 60, 66, 75 - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, -1, 0x0, -1 }, - { -1, -1, -1, -1, -1, 0xc, -1, 0xc, -1 }, - { 0x5, 0x5, 0x5, 0x4, 0x4, 0x4, -1, -1, -1 }, - { -1, -1, -1, 0x6, 0x6, -1, -1, -1, -1 }, - { -1, -1, 0x8, 0x8, -1, -1, -1, -1, -1 }, - { -1, 0xe, 0xe, -1, -1, -1, -1, -1, -1 }, - { 0xa, 0xa, 0xa, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -}; - -// PLL Configuration based on the table in MPC603E7VEC page 29 -static const int mpc603ev_pll_config[12][9] = -{ - // 16, 20, 25, 33, 40, 50, 60, 66, 75 - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - // 2:1 - { -1, -1, -1, -1, -1, -1, -1, 0x4, 0x4 }, - // 2.5:1 - { -1, -1, -1, -1, -1, 0x6, 0x6, 0x6, 0x6 }, - // 3:1 - { -1, -1, -1, -1, 0x8, 0x8, 0x8, 0x8, 0x8 }, - // 3.5:1 - { -1, -1, -1, -1, 0xe, 0xe, 0xe, 0xe, -1 }, - // 4:1 - { -1, -1, -1, 0xa, 0xa, 0xa, 0xa, -1, -1 }, - // 4.5:1 - { -1, -1, -1, 0x7, 0x7, 0x7, -1, -1, -1 }, - // 5:1 - { -1, -1, 0xb, 0xb, 0xb, -1, -1, -1, -1 }, - // 5.5:1 - { -1, -1, 0x9, 0x9, 0x9, -1, -1, -1, -1 }, - // 6:1 - { -1, -1, 0xd, 0xd, 0xd, -1, -1, -1, -1 } -}; - -// PLL Configuration based on the table in MPC603E7TEC page 23 -static const int mpc603r_pll_config[12][9] = -{ - // 16, 20, 25, 33, 40, 50, 60, 66, 75 - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - // 2:1 - { -1, -1, -1, -1, 0x5, 0x5, 0x5, 0x5, 0x5 }, - // 2.5:1 - { -1, -1, -1, -1, -1, -1, 0x6, 0x6, 0x6 }, - // 3:1 - { -1, -1, -1, -1, -1, 0x8, 0x8, 0x8, 0x8 }, - // 3.5:1 - { -1, -1, -1, -1, -1, 0xe, 0xe, 0xe, 0xe }, - // 4:1 - { -1, -1, -1, -1, 0xa, 0xa, 0xa, 0xa, 0xa }, - // 4.5:1 - { -1, -1, -1, 0x7, 0x7, 0x7, 0x7, 0x7, -1 }, - // 5:1 - { -1, -1, -1, 0xb, 0xb, 0xb, 0xb, -1, -1 }, - // 5.5:1 - { -1, -1, -1, 0x9, 0x9, 0x9, -1, -1, -1 }, - // 6:1 - { -1, -1, 0xd, 0xd, 0xd, 0xd, -1, -1, -1 }, -}; - - -static void ppc603_exception(int exception); -static void ppc602_exception(int exception); -static void ppc403_exception(int exception); -static UINT8 ppc403_spu_r(UINT32 a); -static void ppc403_spu_w(UINT32 a, UINT8 d); - -#define RD ((op >> 21) & 0x1F) -#define RT ((op >> 21) & 0x1f) -#define RS ((op >> 21) & 0x1f) -#define RA ((op >> 16) & 0x1f) -#define RB ((op >> 11) & 0x1f) -#define RC ((op >> 6) & 0x1f) - -#define MB ((op >> 6) & 0x1f) -#define ME ((op >> 1) & 0x1f) -#define SH ((op >> 11) & 0x1f) -#define BO ((op >> 21) & 0x1f) -#define BI ((op >> 16) & 0x1f) -#define CRFD ((op >> 23) & 0x7) -#define CRFA ((op >> 18) & 0x7) -#define FXM ((op >> 12) & 0xff) -#define SPR (((op >> 16) & 0x1f) | ((op >> 6) & 0x3e0)) - -#define SIMM16 (INT32)(INT16)(op & 0xffff) -#define UIMM16 (UINT32)(op & 0xffff) - -#define RCBIT (op & 0x1) -#define OEBIT (op & 0x400) -#define AABIT (op & 0x2) -#define LKBIT (op & 0x1) - -#define REG(x) (m_r[x]) -#define LR (m_lr) -#define CTR (m_ctr) -#define XER (m_xer) -#define CR(x) (m_cr[x]) -#define MSR (m_msr) -#define SRR0 (m_srr0) -#define SRR1 (m_srr1) -#define SRR2 (m_srr2) -#define SRR3 (m_srr3) -#define EVPR (m_evpr) -#define EXIER (m_exier) -#define EXISR (m_exisr) -#define DEC (m_dec) - - -// Stuff added for the 6xx -#define FPR(x) (m_fpr[x]) -#define FM ((op >> 17) & 0xFF) -#define SPRF (((op >> 6) & 0x3E0) | ((op >> 16) & 0x1F)) - - -#define CHECK_SUPERVISOR() \ - if((m_msr & 0x4000) != 0){ \ - } - -#define CHECK_FPU_AVAILABLE() \ - if((m_msr & 0x2000) == 0){ \ - } - -static UINT32 ppc_field_xlat[256]; - - - -#define FPSCR_FX 0x80000000 -#define FPSCR_FEX 0x40000000 -#define FPSCR_VX 0x20000000 -#define FPSCR_OX 0x10000000 -#define FPSCR_UX 0x08000000 -#define FPSCR_ZX 0x04000000 -#define FPSCR_XX 0x02000000 - - - -#define BITMASK_0(n) (UINT32)(((UINT64)1 << n) - 1) -#define CRBIT(x) ((m_cr[x / 4] & (1 << (3 - (x % 4)))) ? 1 : 0) -#define _BIT(n) (1 << (n)) -#define GET_ROTATE_MASK(mb,me) (ppc_rotate_mask[mb][me]) -#define ADD_CA(r,a,b) ((UINT32)r < (UINT32)a) -#define SUB_CA(r,a,b) (!((UINT32)a < (UINT32)b)) -#define ADD_OV(r,a,b) ((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) -#define SUB_OV(r,a,b) (( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) - -#define XER_SO 0x80000000 -#define XER_OV 0x40000000 -#define XER_CA 0x20000000 - -#define MSR_AP 0x00800000 /* Access privilege state (PPC602) */ -#define MSR_SA 0x00400000 /* Supervisor access mode (PPC602) */ -#define MSR_POW 0x00040000 /* Power Management Enable */ -#define MSR_WE 0x00040000 -#define MSR_CE 0x00020000 -#define MSR_ILE 0x00010000 /* Interrupt Little Endian Mode */ -#define MSR_EE 0x00008000 /* External Interrupt Enable */ -#define MSR_PR 0x00004000 /* Problem State */ -#define MSR_FP 0x00002000 /* Floating Point Available */ -#define MSR_ME 0x00001000 /* Machine Check Enable */ -#define MSR_FE0 0x00000800 -#define MSR_SE 0x00000400 /* Single Step Trace Enable */ -#define MSR_BE 0x00000200 /* Branch Trace Enable */ -#define MSR_DE 0x00000200 -#define MSR_FE1 0x00000100 -#define MSR_IP 0x00000040 /* Interrupt Prefix */ -#define MSR_IR 0x00000020 /* Instruction Relocate */ -#define MSR_DR 0x00000010 /* Data Relocate */ -#define MSR_PE 0x00000008 -#define MSR_PX 0x00000004 -#define MSR_RI 0x00000002 /* Recoverable Interrupt Enable */ -#define MSR_LE 0x00000001 - -#define TSR_ENW 0x80000000 -#define TSR_WIS 0x40000000 - -#define BYTE_REVERSE16(x) ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00)) -#define BYTE_REVERSE32(x) ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000)) - - -const device_type PPC403 = &device_creator; -const device_type PPC405 = &device_creator; -const device_type PPC601 = &device_creator; -const device_type PPC602 = &device_creator; -const device_type PPC603 = &device_creator; -const device_type PPC603E = &device_creator; -const device_type PPC603R = &device_creator; -const device_type PPC604 = &device_creator; -const device_type MPC8240 = &device_creator; -const device_type PPC403GA = &device_creator; -const device_type PPC403GCX = &device_creator; -const device_type PPC405GP = &device_creator; - - -struct PPC_OPCODE { - int code; - int subcode; - void (* handler)(UINT32); -}; - - - -static UINT32 ppc_rotate_mask[32][32]; - -#define ROPCODE(pc) memory_decrypted_read_dword(m_program, pc) -#define ROPCODE64(pc) memory_decrypted_read_qword(m_program, DWORD_XOR_BE(pc)) - - -ppc_device::ppc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, int address_bits, powerpc_flavor flavor, UINT32 cap, UINT32 tb_divisor) - : cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__) - , m_program_config("program", ENDIANNESS_BIG, address_bits, 32) - , m_core(NULL) - , c_bus_frequency(0) - , m_bus_freq_multiplier(1) - , m_flavor(flavor) - , m_cap(cap) - , m_tb_divisor(tb_divisor) - , m_vtlb(NULL) - , m_cache(CACHE_SIZE + sizeof(internal_ppc_state)) -{ -} - -//ppc403_device::ppc403_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -// : ppc_device(mconfig, PPC403, "PPC403", tag, owner, clock, "ppc403", 32) -//{ -//} -// -//ppc405_device::ppc405_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -// : ppc_device(mconfig, PPC405, "PPC405", tag, owner, clock, "ppc405", 32) -//{ -//} - -ppc603_device::ppc603_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC603, "PowerPC 603", tag, owner, clock, "ppc603", 64, PPC_MODEL_603, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4) -{ -} - -ppc603e_device::ppc603e_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC603E, "PowerPC 603e", tag, owner, clock, "ppc603e", 64, PPC_MODEL_603E, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4) -{ -} - -ppc603r_device::ppc603r_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC603R, "PowerPC 603R", tag, owner, clock, "ppc603r", 64, PPC_MODEL_603R, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4) -{ -} - -ppc602_device::ppc602_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC602, "PowerPC 602", tag, owner, clock, "ppc602", 64, PPC_MODEL_602, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4) -{ -} - -mpc8240_device::mpc8240_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, MPC8240, "PowerPC MPC8240", tag, owner, clock, "mpc8240", 64, PPC_MODEL_MPC8240, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4/* unknown */) -{ -} - -ppc601_device::ppc601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC601, "PowerPC 601", tag, owner, clock, "ppc601", 64, PPC_MODEL_601, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_MFIOC | PPCCAP_601BAT, 0/* no TB */) -{ -} - -ppc604_device::ppc604_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc_device(mconfig, PPC604, "PowerPC 604", tag, owner, clock, "ppc604", 64, PPC_MODEL_604, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_604_MMU, 4) -{ -} - -ppc4xx_device::ppc4xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, powerpc_flavor flavor, UINT32 cap, UINT32 tb_divisor) - : ppc_device(mconfig, type, name, tag, owner, clock, shortname, 64, flavor, cap, tb_divisor) // TODO address bits, ppccom has 31 address bits?? -{ -} - -ppc403ga_device::ppc403ga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, PPC403GA, "PowerPC 403GA", tag, owner, clock, "ppc403ga", PPC_MODEL_403GA, PPCCAP_4XX, 1) -{ -} - -ppc403gcx_device::ppc403gcx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, PPC403GCX, "PowerPC 403GCX", tag, owner, clock, "ppc403gcx", PPC_MODEL_403GCX, PPCCAP_4XX, 1) -{ -} - -ppc405gp_device::ppc405gp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, PPC405GP, "PowerPC 405GP", tag, owner, clock, "ppc405gp", PPC_MODEL_405GP, PPCCAP_4XX | PPCCAP_VEA, 1) -{ -} - -/*********************************************************************/ - -inline int ppc_device::IS_PPC602(void) -{ - return m_is602; -} - -inline int ppc_device::IS_PPC603(void) -{ - return m_is603; -} - -inline int ppc_device::IS_PPC403(void) -{ - return !IS_PPC602() && !IS_PPC603(); -} - -/*********************************************************************/ - - -INLINE void SET_CR0(INT32 rd) -{ - if( rd < 0 ) { - CR(0) = 0x8; - } else if( rd > 0 ) { - CR(0) = 0x4; - } else { - CR(0) = 0x2; - } - - if( XER & XER_SO ) - CR(0) |= 0x1; -} - -INLINE void SET_CR1(void) -{ - CR(1) = (ppc.fpscr >> 28) & 0xf; -} - -INLINE void SET_ADD_OV(UINT32 rd, UINT32 ra, UINT32 rb) -{ - if( ADD_OV(rd, ra, rb) ) - XER |= XER_SO | XER_OV; - else - XER &= ~XER_OV; -} - -INLINE void SET_SUB_OV(UINT32 rd, UINT32 ra, UINT32 rb) -{ - if( SUB_OV(rd, ra, rb) ) - XER |= XER_SO | XER_OV; - else - XER &= ~XER_OV; -} - -INLINE void SET_ADD_CA(UINT32 rd, UINT32 ra, UINT32 rb) -{ - if( ADD_CA(rd, ra, rb) ) - XER |= XER_CA; - else - XER &= ~XER_CA; -} - -INLINE void SET_SUB_CA(UINT32 rd, UINT32 ra, UINT32 rb) -{ - if( SUB_CA(rd, ra, rb) ) - XER |= XER_CA; - else - XER &= ~XER_CA; -} - -INLINE UINT32 check_condition_code(UINT32 bo, UINT32 bi) -{ - UINT32 ctr_ok; - UINT32 condition_ok; - UINT32 bo0 = (bo & 0x10) ? 1 : 0; - UINT32 bo1 = (bo & 0x08) ? 1 : 0; - UINT32 bo2 = (bo & 0x04) ? 1 : 0; - UINT32 bo3 = (bo & 0x02) ? 1 : 0; - - if( bo2 == 0 ) - --CTR; - - ctr_ok = bo2 | ((CTR != 0) ^ bo3); - condition_ok = bo0 | (CRBIT(bi) ^ (~bo1 & 0x1)); - - return ctr_ok && condition_ok; -} - -INLINE UINT64 ppc_read_timebase(void) -{ - int cycles = ppc_tb_base_icount - ppc_icount; - - if (IS_PPC603() || IS_PPC602()) - { - // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly - return ppc.tb + (cycles / 4); - } - else - { - // timebase is incremented once every core cycle on PPC403 - return ppc.tb + cycles; - } -} - -INLINE void ppc_write_timebase_l(UINT32 tbl) -{ - ppc_tb_base_icount = ppc_icount; - - ppc.tb &= ~0xffffffff; - ppc.tb |= tbl; -} - -INLINE void ppc_write_timebase_h(UINT32 tbh) -{ - ppc_tb_base_icount = ppc_icount; - - ppc.tb &= 0xffffffff; - ppc.tb |= (UINT64)(tbh) << 32; -} - -INLINE UINT32 read_decrementer(void) -{ - int cycles = ppc_dec_base_icount - ppc_icount; - - // decrementer is decremented once every four bus clock cycles, so adjust the cycles accordingly - return DEC - (cycles / (bus_freq_multiplier * 2)); -} - -INLINE void write_decrementer(UINT32 value) -{ - ppc_dec_base_icount = ppc_icount + (ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2); - - DEC = value; - - // check if decrementer exception occurs during execution - if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC)) - { - ppc_dec_trigger_cycle = ppc_icount - DEC; - } - else - { - ppc_dec_trigger_cycle = 0x7fffffff; - } -} - -/*********************************************************************/ - -INLINE void ppc_set_spr(int spr, UINT32 value) -{ - switch (spr) - { - case SPR_LR: LR = value; return; - case SPR_CTR: CTR = value; return; - case SPR_XER: XER = value; return; - case SPR_SRR0: ppc.srr0 = value; return; - case SPR_SRR1: ppc.srr1 = value; return; - case SPR_SPRG0: ppc.sprg[0] = value; return; - case SPR_SPRG1: ppc.sprg[1] = value; return; - case SPR_SPRG2: ppc.sprg[2] = value; return; - case SPR_SPRG3: ppc.sprg[3] = value; return; - case SPR_PVR: return; - } - - if(IS_PPC602() || IS_PPC603()) { - switch(spr) - { - case SPR603E_DEC: - if((value & 0x80000000) && !(DEC & 0x80000000)) - { - /* trigger interrupt */ - if (IS_PPC602()) - ppc602_exception(EXCEPTION_DECREMENTER); - if (IS_PPC603()) - ppc603_exception(EXCEPTION_DECREMENTER); - } - write_decrementer(value); - return; - - case SPR603E_TBL_W: - case SPR603E_TBL_R: // special 603e case - ppc_write_timebase_l(value); - return; - - case SPR603E_TBU_R: - case SPR603E_TBU_W: // special 603e case - ppc_write_timebase_h(value); - return; - - case SPR603E_HID0: ppc.hid0 = value; return; - case SPR603E_HID1: ppc.hid1 = value; return; - case SPR603E_HID2: ppc.hid2 = value; return; - - case SPR603E_DSISR: ppc.dsisr = value; return; - case SPR603E_DAR: ppc.dar = value; return; - case SPR603E_EAR: ppc.ear = value; return; - case SPR603E_DMISS: ppc.dmiss = value; return; - case SPR603E_DCMP: ppc.dcmp = value; return; - case SPR603E_HASH1: ppc.hash1 = value; return; - case SPR603E_HASH2: ppc.hash2 = value; return; - case SPR603E_IMISS: ppc.imiss = value; return; - case SPR603E_ICMP: ppc.icmp = value; return; - case SPR603E_RPA: ppc.rpa = value; return; - - case SPR603E_IBAT0L: ppc.ibat[0].l = value; return; - case SPR603E_IBAT0U: ppc.ibat[0].u = value; return; - case SPR603E_IBAT1L: ppc.ibat[1].l = value; return; - case SPR603E_IBAT1U: ppc.ibat[1].u = value; return; - case SPR603E_IBAT2L: ppc.ibat[2].l = value; return; - case SPR603E_IBAT2U: ppc.ibat[2].u = value; return; - case SPR603E_IBAT3L: ppc.ibat[3].l = value; return; - case SPR603E_IBAT3U: ppc.ibat[3].u = value; return; - case SPR603E_DBAT0L: ppc.dbat[0].l = value; return; - case SPR603E_DBAT0U: ppc.dbat[0].u = value; return; - case SPR603E_DBAT1L: ppc.dbat[1].l = value; return; - case SPR603E_DBAT1U: ppc.dbat[1].u = value; return; - case SPR603E_DBAT2L: ppc.dbat[2].l = value; return; - case SPR603E_DBAT2U: ppc.dbat[2].u = value; return; - case SPR603E_DBAT3L: ppc.dbat[3].l = value; return; - case SPR603E_DBAT3U: ppc.dbat[3].u = value; return; - - case SPR603E_SDR1: - ppc.sdr1 = value; - return; - - case SPR603E_IABR: ppc.iabr = value; return; - } - } - - if (ppc.is602) { - switch(spr) - { - case SPR602_LT: ppc.lt = value; return; - case SPR602_IBR: ppc.ibr = value; return; - case SPR602_SEBR: ppc.sebr = value; return; - case SPR602_SER: ppc.ser = value; return; - case SPR602_SP: ppc.sp = value; return; - case SPR602_TCR: ppc.tcr = value; return; - } - } - - if (IS_PPC403()) { - switch(spr) - { - case SPR403_TBHI: ppc_write_timebase_h(value); return; - case SPR403_TBLO: ppc_write_timebase_l(value); return; - - case SPR403_TSR: - ppc.tsr &= ~value; // 1 clears, 0 does nothing - return; - - case SPR403_TCR: - switch((value >> 24) & 0x3) - { - case 0: ppc.fit_bit = 1 << 8; break; - case 1: ppc.fit_bit = 1 << 12; break; - case 2: ppc.fit_bit = 1 << 16; break; - case 3: ppc.fit_bit = 1 << 20; break; - } - switch((value >> 30) & 0x3) - { - case 0: ppc.wdt_bit = 1 << 16; break; - case 1: ppc.wdt_bit = 1 << 20; break; - case 2: ppc.wdt_bit = 1 << 24; break; - case 3: ppc.wdt_bit = 1 << 28; break; - } - ppc.fit_int_enable = (value >> 23) & 0x1; - ppc.wdt_int_enable = (value >> 27) & 0x1; - ppc.tcr = value; - - if (!ppc.fit_int_enable) - { - ppc.interrupt_pending &= ~0x4; - } - return; - - case SPR403_ESR: ppc.esr = value; return; - case SPR403_ICCR: ppc.iccr = value; return; - case SPR403_DCCR: ppc.dccr = value; return; - case SPR403_EVPR: EVPR = value & 0xffff0000; return; - case SPR403_PIT: ppc.pit = value; return; - case SPR403_SGR: ppc.sgr = value; return; - case SPR403_DBSR: ppc.dbsr = value; return; - case SPR403_DCWR: return; - case SPR403_PID: ppc.pid = value; return; - case SPR403_PBL1: ppc.pbl1 = value; return; - case SPR403_PBU1: ppc.pbu1 = value; return; - case SPR403_PBL2: ppc.pbl2 = value; return; - case SPR403_PBU2: ppc.pbu2 = value; return; - case SPR403_SRR2: ppc.srr2 = value; return; - case SPR403_SRR3: ppc.srr3 = value; return; - case SPR403_DAC1: ppc.dac1 = value; return; - case SPR403_DAC2: ppc.dac2 = value; return; - case SPR403_IAC1: ppc.iac1 = value; return; - case SPR403_IAC2: ppc.iac2 = value; return; - } - } - - fatalerror("ppc: set_spr: unknown spr %d (%03X)!\n", spr, spr); -} - -INLINE UINT32 ppc_get_spr(int spr) -{ - switch(spr) - { - case SPR_LR: return LR; - case SPR_CTR: return CTR; - case SPR_XER: return XER; - case SPR_SRR0: return ppc.srr0; - case SPR_SRR1: return ppc.srr1; - case SPR_SPRG0: return ppc.sprg[0]; - case SPR_SPRG1: return ppc.sprg[1]; - case SPR_SPRG2: return ppc.sprg[2]; - case SPR_SPRG3: return ppc.sprg[3]; - case SPR_PVR: return ppc.pvr; - } - - if (IS_PPC403()) - { - switch (spr) - { - case SPR403_TBLU: - case SPR403_TBLO: return (UINT32)(ppc_read_timebase()); - case SPR403_TBHU: - case SPR403_TBHI: return (UINT32)(ppc_read_timebase() >> 32); - - case SPR403_EVPR: return EVPR; - case SPR403_ESR: return ppc.esr; - case SPR403_TCR: return ppc.tcr; - case SPR403_ICCR: return ppc.iccr; - case SPR403_DCCR: return ppc.dccr; - case SPR403_PIT: return ppc.pit; - case SPR403_DBSR: return ppc.dbsr; - case SPR403_SGR: return ppc.sgr; - case SPR403_TSR: return ppc.tsr; - case SPR403_PBL1: return ppc.pbl1; - case SPR403_PBU1: return ppc.pbu1; - case SPR403_PBL2: return ppc.pbl2; - case SPR403_PBU2: return ppc.pbu2; - case SPR403_SRR2: return ppc.srr2; - case SPR403_SRR3: return ppc.srr3; - case SPR403_DAC1: return ppc.dac1; - case SPR403_DAC2: return ppc.dac2; - case SPR403_IAC1: return ppc.iac1; - case SPR403_IAC2: return ppc.iac2; - } - } - - if (ppc.is602) { - switch(spr) - { - case SPR602_LT: return ppc.lt; - case SPR602_IBR: return ppc.ibr; - case SPR602_ESASRR: return ppc.esasrr; - case SPR602_SEBR: return ppc.sebr; - case SPR602_SER: return ppc.ser; - case SPR602_SP: return ppc.sp; - case SPR602_TCR: return ppc.tcr; - } - } - - if (IS_PPC603() || IS_PPC602()) - { - switch (spr) - { - case SPR603E_TBL_R: - fatalerror("ppc: get_spr: TBL_R\n"); - break; - - case SPR603E_TBU_R: - fatalerror("ppc: get_spr: TBU_R\n"); - break; - - case SPR603E_TBL_W: return (UINT32)(ppc_read_timebase()); - case SPR603E_TBU_W: return (UINT32)(ppc_read_timebase() >> 32); - case SPR603E_HID0: return ppc.hid0; - case SPR603E_HID1: return ppc.hid1; - case SPR603E_HID2: return ppc.hid2; - case SPR603E_DEC: return read_decrementer(); - case SPR603E_SDR1: return ppc.sdr1; - case SPR603E_DSISR: return ppc.dsisr; - case SPR603E_DAR: return ppc.dar; - case SPR603E_EAR: return ppc.ear; - case SPR603E_DMISS: return ppc.dmiss; - case SPR603E_DCMP: return ppc.dcmp; - case SPR603E_HASH1: return ppc.hash1; - case SPR603E_HASH2: return ppc.hash2; - case SPR603E_IMISS: return ppc.imiss; - case SPR603E_ICMP: return ppc.icmp; - case SPR603E_RPA: return ppc.rpa; - case SPR603E_IBAT0L: return ppc.ibat[0].l; - case SPR603E_IBAT0U: return ppc.ibat[0].u; - case SPR603E_IBAT1L: return ppc.ibat[1].l; - case SPR603E_IBAT1U: return ppc.ibat[1].u; - case SPR603E_IBAT2L: return ppc.ibat[2].l; - case SPR603E_IBAT2U: return ppc.ibat[2].u; - case SPR603E_IBAT3L: return ppc.ibat[3].l; - case SPR603E_IBAT3U: return ppc.ibat[3].u; - case SPR603E_DBAT0L: return ppc.dbat[0].l; - case SPR603E_DBAT0U: return ppc.dbat[0].u; - case SPR603E_DBAT1L: return ppc.dbat[1].l; - case SPR603E_DBAT1U: return ppc.dbat[1].u; - case SPR603E_DBAT2L: return ppc.dbat[2].l; - case SPR603E_DBAT2U: return ppc.dbat[2].u; - case SPR603E_DBAT3L: return ppc.dbat[3].l; - case SPR603E_DBAT3U: return ppc.dbat[3].u; - } - } - - fatalerror("ppc: get_spr: unknown spr %d (%03X)!\n", spr, spr); - return 0; -} - -static UINT8 ppc_read8_translated(address_space &space, offs_t address); -static UINT16 ppc_read16_translated(address_space &space, offs_t address); -static UINT32 ppc_read32_translated(address_space &space, offs_t address); -static UINT64 ppc_read64_translated(address_space &space, offs_t address); -static void ppc_write8_translated(address_space &space, offs_t address, UINT8 data); -static void ppc_write16_translated(address_space &space, offs_t address, UINT16 data); -static void ppc_write32_translated(address_space &space, offs_t address, UINT32 data); -static void ppc_write64_translated(address_space &space, offs_t address, UINT64 data); - -INLINE void ppc_set_msr(UINT32 value) -{ - if( value & (MSR_ILE | MSR_LE) ) - fatalerror("ppc: set_msr: little_endian mode not supported!\n"); - - MSR = value; - - if (IS_PPC603() || IS_PPC602()) - { - if (!(MSR & MSR_DR)) - { - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - } - else - { - ppc.read8 = ppc_read8_translated; - ppc.read16 = ppc_read16_translated; - ppc.read32 = ppc_read32_translated; - ppc.read64 = ppc_read64_translated; - ppc.write8 = ppc_write8_translated; - ppc.write16 = ppc_write16_translated; - ppc.write32 = ppc_write32_translated; - ppc.write64 = ppc_write64_translated; - } - } -} - -INLINE UINT32 ppc_get_msr(void) -{ - return MSR; -} - -INLINE void ppc_set_cr(UINT32 value) -{ - CR(0) = (value >> 28) & 0xf; - CR(1) = (value >> 24) & 0xf; - CR(2) = (value >> 20) & 0xf; - CR(3) = (value >> 16) & 0xf; - CR(4) = (value >> 12) & 0xf; - CR(5) = (value >> 8) & 0xf; - CR(6) = (value >> 4) & 0xf; - CR(7) = (value >> 0) & 0xf; -} - -INLINE UINT32 ppc_get_cr(void) -{ - return CR(0) << 28 | CR(1) << 24 | CR(2) << 20 | CR(3) << 16 | CR(4) << 12 | CR(5) << 8 | CR(6) << 4 | CR(7); -} - -INLINE void ppc_exception(int exception_type) -{ - longjmp(ppc.exception_jmpbuf, exception_type); -} - -/***********************************************************************/ - -#include "ppc_mem.inc" - -#include "ppc403.inc" -#include "ppc602.inc" -#include "ppc603.inc" - -/********************************************************************/ - -#include "ppc_ops.inc" -#include "ppc_ops.h" - -/* Initialization and shutdown */ - -static void ppc_init(void) -{ - int i,j; - - memset(&ppc, 0, sizeof(ppc)); - - for( i=0; i < 64; i++ ) { - ppc.optable[i] = ppc_invalid; - } - for( i=0; i < 1024; i++ ) { - ppc.optable19[i] = ppc_invalid; - ppc.optable31[i] = ppc_invalid; - ppc.optable59[i] = ppc_invalid; - ppc.optable63[i] = ppc_invalid; - } - - /* Fill the opcode tables */ - for( i=0; i < (sizeof(ppc_opcode_common) / sizeof(PPC_OPCODE)); i++ ) { - switch(ppc_opcode_common[i].code) - { - case 19: - ppc.optable19[ppc_opcode_common[i].subcode] = ppc_opcode_common[i].handler; - break; - - case 31: - ppc.optable31[ppc_opcode_common[i].subcode] = ppc_opcode_common[i].handler; - break; - - case 59: - case 63: - break; - - default: - ppc.optable[ppc_opcode_common[i].code] = ppc_opcode_common[i].handler; - } - - } - - /* Calculate rotate mask table */ - for( i=0; i < 32; i++ ) { - for( j=0; j < 32; j++ ) { - UINT32 mask; - int mb = i; - int me = j; - mask = ((UINT32)0xFFFFFFFF >> mb) ^ ((me >= 31) ? 0 : ((UINT32)0xFFFFFFFF >> (me + 1))); - if( mb > me ) - mask = ~mask; - - ppc_rotate_mask[i][j] = mask; - } - } -} - - -// !!! probably should move this stuff elsewhere !!! -static CPU_INIT( ppc403 ) -{ - const ppc_config *configdata = device->static_config(); - - ppc_init(); - - /* PPC403 specific opcodes */ - ppc.optable31[454] = ppc_dccci; - ppc.optable31[486] = ppc_dcread; - ppc.optable31[262] = ppc_icbt; - ppc.optable31[966] = ppc_iccci; - ppc.optable31[998] = ppc_icread; - ppc.optable31[323] = ppc_mfdcr; - ppc.optable31[451] = ppc_mtdcr; - ppc.optable31[131] = ppc_wrtee; - ppc.optable31[163] = ppc_wrteei; - - // !!! why is rfci here !!! - ppc.optable19[51] = ppc_rfci; - - ppc.spu.rx_timer = device->machine().scheduler().timer_alloc(FUNC(ppc403_spu_rx_callback)); - ppc.spu.tx_timer = device->machine().scheduler().timer_alloc(FUNC(ppc403_spu_tx_callback)); - - ppc.read8 = ppc403_read8; - ppc.read16 = ppc403_read16; - ppc.read32 = ppc403_read32; - ppc.write8 = ppc403_write8; - ppc.write16 = ppc403_write16; - ppc.write32 = ppc403_write32; - ppc.read16_unaligned = ppc403_read16_unaligned; - ppc.read32_unaligned = ppc403_read32_unaligned; - ppc.write16_unaligned = ppc403_write16_unaligned; - ppc.write32_unaligned = ppc403_write32_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; -} - -static CPU_EXIT( ppc403 ) -{ -} - -static CPU_INIT( ppc405 ) -{ - const ppc_config *configdata = device->static_config(); - - ppc_init(); - - /* PPC403 specific opcodes */ - ppc.optable31[454] = ppc_dccci; - ppc.optable31[486] = ppc_dcread; - ppc.optable31[262] = ppc_icbt; - ppc.optable31[966] = ppc_iccci; - ppc.optable31[998] = ppc_icread; - ppc.optable31[323] = ppc_mfdcr; - ppc.optable31[451] = ppc_mtdcr; - ppc.optable31[131] = ppc_wrtee; - ppc.optable31[163] = ppc_wrteei; - - // !!! why is rfci here !!! - ppc.optable19[51] = ppc_rfci; - - ppc.spu.rx_timer = device->machine().scheduler().timer_alloc(FUNC(ppc403_spu_rx_callback)); - ppc.spu.tx_timer = device->machine().scheduler().timer_alloc(FUNC(ppc403_spu_tx_callback)); - - ppc.read8 = ppc403_read8; - ppc.read16 = ppc403_read16; - ppc.read32 = ppc403_read32; - ppc.write8 = ppc403_write8; - ppc.write16 = ppc403_write16; - ppc.write32 = ppc403_write32; - ppc.read16_unaligned = ppc403_read16_unaligned; - ppc.read32_unaligned = ppc403_read32_unaligned; - ppc.write16_unaligned = ppc403_write16_unaligned; - ppc.write32_unaligned = ppc403_write32_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; -} - -static CPU_EXIT( ppc405 ) -{ -} - -static CPU_INIT( ppc603 ) -{ - const ppc_config *configdata = device->static_config(); - int pll_config = 0; - float multiplier; - int i ; - - ppc_init() ; - - ppc.optable[48] = ppc_lfs; - ppc.optable[49] = ppc_lfsu; - ppc.optable[50] = ppc_lfd; - ppc.optable[51] = ppc_lfdu; - ppc.optable[52] = ppc_stfs; - ppc.optable[53] = ppc_stfsu; - ppc.optable[54] = ppc_stfd; - ppc.optable[55] = ppc_stfdu; - ppc.optable31[631] = ppc_lfdux; - ppc.optable31[599] = ppc_lfdx; - ppc.optable31[567] = ppc_lfsux; - ppc.optable31[535] = ppc_lfsx; - ppc.optable31[595] = ppc_mfsr; - ppc.optable31[659] = ppc_mfsrin; - ppc.optable31[371] = ppc_mftb; - ppc.optable31[210] = ppc_mtsr; - ppc.optable31[242] = ppc_mtsrin; - ppc.optable31[758] = ppc_dcba; - ppc.optable31[759] = ppc_stfdux; - ppc.optable31[727] = ppc_stfdx; - ppc.optable31[983] = ppc_stfiwx; - ppc.optable31[695] = ppc_stfsux; - ppc.optable31[663] = ppc_stfsx; - ppc.optable31[370] = ppc_tlbia; - ppc.optable31[306] = ppc_tlbie; - ppc.optable31[566] = ppc_tlbsync; - ppc.optable31[310] = ppc_eciwx; - ppc.optable31[438] = ppc_ecowx; - - ppc.optable63[264] = ppc_fabsx; - ppc.optable63[21] = ppc_faddx; - ppc.optable63[32] = ppc_fcmpo; - ppc.optable63[0] = ppc_fcmpu; - ppc.optable63[14] = ppc_fctiwx; - ppc.optable63[15] = ppc_fctiwzx; - ppc.optable63[18] = ppc_fdivx; - ppc.optable63[72] = ppc_fmrx; - ppc.optable63[136] = ppc_fnabsx; - ppc.optable63[40] = ppc_fnegx; - ppc.optable63[12] = ppc_frspx; - ppc.optable63[26] = ppc_frsqrtex; - ppc.optable63[22] = ppc_fsqrtx; - ppc.optable63[20] = ppc_fsubx; - ppc.optable63[583] = ppc_mffsx; - ppc.optable63[70] = ppc_mtfsb0x; - ppc.optable63[38] = ppc_mtfsb1x; - ppc.optable63[711] = ppc_mtfsfx; - ppc.optable63[134] = ppc_mtfsfix; - ppc.optable63[64] = ppc_mcrfs; - - ppc.optable59[21] = ppc_faddsx; - ppc.optable59[18] = ppc_fdivsx; - ppc.optable59[24] = ppc_fresx; - ppc.optable59[22] = ppc_fsqrtsx; - ppc.optable59[20] = ppc_fsubsx; - - for(i = 0; i < 32; i++) - { - ppc.optable63[i * 32 | 29] = ppc_fmaddx; - ppc.optable63[i * 32 | 28] = ppc_fmsubx; - ppc.optable63[i * 32 | 25] = ppc_fmulx; - ppc.optable63[i * 32 | 31] = ppc_fnmaddx; - ppc.optable63[i * 32 | 30] = ppc_fnmsubx; - ppc.optable63[i * 32 | 23] = ppc_fselx; - - ppc.optable59[i * 32 | 29] = ppc_fmaddsx; - ppc.optable59[i * 32 | 28] = ppc_fmsubsx; - ppc.optable59[i * 32 | 25] = ppc_fmulsx; - ppc.optable59[i * 32 | 31] = ppc_fnmaddsx; - ppc.optable59[i * 32 | 30] = ppc_fnmsubsx; - } - - ppc.optable31[978] = ppc_tlbld; - - for(i = 0; i < 256; i++) - { - ppc_field_xlat[i] = - ((i & 0x80) ? 0xF0000000 : 0) | - ((i & 0x40) ? 0x0F000000 : 0) | - ((i & 0x20) ? 0x00F00000 : 0) | - ((i & 0x10) ? 0x000F0000 : 0) | - ((i & 0x08) ? 0x0000F000 : 0) | - ((i & 0x04) ? 0x00000F00 : 0) | - ((i & 0x02) ? 0x000000F0 : 0) | - ((i & 0x01) ? 0x0000000F : 0); - } - - ppc.is603 = 1; - - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - ppc.read16_unaligned = ppc_read16_unaligned; - ppc.read32_unaligned = ppc_read32_unaligned; - ppc.read64_unaligned = ppc_read64_unaligned; - ppc.write16_unaligned = ppc_write16_unaligned; - ppc.write32_unaligned = ppc_write32_unaligned; - ppc.write64_unaligned = ppc_write64_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; - - multiplier = (float)((configdata->bus_frequency_multiplier >> 4) & 0xf) + - (float)(configdata->bus_frequency_multiplier & 0xf) / 10.0f; - bus_freq_multiplier = (int)(multiplier * 2); - - switch(config->pvr) - { - case PPC_MODEL_603E: pll_config = mpc603e_pll_config[bus_freq_multiplier-1][configdata->bus_frequency]; break; - case PPC_MODEL_603EV: pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][configdata->bus_frequency]; break; - case PPC_MODEL_603R: pll_config = mpc603r_pll_config[bus_freq_multiplier-1][configdata->bus_frequency]; break; - default: break; - } - - if (pll_config == -1) - { - fatalerror("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)\n", config->bus_frequency, multiplier); - } - - ppc.hid1 = pll_config << 28; -} - -static CPU_EXIT( ppc603 ) -{ -} - -static CPU_INIT( ppc602 ) -{ - float multiplier; - const ppc_config *configdata = device->static_config(); - - int i ; - - ppc_init() ; - - ppc.optable[48] = ppc_lfs; - ppc.optable[49] = ppc_lfsu; - ppc.optable[50] = ppc_lfd; - ppc.optable[51] = ppc_lfdu; - ppc.optable[52] = ppc_stfs; - ppc.optable[53] = ppc_stfsu; - ppc.optable[54] = ppc_stfd; - ppc.optable[55] = ppc_stfdu; - ppc.optable31[631] = ppc_lfdux; - ppc.optable31[599] = ppc_lfdx; - ppc.optable31[567] = ppc_lfsux; - ppc.optable31[535] = ppc_lfsx; - ppc.optable31[595] = ppc_mfsr; - ppc.optable31[659] = ppc_mfsrin; - ppc.optable31[371] = ppc_mftb; - ppc.optable31[210] = ppc_mtsr; - ppc.optable31[242] = ppc_mtsrin; - ppc.optable31[758] = ppc_dcba; - ppc.optable31[759] = ppc_stfdux; - ppc.optable31[727] = ppc_stfdx; - ppc.optable31[983] = ppc_stfiwx; - ppc.optable31[695] = ppc_stfsux; - ppc.optable31[663] = ppc_stfsx; - ppc.optable31[370] = ppc_tlbia; - ppc.optable31[306] = ppc_tlbie; - ppc.optable31[566] = ppc_tlbsync; - ppc.optable31[310] = ppc_eciwx; - ppc.optable31[438] = ppc_ecowx; - - ppc.optable63[264] = ppc_fabsx; - ppc.optable63[21] = ppc_faddx; - ppc.optable63[32] = ppc_fcmpo; - ppc.optable63[0] = ppc_fcmpu; - ppc.optable63[14] = ppc_fctiwx; - ppc.optable63[15] = ppc_fctiwzx; - ppc.optable63[18] = ppc_fdivx; - ppc.optable63[72] = ppc_fmrx; - ppc.optable63[136] = ppc_fnabsx; - ppc.optable63[40] = ppc_fnegx; - ppc.optable63[12] = ppc_frspx; - ppc.optable63[26] = ppc_frsqrtex; - ppc.optable63[22] = ppc_fsqrtx; - ppc.optable63[20] = ppc_fsubx; - ppc.optable63[583] = ppc_mffsx; - ppc.optable63[70] = ppc_mtfsb0x; - ppc.optable63[38] = ppc_mtfsb1x; - ppc.optable63[711] = ppc_mtfsfx; - ppc.optable63[134] = ppc_mtfsfix; - ppc.optable63[64] = ppc_mcrfs; - - ppc.optable59[21] = ppc_faddsx; - ppc.optable59[18] = ppc_fdivsx; - ppc.optable59[24] = ppc_fresx; - ppc.optable59[22] = ppc_fsqrtsx; - ppc.optable59[20] = ppc_fsubsx; - - for(i = 0; i < 32; i++) - { - ppc.optable63[i * 32 | 29] = ppc_fmaddx; - ppc.optable63[i * 32 | 28] = ppc_fmsubx; - ppc.optable63[i * 32 | 25] = ppc_fmulx; - ppc.optable63[i * 32 | 31] = ppc_fnmaddx; - ppc.optable63[i * 32 | 30] = ppc_fnmsubx; - ppc.optable63[i * 32 | 23] = ppc_fselx; - - ppc.optable59[i * 32 | 29] = ppc_fmaddsx; - ppc.optable59[i * 32 | 28] = ppc_fmsubsx; - ppc.optable59[i * 32 | 25] = ppc_fmulsx; - ppc.optable59[i * 32 | 31] = ppc_fnmaddsx; - ppc.optable59[i * 32 | 30] = ppc_fnmsubsx; - } - - for(i = 0; i < 256; i++) - { - ppc_field_xlat[i] = - ((i & 0x80) ? 0xF0000000 : 0) | - ((i & 0x40) ? 0x0F000000 : 0) | - ((i & 0x20) ? 0x00F00000 : 0) | - ((i & 0x10) ? 0x000F0000 : 0) | - ((i & 0x08) ? 0x0000F000 : 0) | - ((i & 0x04) ? 0x00000F00 : 0) | - ((i & 0x02) ? 0x000000F0 : 0) | - ((i & 0x01) ? 0x0000000F : 0); - } - - // PPC602 specific opcodes - ppc.optable31[596] = ppc_esa; - ppc.optable31[628] = ppc_dsa; - ppc.optable31[1010] = ppc_tlbli; - ppc.optable31[978] = ppc_tlbld; - - ppc.is602 = 1; - - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - ppc.read16_unaligned = ppc_read16_unaligned; - ppc.read32_unaligned = ppc_read32_unaligned; - ppc.read64_unaligned = ppc_read64_unaligned; - ppc.write16_unaligned = ppc_write16_unaligned; - ppc.write32_unaligned = ppc_write32_unaligned; - ppc.write64_unaligned = ppc_write64_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; - - multiplier = (float)((configdata->bus_frequency_multiplier >> 4) & 0xf) + - (float)(configdata->bus_frequency_multiplier & 0xf) / 10.0f; - bus_freq_multiplier = (int)(multiplier * 2); -} - -static CPU_EXIT( ppc602 ) -{ -} - -static void mpc8240_tlbli(UINT32 op) -{ -} - -static void mpc8240_tlbld(UINT32 op) -{ -} - -static CPU_INIT( mpc8240 ) -{ - float multiplier; - const ppc_config *configdata = device->static_config(); - - int i ; - - ppc_init(); - - ppc.optable[48] = ppc_lfs; - ppc.optable[49] = ppc_lfsu; - ppc.optable[50] = ppc_lfd; - ppc.optable[51] = ppc_lfdu; - ppc.optable[52] = ppc_stfs; - ppc.optable[53] = ppc_stfsu; - ppc.optable[54] = ppc_stfd; - ppc.optable[55] = ppc_stfdu; - ppc.optable31[631] = ppc_lfdux; - ppc.optable31[599] = ppc_lfdx; - ppc.optable31[567] = ppc_lfsux; - ppc.optable31[535] = ppc_lfsx; - ppc.optable31[595] = ppc_mfsr; - ppc.optable31[659] = ppc_mfsrin; - ppc.optable31[371] = ppc_mftb; - ppc.optable31[210] = ppc_mtsr; - ppc.optable31[242] = ppc_mtsrin; - ppc.optable31[758] = ppc_dcba; - ppc.optable31[759] = ppc_stfdux; - ppc.optable31[727] = ppc_stfdx; - ppc.optable31[983] = ppc_stfiwx; - ppc.optable31[695] = ppc_stfsux; - ppc.optable31[663] = ppc_stfsx; - ppc.optable31[370] = ppc_tlbia; - ppc.optable31[306] = ppc_tlbie; - ppc.optable31[566] = ppc_tlbsync; - ppc.optable31[310] = ppc_eciwx; - ppc.optable31[438] = ppc_ecowx; - - ppc.optable63[264] = ppc_fabsx; - ppc.optable63[21] = ppc_faddx; - ppc.optable63[32] = ppc_fcmpo; - ppc.optable63[0] = ppc_fcmpu; - ppc.optable63[14] = ppc_fctiwx; - ppc.optable63[15] = ppc_fctiwzx; - ppc.optable63[18] = ppc_fdivx; - ppc.optable63[72] = ppc_fmrx; - ppc.optable63[136] = ppc_fnabsx; - ppc.optable63[40] = ppc_fnegx; - ppc.optable63[12] = ppc_frspx; - ppc.optable63[26] = ppc_frsqrtex; - ppc.optable63[22] = ppc_fsqrtx; - ppc.optable63[20] = ppc_fsubx; - ppc.optable63[583] = ppc_mffsx; - ppc.optable63[70] = ppc_mtfsb0x; - ppc.optable63[38] = ppc_mtfsb1x; - ppc.optable63[711] = ppc_mtfsfx; - ppc.optable63[134] = ppc_mtfsfix; - ppc.optable63[64] = ppc_mcrfs; - - ppc.optable59[21] = ppc_faddsx; - ppc.optable59[18] = ppc_fdivsx; - ppc.optable59[24] = ppc_fresx; - ppc.optable59[22] = ppc_fsqrtsx; - ppc.optable59[20] = ppc_fsubsx; - - for(i = 0; i < 32; i++) - { - ppc.optable63[i * 32 | 29] = ppc_fmaddx; - ppc.optable63[i * 32 | 28] = ppc_fmsubx; - ppc.optable63[i * 32 | 25] = ppc_fmulx; - ppc.optable63[i * 32 | 31] = ppc_fnmaddx; - ppc.optable63[i * 32 | 30] = ppc_fnmsubx; - ppc.optable63[i * 32 | 23] = ppc_fselx; - - ppc.optable59[i * 32 | 29] = ppc_fmaddsx; - ppc.optable59[i * 32 | 28] = ppc_fmsubsx; - ppc.optable59[i * 32 | 25] = ppc_fmulsx; - ppc.optable59[i * 32 | 31] = ppc_fnmaddsx; - ppc.optable59[i * 32 | 30] = ppc_fnmsubsx; - } - - for(i = 0; i < 256; i++) - { - ppc_field_xlat[i] = - ((i & 0x80) ? 0xF0000000 : 0) | - ((i & 0x40) ? 0x0F000000 : 0) | - ((i & 0x20) ? 0x00F00000 : 0) | - ((i & 0x10) ? 0x000F0000 : 0) | - ((i & 0x08) ? 0x0000F000 : 0) | - ((i & 0x04) ? 0x00000F00 : 0) | - ((i & 0x02) ? 0x000000F0 : 0) | - ((i & 0x01) ? 0x0000000F : 0); - } - - // MPC8240 specific opcodes - ppc.optable31[978] = mpc8240_tlbld; - ppc.optable31[1010] = mpc8240_tlbli; - - ppc.is603 = 1; - - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - ppc.read16_unaligned = ppc_read16_unaligned; - ppc.read32_unaligned = ppc_read32_unaligned; - ppc.read64_unaligned = ppc_read64_unaligned; - ppc.write16_unaligned = ppc_write16_unaligned; - ppc.write32_unaligned = ppc_write32_unaligned; - ppc.write64_unaligned = ppc_write64_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; - - multiplier = (float)((configdata->bus_frequency_multiplier >> 4) & 0xf) + - (float)(configdata->bus_frequency_multiplier & 0xf) / 10.0f; - bus_freq_multiplier = (int)(multiplier * 2); -} - -static CPU_EXIT( mpc8240 ) -{ -} - -static CPU_INIT( ppc601 ) -{ - const ppc_config *configdata = device->static_config(); - float multiplier; - int i ; - - ppc_init() ; - - ppc.optable[48] = ppc_lfs; - ppc.optable[49] = ppc_lfsu; - ppc.optable[50] = ppc_lfd; - ppc.optable[51] = ppc_lfdu; - ppc.optable[52] = ppc_stfs; - ppc.optable[53] = ppc_stfsu; - ppc.optable[54] = ppc_stfd; - ppc.optable[55] = ppc_stfdu; - ppc.optable31[631] = ppc_lfdux; - ppc.optable31[599] = ppc_lfdx; - ppc.optable31[567] = ppc_lfsux; - ppc.optable31[535] = ppc_lfsx; - ppc.optable31[595] = ppc_mfsr; - ppc.optable31[659] = ppc_mfsrin; - ppc.optable31[371] = ppc_mftb; - ppc.optable31[210] = ppc_mtsr; - ppc.optable31[242] = ppc_mtsrin; - ppc.optable31[758] = ppc_dcba; - ppc.optable31[759] = ppc_stfdux; - ppc.optable31[727] = ppc_stfdx; - ppc.optable31[983] = ppc_stfiwx; - ppc.optable31[695] = ppc_stfsux; - ppc.optable31[663] = ppc_stfsx; - ppc.optable31[370] = ppc_tlbia; - ppc.optable31[306] = ppc_tlbie; - ppc.optable31[566] = ppc_tlbsync; - ppc.optable31[310] = ppc_eciwx; - ppc.optable31[438] = ppc_ecowx; - - ppc.optable63[264] = ppc_fabsx; - ppc.optable63[21] = ppc_faddx; - ppc.optable63[32] = ppc_fcmpo; - ppc.optable63[0] = ppc_fcmpu; - ppc.optable63[14] = ppc_fctiwx; - ppc.optable63[15] = ppc_fctiwzx; - ppc.optable63[18] = ppc_fdivx; - ppc.optable63[72] = ppc_fmrx; - ppc.optable63[136] = ppc_fnabsx; - ppc.optable63[40] = ppc_fnegx; - ppc.optable63[12] = ppc_frspx; - ppc.optable63[26] = ppc_frsqrtex; - ppc.optable63[22] = ppc_fsqrtx; - ppc.optable63[20] = ppc_fsubx; - ppc.optable63[583] = ppc_mffsx; - ppc.optable63[70] = ppc_mtfsb0x; - ppc.optable63[38] = ppc_mtfsb1x; - ppc.optable63[711] = ppc_mtfsfx; - ppc.optable63[134] = ppc_mtfsfix; - ppc.optable63[64] = ppc_mcrfs; - - ppc.optable59[21] = ppc_faddsx; - ppc.optable59[18] = ppc_fdivsx; - ppc.optable59[24] = ppc_fresx; - ppc.optable59[22] = ppc_fsqrtsx; - ppc.optable59[20] = ppc_fsubsx; - - for(i = 0; i < 32; i++) - { - ppc.optable63[i * 32 | 29] = ppc_fmaddx; - ppc.optable63[i * 32 | 28] = ppc_fmsubx; - ppc.optable63[i * 32 | 25] = ppc_fmulx; - ppc.optable63[i * 32 | 31] = ppc_fnmaddx; - ppc.optable63[i * 32 | 30] = ppc_fnmsubx; - ppc.optable63[i * 32 | 23] = ppc_fselx; - - ppc.optable59[i * 32 | 29] = ppc_fmaddsx; - ppc.optable59[i * 32 | 28] = ppc_fmsubsx; - ppc.optable59[i * 32 | 25] = ppc_fmulsx; - ppc.optable59[i * 32 | 31] = ppc_fnmaddsx; - ppc.optable59[i * 32 | 30] = ppc_fnmsubsx; - } - - for(i = 0; i < 256; i++) - { - ppc_field_xlat[i] = - ((i & 0x80) ? 0xF0000000 : 0) | - ((i & 0x40) ? 0x0F000000 : 0) | - ((i & 0x20) ? 0x00F00000 : 0) | - ((i & 0x10) ? 0x000F0000 : 0) | - ((i & 0x08) ? 0x0000F000 : 0) | - ((i & 0x04) ? 0x00000F00 : 0) | - ((i & 0x02) ? 0x000000F0 : 0) | - ((i & 0x01) ? 0x0000000F : 0); - } - - ppc.is603 = 1; - - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - ppc.read16_unaligned = ppc_read16_unaligned; - ppc.read32_unaligned = ppc_read32_unaligned; - ppc.read64_unaligned = ppc_read64_unaligned; - ppc.write16_unaligned = ppc_write16_unaligned; - ppc.write32_unaligned = ppc_write32_unaligned; - ppc.write64_unaligned = ppc_write64_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; - - multiplier = (float)((configdata->bus_frequency_multiplier >> 4) & 0xf) + - (float)(configdata->bus_frequency_multiplier & 0xf) / 10.0f; - bus_freq_multiplier = (int)(multiplier * 2); - - ppc.hid1 = 0; -} - -static CPU_EXIT( ppc601 ) -{ -} - -static CPU_INIT( ppc604 ) -{ - const ppc_config *configdata = device->static_config(); - float multiplier; - int i ; - - ppc_init() ; - - ppc.optable[48] = ppc_lfs; - ppc.optable[49] = ppc_lfsu; - ppc.optable[50] = ppc_lfd; - ppc.optable[51] = ppc_lfdu; - ppc.optable[52] = ppc_stfs; - ppc.optable[53] = ppc_stfsu; - ppc.optable[54] = ppc_stfd; - ppc.optable[55] = ppc_stfdu; - ppc.optable31[631] = ppc_lfdux; - ppc.optable31[599] = ppc_lfdx; - ppc.optable31[567] = ppc_lfsux; - ppc.optable31[535] = ppc_lfsx; - ppc.optable31[595] = ppc_mfsr; - ppc.optable31[659] = ppc_mfsrin; - ppc.optable31[371] = ppc_mftb; - ppc.optable31[210] = ppc_mtsr; - ppc.optable31[242] = ppc_mtsrin; - ppc.optable31[758] = ppc_dcba; - ppc.optable31[759] = ppc_stfdux; - ppc.optable31[727] = ppc_stfdx; - ppc.optable31[983] = ppc_stfiwx; - ppc.optable31[695] = ppc_stfsux; - ppc.optable31[663] = ppc_stfsx; - ppc.optable31[370] = ppc_tlbia; - ppc.optable31[306] = ppc_tlbie; - ppc.optable31[566] = ppc_tlbsync; - ppc.optable31[310] = ppc_eciwx; - ppc.optable31[438] = ppc_ecowx; - - ppc.optable63[264] = ppc_fabsx; - ppc.optable63[21] = ppc_faddx; - ppc.optable63[32] = ppc_fcmpo; - ppc.optable63[0] = ppc_fcmpu; - ppc.optable63[14] = ppc_fctiwx; - ppc.optable63[15] = ppc_fctiwzx; - ppc.optable63[18] = ppc_fdivx; - ppc.optable63[72] = ppc_fmrx; - ppc.optable63[136] = ppc_fnabsx; - ppc.optable63[40] = ppc_fnegx; - ppc.optable63[12] = ppc_frspx; - ppc.optable63[26] = ppc_frsqrtex; - ppc.optable63[22] = ppc_fsqrtx; - ppc.optable63[20] = ppc_fsubx; - ppc.optable63[583] = ppc_mffsx; - ppc.optable63[70] = ppc_mtfsb0x; - ppc.optable63[38] = ppc_mtfsb1x; - ppc.optable63[711] = ppc_mtfsfx; - ppc.optable63[134] = ppc_mtfsfix; - ppc.optable63[64] = ppc_mcrfs; - - ppc.optable59[21] = ppc_faddsx; - ppc.optable59[18] = ppc_fdivsx; - ppc.optable59[24] = ppc_fresx; - ppc.optable59[22] = ppc_fsqrtsx; - ppc.optable59[20] = ppc_fsubsx; - - for(i = 0; i < 32; i++) - { - ppc.optable63[i * 32 | 29] = ppc_fmaddx; - ppc.optable63[i * 32 | 28] = ppc_fmsubx; - ppc.optable63[i * 32 | 25] = ppc_fmulx; - ppc.optable63[i * 32 | 31] = ppc_fnmaddx; - ppc.optable63[i * 32 | 30] = ppc_fnmsubx; - ppc.optable63[i * 32 | 23] = ppc_fselx; - - ppc.optable59[i * 32 | 29] = ppc_fmaddsx; - ppc.optable59[i * 32 | 28] = ppc_fmsubsx; - ppc.optable59[i * 32 | 25] = ppc_fmulsx; - ppc.optable59[i * 32 | 31] = ppc_fnmaddsx; - ppc.optable59[i * 32 | 30] = ppc_fnmsubsx; - } - - ppc.optable31[978] = ppc_tlbld; - - for(i = 0; i < 256; i++) - { - ppc_field_xlat[i] = - ((i & 0x80) ? 0xF0000000 : 0) | - ((i & 0x40) ? 0x0F000000 : 0) | - ((i & 0x20) ? 0x00F00000 : 0) | - ((i & 0x10) ? 0x000F0000 : 0) | - ((i & 0x08) ? 0x0000F000 : 0) | - ((i & 0x04) ? 0x00000F00 : 0) | - ((i & 0x02) ? 0x000000F0 : 0) | - ((i & 0x01) ? 0x0000000F : 0); - } - - ppc.is603 = 1; - - ppc.read8 = memory_read_byte_64be; - ppc.read16 = memory_read_word_64be; - ppc.read32 = memory_read_dword_64be; - ppc.read64 = memory_read_qword_64be; - ppc.write8 = memory_write_byte_64be; - ppc.write16 = memory_write_word_64be; - ppc.write32 = memory_write_dword_64be; - ppc.write64 = memory_write_qword_64be; - ppc.read16_unaligned = ppc_read16_unaligned; - ppc.read32_unaligned = ppc_read32_unaligned; - ppc.read64_unaligned = ppc_read64_unaligned; - ppc.write16_unaligned = ppc_write16_unaligned; - ppc.write32_unaligned = ppc_write32_unaligned; - ppc.write64_unaligned = ppc_write64_unaligned; - - ppc.irq_callback = irqcallback; - ppc.device = device; - ppc.program = &device->space(AS_PROGRAM); - - ppc.pvr = configdata->pvr; - - multiplier = (float)((configdata->bus_frequency_multiplier >> 4) & 0xf) + - (float)(configdata->bus_frequency_multiplier & 0xf) / 10.0f; - bus_freq_multiplier = (int)(multiplier * 2); - - ppc.hid1 = 0; -} - -static CPU_EXIT( ppc604 ) -{ -} - - - -/************************************************************************** - * Generic set_info - **************************************************************************/ - -static CPU_SET_INFO( ppc ) -{ - switch (state) - { - case CPUINFO_INT_PC: - case CPUINFO_INT_REGISTER + PPC_PC: ppc.pc = info->i; break; - case CPUINFO_INT_REGISTER + PPC_MSR: ppc_set_msr(info->i); break; - case CPUINFO_INT_REGISTER + PPC_CR: ppc_set_cr(info->i); break; - case CPUINFO_INT_REGISTER + PPC_LR: LR = info->i; break; - case CPUINFO_INT_REGISTER + PPC_CTR: CTR = info->i; break; - case CPUINFO_INT_REGISTER + PPC_XER: XER = info->i; break; - case CPUINFO_INT_REGISTER + PPC_SRR0: SRR0 = info->i; break; - case CPUINFO_INT_REGISTER + PPC_SRR1: SRR1 = info->i; break; - - case CPUINFO_INT_REGISTER + PPC_R0: ppc.r[0] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R1: ppc.r[1] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R2: ppc.r[2] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R3: ppc.r[3] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R4: ppc.r[4] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R5: ppc.r[5] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R6: ppc.r[6] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R7: ppc.r[7] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R8: ppc.r[8] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R9: ppc.r[9] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R10: ppc.r[10] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R11: ppc.r[11] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R12: ppc.r[12] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R13: ppc.r[13] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R14: ppc.r[14] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R15: ppc.r[15] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R16: ppc.r[16] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R17: ppc.r[17] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R18: ppc.r[18] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R19: ppc.r[19] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R20: ppc.r[20] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R21: ppc.r[21] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R22: ppc.r[22] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R23: ppc.r[23] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R24: ppc.r[24] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R25: ppc.r[25] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R26: ppc.r[26] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R27: ppc.r[27] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R28: ppc.r[28] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R29: ppc.r[29] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R30: ppc.r[30] = info->i; break; - case CPUINFO_INT_REGISTER + PPC_R31: ppc.r[31] = info->i; break; - } -} - -static CPU_SET_INFO( ppc403 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 8) - { - ppc403_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - case CPUINFO_INT_REGISTER + PPC_EXIER: EXIER = info->i; break; - case CPUINFO_INT_REGISTER + PPC_EXISR: EXISR = info->i; break; - default: ppc_set_info(state, info); break; - } -} - -static CPU_SET_INFO( ppc603 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5) - { - ppc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - case CPUINFO_INT_REGISTER + PPC_DEC: write_decrementer(info->i); break; - case CPUINFO_INT_INPUT_STATE + PPC_INPUT_LINE_SMI: ppc603_set_smi_line(info->i); break; - default: ppc_set_info(state, info); break; - } -} - -static CPU_GET_INFO( ppc ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(ppc); break; - case CPUINFO_INT_INPUT_LINES: info->i = 1; break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 40; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 32; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; - - case CPUINFO_INT_INPUT_STATE: info->i = CLEAR_LINE; break; - - case CPUINFO_INT_PREVIOUSPC: /* not implemented */ break; - - case CPUINFO_INT_PC: /* intentional fallthrough */ - case CPUINFO_INT_REGISTER + PPC_PC: info->i = ppc.pc; break; - case CPUINFO_INT_REGISTER + PPC_MSR: info->i = ppc_get_msr(); break; - case CPUINFO_INT_REGISTER + PPC_CR: info->i = ppc_get_cr(); break; - case CPUINFO_INT_REGISTER + PPC_LR: info->i = LR; break; - case CPUINFO_INT_REGISTER + PPC_CTR: info->i = CTR; break; - case CPUINFO_INT_REGISTER + PPC_XER: info->i = XER; break; - case CPUINFO_INT_REGISTER + PPC_SRR0: info->i = SRR0; break; - case CPUINFO_INT_REGISTER + PPC_SRR1: info->i = SRR1; break; - - case CPUINFO_INT_REGISTER + PPC_R0: info->i = ppc.r[0]; break; - case CPUINFO_INT_REGISTER + PPC_R1: info->i = ppc.r[1]; break; - case CPUINFO_INT_REGISTER + PPC_R2: info->i = ppc.r[2]; break; - case CPUINFO_INT_REGISTER + PPC_R3: info->i = ppc.r[3]; break; - case CPUINFO_INT_REGISTER + PPC_R4: info->i = ppc.r[4]; break; - case CPUINFO_INT_REGISTER + PPC_R5: info->i = ppc.r[5]; break; - case CPUINFO_INT_REGISTER + PPC_R6: info->i = ppc.r[6]; break; - case CPUINFO_INT_REGISTER + PPC_R7: info->i = ppc.r[7]; break; - case CPUINFO_INT_REGISTER + PPC_R8: info->i = ppc.r[8]; break; - case CPUINFO_INT_REGISTER + PPC_R9: info->i = ppc.r[9]; break; - case CPUINFO_INT_REGISTER + PPC_R10: info->i = ppc.r[10]; break; - case CPUINFO_INT_REGISTER + PPC_R11: info->i = ppc.r[11]; break; - case CPUINFO_INT_REGISTER + PPC_R12: info->i = ppc.r[12]; break; - case CPUINFO_INT_REGISTER + PPC_R13: info->i = ppc.r[13]; break; - case CPUINFO_INT_REGISTER + PPC_R14: info->i = ppc.r[14]; break; - case CPUINFO_INT_REGISTER + PPC_R15: info->i = ppc.r[15]; break; - case CPUINFO_INT_REGISTER + PPC_R16: info->i = ppc.r[16]; break; - case CPUINFO_INT_REGISTER + PPC_R17: info->i = ppc.r[17]; break; - case CPUINFO_INT_REGISTER + PPC_R18: info->i = ppc.r[18]; break; - case CPUINFO_INT_REGISTER + PPC_R19: info->i = ppc.r[19]; break; - case CPUINFO_INT_REGISTER + PPC_R20: info->i = ppc.r[20]; break; - case CPUINFO_INT_REGISTER + PPC_R21: info->i = ppc.r[21]; break; - case CPUINFO_INT_REGISTER + PPC_R22: info->i = ppc.r[22]; break; - case CPUINFO_INT_REGISTER + PPC_R23: info->i = ppc.r[23]; break; - case CPUINFO_INT_REGISTER + PPC_R24: info->i = ppc.r[24]; break; - case CPUINFO_INT_REGISTER + PPC_R25: info->i = ppc.r[25]; break; - case CPUINFO_INT_REGISTER + PPC_R26: info->i = ppc.r[26]; break; - case CPUINFO_INT_REGISTER + PPC_R27: info->i = ppc.r[27]; break; - case CPUINFO_INT_REGISTER + PPC_R28: info->i = ppc.r[28]; break; - case CPUINFO_INT_REGISTER + PPC_R29: info->i = ppc.r[29]; break; - case CPUINFO_INT_REGISTER + PPC_R30: info->i = ppc.r[30]; break; - case CPUINFO_INT_REGISTER + PPC_R31: info->i = ppc.r[31]; break; - - - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_BURN: info->burn = NULL; break; - case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(ppc); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ppc_icount; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC403"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc403"); break; - case CPUINFO_STR_FAMILY: strcpy(info->s, "PowerPC"); break; - case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break; - - case CPUINFO_STR_FLAGS: strcpy(info->s, " "); break; - - case CPUINFO_STR_REGISTER + PPC_PC: sprintf(info->s, "PC: %08X", ppc.pc); break; - case CPUINFO_STR_REGISTER + PPC_MSR: sprintf(info->s, "MSR: %08X", ppc_get_msr()); break; - case CPUINFO_STR_REGISTER + PPC_CR: sprintf(info->s, "CR: %08X", ppc_get_cr()); break; - case CPUINFO_STR_REGISTER + PPC_LR: sprintf(info->s, "LR: %08X", LR); break; - case CPUINFO_STR_REGISTER + PPC_CTR: sprintf(info->s, "CTR: %08X", CTR); break; - case CPUINFO_STR_REGISTER + PPC_XER: sprintf(info->s, "XER: %08X", XER); break; - case CPUINFO_STR_REGISTER + PPC_SRR0: sprintf(info->s, "SRR0: %08X", SRR0); break; - case CPUINFO_STR_REGISTER + PPC_SRR1: sprintf(info->s, "SRR1: %08X", SRR1); break; - - case CPUINFO_STR_REGISTER + PPC_R0: sprintf(info->s, "R0: %08X", ppc.r[0]); break; - case CPUINFO_STR_REGISTER + PPC_R1: sprintf(info->s, "R1: %08X", ppc.r[1]); break; - case CPUINFO_STR_REGISTER + PPC_R2: sprintf(info->s, "R2: %08X", ppc.r[2]); break; - case CPUINFO_STR_REGISTER + PPC_R3: sprintf(info->s, "R3: %08X", ppc.r[3]); break; - case CPUINFO_STR_REGISTER + PPC_R4: sprintf(info->s, "R4: %08X", ppc.r[4]); break; - case CPUINFO_STR_REGISTER + PPC_R5: sprintf(info->s, "R5: %08X", ppc.r[5]); break; - case CPUINFO_STR_REGISTER + PPC_R6: sprintf(info->s, "R6: %08X", ppc.r[6]); break; - case CPUINFO_STR_REGISTER + PPC_R7: sprintf(info->s, "R7: %08X", ppc.r[7]); break; - case CPUINFO_STR_REGISTER + PPC_R8: sprintf(info->s, "R8: %08X", ppc.r[8]); break; - case CPUINFO_STR_REGISTER + PPC_R9: sprintf(info->s, "R9: %08X", ppc.r[9]); break; - case CPUINFO_STR_REGISTER + PPC_R10: sprintf(info->s, "R10: %08X", ppc.r[10]); break; - case CPUINFO_STR_REGISTER + PPC_R11: sprintf(info->s, "R11: %08X", ppc.r[11]); break; - case CPUINFO_STR_REGISTER + PPC_R12: sprintf(info->s, "R12: %08X", ppc.r[12]); break; - case CPUINFO_STR_REGISTER + PPC_R13: sprintf(info->s, "R13: %08X", ppc.r[13]); break; - case CPUINFO_STR_REGISTER + PPC_R14: sprintf(info->s, "R14: %08X", ppc.r[14]); break; - case CPUINFO_STR_REGISTER + PPC_R15: sprintf(info->s, "R15: %08X", ppc.r[15]); break; - case CPUINFO_STR_REGISTER + PPC_R16: sprintf(info->s, "R16: %08X", ppc.r[16]); break; - case CPUINFO_STR_REGISTER + PPC_R17: sprintf(info->s, "R17: %08X", ppc.r[17]); break; - case CPUINFO_STR_REGISTER + PPC_R18: sprintf(info->s, "R18: %08X", ppc.r[18]); break; - case CPUINFO_STR_REGISTER + PPC_R19: sprintf(info->s, "R19: %08X", ppc.r[19]); break; - case CPUINFO_STR_REGISTER + PPC_R20: sprintf(info->s, "R20: %08X", ppc.r[20]); break; - case CPUINFO_STR_REGISTER + PPC_R21: sprintf(info->s, "R21: %08X", ppc.r[21]); break; - case CPUINFO_STR_REGISTER + PPC_R22: sprintf(info->s, "R22: %08X", ppc.r[22]); break; - case CPUINFO_STR_REGISTER + PPC_R23: sprintf(info->s, "R23: %08X", ppc.r[23]); break; - case CPUINFO_STR_REGISTER + PPC_R24: sprintf(info->s, "R24: %08X", ppc.r[24]); break; - case CPUINFO_STR_REGISTER + PPC_R25: sprintf(info->s, "R25: %08X", ppc.r[25]); break; - case CPUINFO_STR_REGISTER + PPC_R26: sprintf(info->s, "R26: %08X", ppc.r[26]); break; - case CPUINFO_STR_REGISTER + PPC_R27: sprintf(info->s, "R27: %08X", ppc.r[27]); break; - case CPUINFO_STR_REGISTER + PPC_R28: sprintf(info->s, "R28: %08X", ppc.r[28]); break; - case CPUINFO_STR_REGISTER + PPC_R29: sprintf(info->s, "R29: %08X", ppc.r[29]); break; - case CPUINFO_STR_REGISTER + PPC_R30: sprintf(info->s, "R30: %08X", ppc.r[30]); break; - case CPUINFO_STR_REGISTER + PPC_R31: sprintf(info->s, "R31: %08X", ppc.r[31]); break; - } -} - -CPU_GET_INFO( ppc403 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 8; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - case CPUINFO_INT_REGISTER + PPC_EXIER: info->i = EXIER; break; - case CPUINFO_INT_REGISTER + PPC_EXISR: info->i = EXISR; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc403); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc403); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc403); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc403); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc403); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC403"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc403"); break; - case CPUINFO_STR_REGISTER + PPC_EXIER: sprintf(info->s, "EXIER: %08X", EXIER); break; - case CPUINFO_STR_REGISTER + PPC_EXISR: sprintf(info->s, "EXISR: %08X", EXISR); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -CPU_GET_INFO( ppc405 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 8; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - case CPUINFO_INT_REGISTER + PPC_EXIER: info->i = EXIER; break; - case CPUINFO_INT_REGISTER + PPC_EXISR: info->i = EXISR; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc405); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc405); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc405); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc405); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc405); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC405"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc405"); break; - case CPUINFO_STR_REGISTER + PPC_EXIER: sprintf(info->s, "EXIER: %08X", EXIER); break; - case CPUINFO_STR_REGISTER + PPC_EXISR: sprintf(info->s, "EXISR: %08X", EXISR); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -CPU_GET_INFO( ppc603 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 5; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 64; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - case CPUINFO_INT_LOGADDR_WIDTH_PROGRAM: info->i = 32; break; - case CPUINFO_INT_PAGE_SHIFT_PROGRAM: info->i = 17; break; - case CPUINFO_INT_REGISTER + PPC_DEC: info->i = read_decrementer(); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc603); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc603); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc603); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc603); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc603); break; - case CPUINFO_FCT_READ: info->read = CPU_GET_READ_NAME(ppc); break; - case CPUINFO_FCT_WRITE: info->write = CPU_GET_WRITE_NAME(ppc); break; - case CPUINFO_FCT_READOP: info->readop = CPU_GET_READOP_NAME(ppc); break; - case CPUINFO_FCT_TRANSLATE: info->translate = ppc_translate_address_cb; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC603"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc603"); break; - case CPUINFO_STR_REGISTER + PPC_DEC: sprintf(info->s, "DEC: %08X", read_decrementer()); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -static CPU_SET_INFO( ppc602 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5) - { - ppc602_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - case CPUINFO_INT_INPUT_STATE + PPC_INPUT_LINE_SMI: ppc602_set_smi_line(info->i); break; - default: ppc_set_info(state, info); break; - } -} - -CPU_GET_INFO( ppc602 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 5; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - case CPUINFO_INT_REGISTER + PPC_IBR: info->i = ppc.ibr; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 64; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc602); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc602); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc602); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc602); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc602); break; - case CPUINFO_FCT_READ: info->read = CPU_GET_READ_NAME(ppc); break; - case CPUINFO_FCT_WRITE: info->write = CPU_GET_WRITE_NAME(ppc); break; - case CPUINFO_FCT_READOP: info->readop = CPU_GET_READOP_NAME(ppc); break; - case CPUINFO_FCT_TRANSLATE: info->translate = ppc_translate_address_cb; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC602"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc602"); break; - case CPUINFO_STR_REGISTER + PPC_IBR: sprintf(info->s, "IBR: %08X", ppc.ibr); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - - -static CPU_SET_INFO( mpc8240 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5) - { - ppc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - default: ppc_set_info(state, info); break; - } -} - -CPU_GET_INFO( mpc8240 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 5; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 64; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(mpc8240); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(mpc8240); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc603); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(mpc8240); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc603); break; - case CPUINFO_FCT_READ: info->read = CPU_GET_READ_NAME(ppc); break; - case CPUINFO_FCT_WRITE: info->write = CPU_GET_WRITE_NAME(ppc); break; - case CPUINFO_FCT_READOP: info->readop = CPU_GET_READOP_NAME(ppc); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "MPC8240"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "mpc8240"); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -static CPU_SET_INFO( ppc601 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5) - { - ppc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - default: ppc_set_info(state, info); break; - } -} - -CPU_GET_INFO( ppc601 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 5; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 64; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc601); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc601); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc603); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc601); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc603); break; - case CPUINFO_FCT_READ: info->read = CPU_GET_READ_NAME(ppc); break; - case CPUINFO_FCT_WRITE: info->write = CPU_GET_WRITE_NAME(ppc); break; - case CPUINFO_FCT_READOP: info->readop = CPU_GET_READOP_NAME(ppc); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC601"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc601"); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -static CPU_SET_INFO( ppc604 ) -{ - if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5) - { - ppc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i); - return; - } - switch(state) - { - default: ppc_set_info(state, info); break; - } -} - -CPU_GET_INFO( ppc604 ) -{ - switch(state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_LINES: info->i = 5; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 64; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ppc604); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ppc604); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ppc603); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ppc604); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ppc603); break; - case CPUINFO_FCT_READ: info->read = CPU_GET_READ_NAME(ppc); break; - case CPUINFO_FCT_WRITE: info->write = CPU_GET_WRITE_NAME(ppc); break; - case CPUINFO_FCT_READOP: info->readop = CPU_GET_READOP_NAME(ppc); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PPC604"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ppc604"); break; - - default: CPU_GET_INFO_CALL(ppc); break; - } -} - -ppc403ga_device::ppc403ga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, type, tag, owner, clock, CPU_GET_INFO_NAME(ppc403ga)) -{ -} - -const device_type PPC403GA = &legacy_device_creator; - -ppc403gcx_device::ppc403gcx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, type, tag, owner, clock, CPU_GET_INFO_NAME(ppc403gcx)) -{ -} - -const device_type PPC403GCX = &legacy_device_creator; - -ppc405gp_device::ppc405gp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock) - : ppc4xx_device(mconfig, type, tag, owner, clock, CPU_GET_INFO_NAME(ppc405gp)) -{ -} - -const device_type PPC405GP = &legacy_device_creator; - -ppc4xx_device::ppc4xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, cpu_get_info_func info) - : legacy_cpu_device(mconfig, type, tag, owner, clock, info) -{ -} - -DEFINE_LEGACY_CPU_DEVICE(PPC601, ppc601); -DEFINE_LEGACY_CPU_DEVICE(PPC602, ppc602); -DEFINE_LEGACY_CPU_DEVICE(PPC603, ppc603); -DEFINE_LEGACY_CPU_DEVICE(PPC603E, ppc603e); -DEFINE_LEGACY_CPU_DEVICE(PPC603R, ppc603r); -DEFINE_LEGACY_CPU_DEVICE(PPC604, ppc604); -DEFINE_LEGACY_CPU_DEVICE(MPC8240, mpc8240); diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h index a683f1f5fd4..3a0e9b9b2f3 100644 --- a/src/devices/cpu/powerpc/ppc.h +++ b/src/devices/cpu/powerpc/ppc.h @@ -14,9 +14,6 @@ #ifndef __PPC_H__ #define __PPC_H__ -#ifdef PPC_H_INCLUDED_FROM_PPC_C -#include -#endif #include "cpu/vtlb.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" diff --git a/src/devices/cpu/powerpc/ppc403.inc b/src/devices/cpu/powerpc/ppc403.inc deleted file mode 100644 index 054c2657142..00000000000 --- a/src/devices/cpu/powerpc/ppc403.inc +++ /dev/null @@ -1,947 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/* PowerPC 403 specific functions */ - -static void ppc403_dma_exec(int ch); - -#define DMA_CE 0x80000000 -#define DMA_CIE 0x40000000 -#define DMA_TD 0x20000000 -#define DMA_PL 0x10000000 -#define DMA_DAI 0x02000000 -#define DMA_SAI 0x01000000 -#define DMA_CP 0x00800000 -#define DMA_ETD 0x00000200 -#define DMA_TCE 0x00000100 -#define DMA_CH 0x00000080 -#define DMA_BME 0x00000040 -#define DMA_ECE 0x00000020 -#define DMA_TCD 0x00000010 -#define DMA_PCE 0x00000008 - -static SPU_RX_HANDLER spu_rx_handler; -static SPU_TX_HANDLER spu_tx_handler; -static TIMER_CALLBACK( ppc403_spu_rx_callback ); -static TIMER_CALLBACK( ppc403_spu_tx_callback ); - -static PPC_DMA_HANDLER spu_rx_dma_handler; -static PPC_DMA_HANDLER spu_tx_dma_handler; -static UINT8 *spu_rx_dma_ptr; -static UINT8 *spu_tx_dma_ptr; - -static PPC_DMA_HANDLER dma_read_handler[4]; -static PPC_DMA_HANDLER dma_write_handler[4]; -static UINT8 *dma_read_ptr[4]; -static UINT8 *dma_write_ptr[4]; - -INLINE void ppc_set_dcr(int dcr, UINT32 value) -{ - switch(dcr) - { - case DCR_BEAR: ppc.bear = value; break; - case DCR_BESR: ppc.besr = value; break; - case DCR_BR0: ppc.br[0] = value; break; - case DCR_BR1: ppc.br[1] = value; break; - case DCR_BR2: ppc.br[2] = value; break; - case DCR_BR3: ppc.br[3] = value; break; - case DCR_BR4: ppc.br[4] = value; break; - case DCR_BR5: ppc.br[5] = value; break; - case DCR_BR6: ppc.br[6] = value; break; - case DCR_BR7: ppc.br[7] = value; break; - - case DCR_EXISR: ppc.exisr &= ~value; break; - case DCR_EXIER: EXIER = value; ppc.exisr &= EXIER; break; - case DCR_IOCR: ppc.iocr = value; break; - case DCR_DMASR: break; /* TODO */ - case DCR_DMADA0: ppc.dma[0].da = value; break; - case DCR_DMADA1: ppc.dma[1].da = value; break; - case DCR_DMADA2: ppc.dma[2].da = value; break; - case DCR_DMADA3: ppc.dma[3].da = value; break; - case DCR_DMASA0: ppc.dma[0].sa = value; break; - case DCR_DMASA1: ppc.dma[1].sa = value; break; - case DCR_DMASA2: ppc.dma[2].sa = value; break; - case DCR_DMASA3: ppc.dma[3].sa = value; break; - case DCR_DMACT0: ppc.dma[0].ct = value; break; - case DCR_DMACT1: ppc.dma[1].ct = value; break; - case DCR_DMACT2: ppc.dma[2].ct = value; break; - case DCR_DMACT3: ppc.dma[3].ct = value; break; - case DCR_DMACR0: ppc.dma[0].cr = value; ppc403_dma_exec(0); break; - case DCR_DMACR1: ppc.dma[1].cr = value; ppc403_dma_exec(1); break; - case DCR_DMACR2: ppc.dma[2].cr = value; ppc403_dma_exec(2); break; - case DCR_DMACR3: ppc.dma[3].cr = value; ppc403_dma_exec(3); break; - - default: - fatalerror("ppc: set_dcr: Unimplemented DCR %X\n", dcr); - break; - } -} - -INLINE UINT32 ppc_get_dcr(int dcr) -{ - switch(dcr) - { - case DCR_BEAR: return ppc.bear; - case DCR_BESR: return ppc.besr; - case DCR_BR0: return ppc.br[0]; - case DCR_BR1: return ppc.br[1]; - case DCR_BR2: return ppc.br[2]; - case DCR_BR3: return ppc.br[3]; - case DCR_BR4: return ppc.br[4]; - case DCR_BR5: return ppc.br[5]; - case DCR_BR6: return ppc.br[6]; - case DCR_BR7: return ppc.br[7]; - case DCR_EXISR: return EXISR; - case DCR_EXIER: return EXIER; - case DCR_IOCR: return ppc.iocr; - case DCR_DMASR: return ppc.dmasr; - case DCR_DMADA0: return ppc.dma[0].da; - case DCR_DMADA1: return ppc.dma[1].da; - case DCR_DMADA2: return ppc.dma[2].da; - case DCR_DMADA3: return ppc.dma[3].da; - case DCR_DMASA0: return ppc.dma[0].sa; - case DCR_DMASA1: return ppc.dma[1].sa; - case DCR_DMASA2: return ppc.dma[2].sa; - case DCR_DMASA3: return ppc.dma[3].sa; - case DCR_DMACT0: return ppc.dma[0].ct; - case DCR_DMACT1: return ppc.dma[1].ct; - case DCR_DMACT2: return ppc.dma[2].ct; - case DCR_DMACT3: return ppc.dma[3].ct; - case DCR_DMACR0: return ppc.dma[0].cr; - case DCR_DMACR1: return ppc.dma[1].cr; - case DCR_DMACR2: return ppc.dma[2].cr; - case DCR_DMACR3: return ppc.dma[3].cr; - - default: - fatalerror("ppc: get_dcr: Unimplemented DCR %X\n", dcr); - break; - } -} - - - -#ifndef PPC_DRC -INLINE void ppc403_check_interrupts(void) -{ - if (MSR & MSR_EE) - { - if (ppc.interrupt_pending != 0) - { - if (ppc.interrupt_pending & 0x1) - { - ppc403_exception(EXCEPTION_IRQ); - } - else if (ppc.interrupt_pending & 0x2) - { - ppc403_exception(EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER); - } - else if (ppc.interrupt_pending & 0x4) - { - ppc403_exception(EXCEPTION_FIXED_INTERVAL_TIMER); - } - } - } -} - -static CPU_RESET( ppc403 ) -{ - ppc.pc = ppc.npc = 0xfffffffc; - - ppc_set_msr(0); -} - -static CPU_EXECUTE( ppc403 ) -{ - UINT32 fit_trigger_cycle; - ppc_tb_base_icount = cycles; - - fit_trigger_cycle = 0x7fffffff; - - if (ppc.fit_int_enable) - { - UINT32 tb = (UINT32)ppc.tb; - UINT32 fit_cycles = 0; - - if (ppc.tb & ppc.fit_bit) - { - fit_cycles += ppc.fit_bit; - tb += fit_cycles; - } - - fit_cycles += ppc.fit_bit - (tb & (ppc.fit_bit-1)); - - fit_trigger_cycle = ppc_icount - fit_cycles; - } - - while( ppc_icount > 0 ) - { - UINT32 opcode; - - debugger_instruction_hook(device, ppc.pc); - ppc.pc = ppc.npc; - ppc.npc += 4; - opcode = ROPCODE(ppc.pc); - - switch(opcode >> 26) - { - case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break; - case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break; - case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break; - case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break; - default: ppc.optable[opcode >> 26](opcode); break; - } - - ppc_icount--; - - /* Programmable Interval Timer (PIT) */ - if (ppc.pit_counter > 0) - { - ppc.pit_counter--; - if (ppc.pit_counter == 0) - { - if (ppc.pit_int_enable) { - ppc.interrupt_pending |= 0x2; - } - if (ppc.tcr & 0x00400000) // Automatic reload - { - ppc.pit_counter = ppc.pit; - } - } - } - - /* Fixed Interval Timer */ - if (fit_trigger_cycle != 0x7fffffff) - { - if (ppc_icount == fit_trigger_cycle) - { - if (ppc.fit_int_enable) - { - fit_trigger_cycle -= ppc.fit_bit; - ppc.interrupt_pending |= 0x4; - } - } - } - -#if 0 - /* Watchdog Timer */ - if (((UINT32)(ppc.tb) & ppc.wdt_bit) && (tblo & ppc.wdt_bit) == 0) { - switch((ppc.tsr >> 28) & 0x3) - { - case 0: ppc.tsr |= TSR_ENW; break; - case 1: ppc.tsr |= TSR_ENW; break; - case 2: - if (ppc.wdt_int_enable && (ppc.msr & MSR_CE)) { - ppc403_exception(EXCEPTION_WATCHDOG_TIMER); - } - break; - case 3: - fatalerror("PPC: Watchdog Timer caused reset\n"); - break; - } - } -#endif - - ppc403_check_interrupts(); - } - - // update timebase - ppc.tb += (ppc_tb_base_icount - ppc_icount); -} - -void ppc403_exception(int exception) -{ - switch( exception ) - { - case EXCEPTION_IRQ: /* External Interrupt */ - { - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR - if( msr & MSR_LE ) - msr |= MSR_ILE; - else - msr &= ~MSR_ILE; - ppc_set_msr(msr); - - ppc.npc = EVPR | 0x0500; - - ppc.interrupt_pending &= ~0x1; - } - break; - } - - case EXCEPTION_TRAP: /* Program exception / Trap */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.pc; - SRR1 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0700; - else - ppc.npc = EVPR | 0x0700; - break; - } - - case EXCEPTION_SYSTEM_CALL: /* System call */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0c00; - else - ppc.npc = EVPR | 0x0c00; - break; - } - - case EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER: - { - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR - if( msr & MSR_LE ) - msr |= MSR_ILE; - else - msr &= ~MSR_ILE; - ppc_set_msr(msr); - - ppc.npc = EVPR | 0x1000; - - ppc.tsr |= 0x08000000; // PIT interrupt - ppc.interrupt_pending &= ~0x2; - } - break; - } - - case EXCEPTION_FIXED_INTERVAL_TIMER: /* Fixed Interval Timer */ - { - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR - if( msr & MSR_LE ) - msr |= MSR_ILE; - else - msr &= ~MSR_ILE; - ppc_set_msr(msr); - - ppc.npc = EVPR | 0x1010; - ppc.interrupt_pending &= ~0x4; - } - break; - } - - case EXCEPTION_WATCHDOG_TIMER: /* Watchdog Timer */ - { - UINT32 msr = ppc_get_msr(); - - SRR2 = ppc.npc; - SRR3 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_CE | MSR_EE | MSR_DE | MSR_PE | MSR_DR | MSR_IR); - if (msr & MSR_LE) - msr |= MSR_ILE; - else - msr &= ~MSR_ILE; - ppc_set_msr(msr); - - ppc.npc = EVPR | 0x1020; - break; - } - - case EXCEPTION_CRITICAL_INTERRUPT: - { - UINT32 msr = ppc_get_msr(); - - SRR2 = ppc.npc; - SRR3 = msr; - - msr &= ~(MSR_WE | MSR_PR | MSR_CE | MSR_EE | MSR_DE | MSR_PE | MSR_DR | MSR_IR); - if (msr & MSR_LE) - msr |= MSR_ILE; - else - msr &= ~MSR_ILE; - ppc_set_msr(msr); - - EXISR |= 0x80000000; - ppc.npc = EVPR | 0x100; - break; - } - - default: - fatalerror("ppc: Unhandled exception %d\n", exception); - break; - } -} - -static void ppc403_set_irq_line(int irqline, int state) -{ - if (irqline >= INPUT_LINE_IRQ0 && irqline <= INPUT_LINE_IRQ4) - { - UINT32 mask = (1 << (4 - irqline)); - if( state == ASSERT_LINE) { - if( EXIER & mask ) { - ppc.exisr |= mask; - ppc.interrupt_pending |= 0x1; - - if (ppc.irq_callback) - { - ppc.irq_callback(ppc.device, irqline); - } - } - } - // clear line is used to clear the interrupt when the interrupts are level-sensitive - else if (state == CLEAR_LINE) - { - ppc.exisr &= ~mask; - } - } - else if (irqline == PPC_IRQ_SPU_RX) - { - UINT32 mask = 0x08000000; - if (state) { - if( EXIER & mask ) { - ppc.exisr |= mask; - ppc.interrupt_pending |= 0x1; - } - } - } - else if (irqline == PPC_IRQ_SPU_TX) - { - UINT32 mask = 0x04000000; - if (state) { - if( EXIER & mask ) { - ppc.exisr |= mask; - ppc.interrupt_pending |= 0x1; - } - } - } - else if (irqline == PPC_IRQ_CRITICAL) - { - if (state) { - if (EXIER & 0x80000000) { - ppc403_exception(EXCEPTION_CRITICAL_INTERRUPT); - } - } - } - else - { - fatalerror("PPC: Unknown IRQ line %d\n", irqline); - } -} - -static void ppc403_dma_set_irq_line(int dma, int state) -{ - UINT32 mask = (1 << (3 - dma)) << 20; - if( state ) { - if( EXIER & mask ) { - ppc.exisr |= mask; - ppc.interrupt_pending |= 0x1; - } - } -} -#endif - -#ifdef PPC_DRC -static void ppc403_dma_set_irq_line(int dma, int state) -{ - UINT32 mask = (1 << (3 - dma)) << 20; - if( state ) { - if( EXIER & mask ) { - ppc.exisr |= mask; - ppc.exception_pending |= 0x1; - } - } -} -#endif - - - - - - -#ifndef PPC_DRC -static void ppc_dccci(UINT32 op) -{ -} - -static void ppc_dcread(UINT32 op) -{ -} - -static void ppc_icbt(UINT32 op) -{ -} - -static void ppc_iccci(UINT32 op) -{ -} - -static void ppc_icread(UINT32 op) -{ -} - -static void ppc_rfci(UINT32 op) -{ - UINT32 msr; - ppc.npc = ppc.srr2; - msr = ppc.srr3; - ppc_set_msr( msr ); - -} -#endif - -static void ppc_mfdcr(UINT32 op) -{ - REG(RT) = ppc_get_dcr(SPR); -} - -static void ppc_mtdcr(UINT32 op) -{ - ppc_set_dcr(SPR, REG(RS)); -} - -static void ppc_wrtee(UINT32 op) -{ - if( REG(RS) & 0x8000 ) - ppc_set_msr( ppc_get_msr() | MSR_EE); - else - ppc_set_msr( ppc_get_msr() & ~MSR_EE); -} - -static void ppc_wrteei(UINT32 op) -{ - if( op & 0x8000 ) - ppc_set_msr( ppc_get_msr() | MSR_EE); - else - ppc_set_msr( ppc_get_msr() & ~MSR_EE); -} - - - -/**************************************************************************/ -/* PPC403 Serial Port */ - -static UINT8 ppc403_spu_r(UINT32 a) -{ - switch(a & 0xf) - { - case 0x0: return ppc.spu.spls | 0x6; /* transmit buffer is always empty */ - case 0x2: return ppc.spu.sphs; - case 0x4: return (ppc.spu.brd >> 8) & 0xf; - case 0x5: return (ppc.spu.brd & 0xff); - case 0x6: return ppc.spu.spctl; - case 0x7: return ppc.spu.sprc; - case 0x8: return ppc.spu.sptc; - case 0x9: return ppc.spu.sprb; - default: fatalerror("ppc: spu_r: %02X\n", a & 0xf); - } -} - -static void ppc403_spu_w(UINT32 a, UINT8 d) -{ - switch(a & 0xf) - { - case 0x0: - if( d & 0x80 ) ppc.spu.spls &= ~0x80; - if( d & 0x40 ) ppc.spu.spls &= ~0x40; - if( d & 0x20 ) ppc.spu.spls &= ~0x20; - if( d & 0x10 ) ppc.spu.spls &= ~0x10; - if( d & 0x08 ) ppc.spu.spls &= ~0x08; - break; - - case 0x2: - ppc.spu.sphs = d; - break; - - case 0x4: - ppc.spu.brd &= 0xff; - ppc.spu.brd |= (d << 8); - break; - - case 0x5: - ppc.spu.brd &= 0xff00; - ppc.spu.brd |= d; - if (ppc.iocr & 0x2) { - osd_printf_debug("ppc: SPU Baud rate: %d\n", (3686400 / (ppc.spu.brd + 1)) / 16); - } else { - osd_printf_debug("ppc: SPU Baud rate: %d\n", (33333333 / (ppc.spu.brd + 1)) / 16); - } - break; - - case 0x6: - ppc.spu.spctl = d; - break; - - case 0x7: - ppc.spu.sprc = d; - if (ppc.spu.sprc & 0x80) /* enable RX */ - { - /* - int baud_rate; - if (ppc.iocr & 0x2) { - baud_rate = (3686400 / (ppc.spu.brd + 1)) / 16; - } else { - baud_rate = (33333333 / (ppc.spu.brd + 1)) / 16; - } - */ - - /* check if serial port is hooked to a DMA channel */ - /* if so, do a DMA operation */ - if( ((((ppc.spu.sprc >> 5) & 0x3) == 2) && (ppc.dma[2].cr & DMA_CE)) || - ((((ppc.spu.sprc >> 5) & 0x3) == 3) && (ppc.dma[3].cr & DMA_CE)) ) - { - int i; - int ch = (ppc.spu.sprc >> 5) & 0x3; - // osd_printf_debug("ppc: DMA from serial port on channel %d (DA: %08X)\n", ch, ppc.dma[ch].da); - - if (spu_rx_dma_handler) - { - int length = ppc.dma[ch].ct; - - spu_rx_dma_handler(length); - - for (i=0; i < length; i++) - { - ppc.program->write_byte(ppc.dma[ch].da++, spu_rx_dma_ptr[i]); - } - } - - ppc.dmasr |= (1 << (27 - ch)); - - /* generate interrupts */ - if( ppc.dma[ch].cr & DMA_CIE ) - { - ppc403_dma_set_irq_line( ch, PULSE_LINE ); - } - - /* set receive buffer full */ - ppc.spu.spls = 0x80; - -#ifndef PPC_DRC - ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE); -#else - ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE); -#endif - } - } - else /* disable RX */ - { - } - break; - - case 0x8: - ppc.spu.sptc = d; - break; - - case 0x9: - ppc.spu.sptb = d; - ppc403_spu_tx_callback(NULL/* Machine */, NULL, cpunum_get_active()); - break; - - default: - fatalerror("ppc: spu_w: %02X, %02X\n", a & 0xf, d); - break; - } - //osd_printf_debug("spu_w: %02X, %02X at %08X\n", a & 0xf, d, ppc.pc); -} - -void ppc403_spu_rx(UINT8 data) -{ - ppc.spu.sprb = data; - - /* set receive buffer full */ - ppc.spu.spls = 0x80; - - /* generate interrupt if DMA is disabled and RBR interrupt is enabled */ - if (((ppc.spu.sprc >> 5) & 0x3) == 0x01) { -#ifndef PPC_DRC - ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE); -#else - ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE); -#endif - } -} - -static TIMER_CALLBACK( ppc403_spu_rx_callback ) -{ - if (spu_rx_handler != NULL) - { - ppc403_spu_rx(spu_rx_handler()); - } -} - -static TIMER_CALLBACK( ppc403_spu_tx_callback ) -{ - if (spu_tx_handler != NULL) - { - spu_tx_handler(ppc.spu.sptb); - - /* generate interrupt if DMA is disabled and TBR interrupt is enabled */ - if (((ppc.spu.sptc >> 5) & 0x3) == 0x01) { -#ifndef PPC_DRC - ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE); -#else - ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE); -#endif - } - } -} - -void ppc403_install_spu_rx_handler(SPU_RX_HANDLER rx_handler) -{ - spu_rx_handler = rx_handler; -} - -void ppc403_install_spu_tx_handler(SPU_TX_HANDLER tx_handler) -{ - spu_tx_handler = tx_handler; -} - - -void ppc403_spu_rx_dma(UINT8 *data, int length) -{ -} - -void ppc403_install_spu_rx_dma_handler(PPC_DMA_HANDLER rx_dma_handler, UINT8 *buffer) -{ - spu_rx_dma_handler = rx_dma_handler; - spu_rx_dma_ptr = buffer; -} - -void ppc403_install_spu_tx_dma_handler(PPC_DMA_HANDLER tx_dma_handler, UINT8 *buffer) -{ - spu_tx_dma_handler = tx_dma_handler; - spu_tx_dma_ptr = buffer; -} - -/*********************************************************************************/ - -/* PPC 403 DMA */ - -static const int dma_transfer_width[4] = { 1, 2, 4, 16 }; - -void ppc403_install_dma_read_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer) -{ - dma_read_handler[ch] = dma_handler; - dma_read_ptr[ch] = buffer; -} - -void ppc403_install_dma_write_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer) -{ - dma_write_handler[ch] = dma_handler; - dma_write_ptr[ch] = buffer; -} - -static void ppc403_dma_exec(int ch) -{ - int i; - int dai, sai, width; - - /* Is the DMA channel enabled ? */ - if( ppc.dma[ch].cr & DMA_CE ) - { - /* transfer width */ - width = dma_transfer_width[(ppc.dma[ch].cr >> 26) & 0x3]; - - if( ppc.dma[ch].cr & DMA_DAI ) - dai = width; - else - dai = 0; /* DA not incremented */ - - if( ppc.dma[ch].cr & DMA_SAI ) - sai = width; - else - sai = 0; /* SA not incremented */ - - - /* transfer mode */ - switch( (ppc.dma[ch].cr >> 21) & 0x3 ) - { - case 0: /* buffered DMA */ - if( ppc.dma[ch].cr & DMA_TD ) /* peripheral to mem */ - { - // nothing to do for now */ - } - else /* mem to peripheral */ - { - /* check if the serial port is hooked to channel 2 or 3 */ - if( (ch == 2 && ((ppc.spu.sptc >> 5) & 0x3) == 2) || - (ch == 3 && ((ppc.spu.sptc >> 5) & 0x3) == 3) ) - { - osd_printf_debug("ppc: dma_exec: DMA to serial port on channel %d (DA: %08X)\n", ch, ppc.dma[ch].da); - - if (spu_tx_dma_handler) - { - int length = ppc.dma[ch].ct; - - for( i=0; i < length; i++ ) { - spu_tx_dma_ptr[i] = ppc.program->read_byte(ppc.dma[ch].da++); - } - spu_tx_dma_handler(length); - } - -#ifndef PPC_DRC - ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE); -#else - ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE); -#endif - } - else { - fatalerror("ppc: dma_exec: buffered DMA to unknown peripheral ! (channel %d)\n", ch); - } - - } - break; - - case 1: /* fly-by DMA */ - fatalerror("ppc: dma_exec: fly-by DMA not implemented\n"); - break; - - case 2: /* software initiated mem-to-mem DMA */ - //osd_printf_debug("ppc: DMA (%d, SW mem-to-mem): SA = %08X, DA = %08X, CT = %08X\n", ch, ppc.dma[ch].sa, ppc.dma[ch].da, ppc.dma[ch].ct); - - switch(width) - { - case 1: /* Byte transfer */ - for (i=0; i < ppc.dma[ch].ct; i++) - { - UINT8 b = READ8(ppc.dma[ch].sa); - WRITE8(ppc.dma[ch].da, b); - ppc.dma[ch].sa += sai; - ppc.dma[ch].da += dai; - } - break; - case 2: /* Word transfer */ - for (i=0; i < ppc.dma[ch].ct; i++) - { - UINT16 w = READ16(ppc.dma[ch].sa); - WRITE16(ppc.dma[ch].da, w); - ppc.dma[ch].sa += sai; - ppc.dma[ch].da += dai; - } - break; - case 4: /* Double word transfer */ - for (i=0; i < ppc.dma[ch].ct; i++) - { - UINT32 d = READ32(ppc.dma[ch].sa); - WRITE32(ppc.dma[ch].da, d); - ppc.dma[ch].sa += sai; - ppc.dma[ch].da += dai; - } - break; - case 16: /* 16-byte transfer */ - for (i=0; i < ppc.dma[ch].ct; i++) - { - UINT32 d1 = READ32(ppc.dma[ch].sa+0); - UINT32 d2 = READ32(ppc.dma[ch].sa+4); - UINT32 d3 = READ32(ppc.dma[ch].sa+8); - UINT32 d4 = READ32(ppc.dma[ch].sa+12); - WRITE32(ppc.dma[ch].da+0, d1); - WRITE32(ppc.dma[ch].da+4, d2); - WRITE32(ppc.dma[ch].da+8, d3); - WRITE32(ppc.dma[ch].da+12, d4); - ppc.dma[ch].sa += 16; - ppc.dma[ch].da += 16; - } - break; - default: - fatalerror("dma: dma_exec: SW mem-to-mem DMA, width = %d\n", width); - } - break; - - case 3: /* hardware initiated mem-to-mem DMA */ - fatalerror("ppc: dma_exec: HW mem-to-mem DMA not implemented\n"); - break; - } - - ppc.dmasr |= (1 << (27 - ch)); - - /* DEBUG: check for not yet supported features */ - if( (ppc.dma[ch].cr & DMA_TCE) == 0 ) - fatalerror("ppc: dma_exec: DMA_TCE == 0\n"); - - if( ppc.dma[ch].cr & DMA_CH ) - fatalerror("ppc: dma_exec: DMA chaining not implemented\n"); - - /* generate interrupts */ - if( ppc.dma[ch].cr & DMA_CIE ) - ppc403_dma_set_irq_line( ch, PULSE_LINE ); - - } -} - -/*********************************************************************************/ - -static UINT8 ppc403_read8(address_space &space, UINT32 a) -{ - if(a >= 0x40000000 && a <= 0x4000000f) /* Serial Port */ - return ppc403_spu_r(a); - return space.read_byte(a); -} - -#define ppc403_read16 memory_read_word_32be -#define ppc403_read32 memory_read_dword_32be - -static void ppc403_write8(address_space &space, UINT32 a, UINT8 d) -{ - if( a >= 0x40000000 && a <= 0x4000000f ) /* Serial Port */ - { - ppc403_spu_w(a, d); - return; - } - space.write_byte(a, d); -} - -#define ppc403_write16 memory_write_word_32be -#define ppc403_write32 memory_write_dword_32be - -static UINT16 ppc403_read16_unaligned(address_space &space, UINT32 a) -{ - fatalerror("ppc: Unaligned read16 %08X at %08X\n", a, ppc.pc); - return 0; -} - -static UINT32 ppc403_read32_unaligned(address_space &space, UINT32 a) -{ - fatalerror("ppc: Unaligned read32 %08X at %08X\n", a, ppc.pc); - return 0; -} - -static void ppc403_write16_unaligned(address_space &space, UINT32 a, UINT16 d) -{ - fatalerror("ppc: Unaligned write16 %08X, %04X at %08X\n", a, d, ppc.pc); -} - -static void ppc403_write32_unaligned(address_space &space, UINT32 a, UINT32 d) -{ - fatalerror("ppc: Unaligned write32 %08X, %08X at %08X\n", a, d, ppc.pc); -} diff --git a/src/devices/cpu/powerpc/ppc602.inc b/src/devices/cpu/powerpc/ppc602.inc deleted file mode 100644 index 6b1998201f7..00000000000 --- a/src/devices/cpu/powerpc/ppc602.inc +++ /dev/null @@ -1,279 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -static void ppc_dsa(UINT32 op) -{ - UINT32 msr = ppc_get_msr(); - - msr &= ~(MSR_SA | MSR_EE | MSR_PR | MSR_AP); - if (ppc.esasrr & 0x8) msr |= MSR_PR; - if (ppc.esasrr & 0x4) msr |= MSR_AP; - if (ppc.esasrr & 0x2) msr |= MSR_SA; - if (ppc.esasrr & 0x1) msr |= MSR_EE; - - ppc_set_msr(msr); -} - -static void ppc_esa(UINT32 op) -{ - int sa, ee, pr, ap; - UINT32 msr = ppc_get_msr(); - - sa = (msr & MSR_SA) ? 1 : 0; - ee = (msr & MSR_EE) ? 1 : 0; - pr = (msr & MSR_PR) ? 1 : 0; - ap = (msr & MSR_AP) ? 1 : 0; - - ppc.esasrr = (pr << 3) | (ap << 2) | (sa << 1) | (ee); - - msr &= ~(MSR_EE | MSR_PR | MSR_AP); - msr |= MSR_SA; - - ppc_set_msr(msr); -} - -#ifndef PPC_DRC -static void ppc_tlbli(UINT32 op) -{ -} - -static void ppc_tlbld(UINT32 op) -{ -} -#endif - -#ifndef PPC_DRC -void ppc602_exception(int exception) -{ - switch( exception ) - { - case EXCEPTION_IRQ: /* External Interrupt */ - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0500; - else - ppc.npc = ppc.ibr | 0x0500; - - ppc.interrupt_pending &= ~0x1; - } - break; - - case EXCEPTION_DECREMENTER: /* Decrementer overflow exception */ - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0900; - else - ppc.npc = ppc.ibr | 0x0900; - - ppc.interrupt_pending &= ~0x2; - } - break; - - case EXCEPTION_TRAP: /* Program exception / Trap */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.pc; - SRR1 = (msr & 0xff73) | 0x20000; /* 0x20000 = TRAP bit */ - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0700; - else - ppc.npc = ppc.ibr | 0x0700; - } - break; - - case EXCEPTION_SYSTEM_CALL: /* System call */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = (msr & 0xff73); - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0c00; - else - ppc.npc = ppc.ibr | 0x0c00; - } - break; - - case EXCEPTION_SMI: - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x1400; - else - ppc.npc = ppc.ibr | 0x1400; - - ppc.interrupt_pending &= ~0x4; - } - break; - - - default: - fatalerror("ppc: Unhandled exception %d\n", exception); - break; - } -} - -static void ppc602_set_irq_line(int irqline, int state) -{ - if( state ) { - ppc.interrupt_pending |= 0x1; - if (ppc.irq_callback) - { - ppc.irq_callback(ppc.device, irqline); - } - } -} - -static void ppc602_set_smi_line(int state) -{ - if( state ) { - ppc.interrupt_pending |= 0x4; - } -} - -INLINE void ppc602_check_interrupts(void) -{ - if (MSR & MSR_EE) - { - if (ppc.interrupt_pending != 0) - { - if (ppc.interrupt_pending & 0x1) - { - ppc602_exception(EXCEPTION_IRQ); - } - else if (ppc.interrupt_pending & 0x2) - { - ppc602_exception(EXCEPTION_DECREMENTER); - } - else if (ppc.interrupt_pending & 0x4) - { - ppc602_exception(EXCEPTION_SMI); - } - } - } -} - -static CPU_RESET( ppc602 ) -{ - ppc.pc = ppc.npc = 0xfff00100; - - ppc_set_msr(0x40); - - ppc.hid0 = 1; - - ppc.interrupt_pending = 0; -} - -static CPU_EXECUTE( ppc602 ) -{ - int exception_type; - UINT32 opcode; - ppc_tb_base_icount = ppc_icount; - ppc_dec_base_icount = ppc_icount; - - // check if decrementer exception occurs during execution - if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC)) - { - ppc_dec_trigger_cycle = ppc_icount - DEC; - } - else - { - ppc_dec_trigger_cycle = 0x7fffffff; - } - - // MinGW's optimizer kills setjmp()/longjmp() - SETJMP_GNUC_PROTECT(); - - exception_type = setjmp(ppc.exception_jmpbuf); - if (exception_type) - { - ppc.npc = ppc.pc; - ppc602_exception(exception_type); - } - - while( ppc_icount > 0 ) - { - ppc.pc = ppc.npc; - debugger_instruction_hook(device, ppc.pc); - - if (MSR & MSR_IR) - opcode = ppc_readop_translated(ppc.program, ppc.pc); - else - opcode = ROPCODE64(ppc.pc); - - ppc.npc = ppc.pc + 4; - switch(opcode >> 26) - { - case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break; - case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break; - case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break; - case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break; - default: ppc.optable[opcode >> 26](opcode); break; - } - - ppc_icount--; - - if(ppc_icount == ppc_dec_trigger_cycle) { - ppc.interrupt_pending |= 0x2; - } - - ppc602_check_interrupts(); - } - - // update timebase - // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly - ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4); - - // update decrementer - DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2)); -} -#endif // PPC_DRC diff --git a/src/devices/cpu/powerpc/ppc603.inc b/src/devices/cpu/powerpc/ppc603.inc deleted file mode 100644 index 114728d19ce..00000000000 --- a/src/devices/cpu/powerpc/ppc603.inc +++ /dev/null @@ -1,285 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -void ppc603_exception(int exception) -{ - switch( exception ) - { - case EXCEPTION_IRQ: /* External Interrupt */ - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0500; - else - ppc.npc = 0x00000000 | 0x0500; - - ppc.interrupt_pending &= ~0x1; - } - break; - - case EXCEPTION_DECREMENTER: /* Decrementer overflow exception */ - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0900; - else - ppc.npc = 0x00000000 | 0x0900; - - ppc.interrupt_pending &= ~0x2; - } - break; - - case EXCEPTION_TRAP: /* Program exception / Trap */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.pc; - SRR1 = (msr & 0xff73) | 0x20000; /* 0x20000 = TRAP bit */ - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0700; - else - ppc.npc = 0x00000000 | 0x0700; - } - break; - - case EXCEPTION_SYSTEM_CALL: /* System call */ - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = (msr & 0xff73); - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0c00; - else - ppc.npc = 0x00000000 | 0x0c00; - } - break; - - case EXCEPTION_SMI: - if( ppc_get_msr() & MSR_EE ) { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x1400; - else - ppc.npc = 0x00000000 | 0x1400; - - ppc.interrupt_pending &= ~0x4; - } - break; - - case EXCEPTION_DSI: - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0300; - else - ppc.npc = 0x00000000 | 0x0300; - - ppc.interrupt_pending &= ~0x4; - } - break; - - case EXCEPTION_ISI: - { - UINT32 msr = ppc_get_msr(); - - SRR0 = ppc.npc; - SRR1 = msr & 0xff73; - - msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI); - if( msr & MSR_ILE ) - msr |= MSR_LE; - else - msr &= ~MSR_LE; - ppc_set_msr(msr); - - if( msr & MSR_IP ) - ppc.npc = 0xfff00000 | 0x0400; - else - ppc.npc = 0x00000000 | 0x0400; - - ppc.interrupt_pending &= ~0x4; - } - break; - - default: - fatalerror("ppc: Unhandled exception %d\n", exception); - break; - } -} - -static void ppc603_set_irq_line(int irqline, int state) -{ - if( state ) { - ppc.interrupt_pending |= 0x1; - if (ppc.irq_callback) - { - ppc.irq_callback(ppc.device, irqline); - } - } -} - -static void ppc603_set_smi_line(int state) -{ - if( state ) { - ppc.interrupt_pending |= 0x4; - } -} - -INLINE void ppc603_check_interrupts(void) -{ - if (MSR & MSR_EE) - { - if (ppc.interrupt_pending != 0) - { - if (ppc.interrupt_pending & 0x1) - { - ppc603_exception(EXCEPTION_IRQ); - } - else if (ppc.interrupt_pending & 0x2) - { - ppc603_exception(EXCEPTION_DECREMENTER); - } - else if (ppc.interrupt_pending & 0x4) - { - ppc603_exception(EXCEPTION_SMI); - } - } - } -} - -static CPU_RESET( ppc603 ) -{ - ppc.pc = ppc.npc = 0xfff00100; - - ppc_set_msr(0x40); - - ppc.hid0 = 1; - - ppc.interrupt_pending = 0; -} - - -static CPU_EXECUTE( ppc603 ) -{ - int exception_type; - UINT32 opcode; - ppc_tb_base_icount = ppc_icount; - ppc_dec_base_icount = ppc_icount + ppc.dec_frac; - - // check if decrementer exception occurs during execution - if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC)) - { - ppc_dec_trigger_cycle = ppc_icount - DEC; - } - else - { - ppc_dec_trigger_cycle = 0x7fffffff; - } - - // MinGW's optimizer kills setjmp()/longjmp() - SETJMP_GNUC_PROTECT(); - - exception_type = setjmp(ppc.exception_jmpbuf); - if (exception_type) - { - ppc.npc = ppc.pc; - ppc603_exception(exception_type); - } - - while( ppc_icount > 0 ) - { - ppc.pc = ppc.npc; - debugger_instruction_hook(device, ppc.pc); - - if (MSR & MSR_IR) - opcode = ppc_readop_translated(ppc.program, ppc.pc); - else - opcode = ROPCODE64(ppc.pc); - - ppc.npc = ppc.pc + 4; - switch(opcode >> 26) - { - case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break; - case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break; - case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break; - case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break; - default: ppc.optable[opcode >> 26](opcode); break; - } - - ppc_icount--; - - if(ppc_icount == ppc_dec_trigger_cycle) { - ppc.interrupt_pending |= 0x2; - } - - ppc603_check_interrupts(); - } - - // update timebase - // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly - ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4); - - // update decrementer - ppc.dec_frac = ((ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2)); - DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2)); -} diff --git a/src/devices/cpu/powerpc/ppc_mem.inc b/src/devices/cpu/powerpc/ppc_mem.inc deleted file mode 100644 index 0f8851e4c5c..00000000000 --- a/src/devices/cpu/powerpc/ppc_mem.inc +++ /dev/null @@ -1,421 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -#define DUMP_PAGEFAULTS 0 - -INLINE UINT8 READ8(UINT32 a) -{ - return ppc.read8(ppc.program, a); -} - -INLINE UINT16 READ16(UINT32 a) -{ - if( a & 0x1 ) - return ppc.read16_unaligned(ppc.program, a); - else - return ppc.read16(ppc.program, a); -} - -INLINE UINT32 READ32(UINT32 a) -{ - if( a & 0x3 ) - return ppc.read32_unaligned(ppc.program, a); - else - return ppc.read32(ppc.program, a); -} - -INLINE UINT64 READ64(UINT32 a) -{ - if( a & 0x7 ) - return ppc.read64_unaligned(ppc.program, a); - else - return ppc.read64(ppc.program, a); -} - -INLINE void WRITE8(UINT32 a, UINT8 d) -{ - ppc.write8(ppc.program, a, d); -} - -INLINE void WRITE16(UINT32 a, UINT16 d) -{ - if( a & 0x1 ) - ppc.write16_unaligned(ppc.program, a, d); - else - ppc.write16(ppc.program, a, d); -} - -INLINE void WRITE32(UINT32 a, UINT32 d) -{ - if( ppc.reserved ) { - if( a == ppc.reserved_address ) { - ppc.reserved = 0; - } - } - - if( a & 0x3 ) - ppc.write32_unaligned(ppc.program, a, d); - else - ppc.write32(ppc.program, a, d); -} - -INLINE void WRITE64(UINT32 a, UINT64 d) -{ - if( a & 0x7 ) - ppc.write64_unaligned(ppc.program, a, d); - else - ppc.write64(ppc.program, a, d); -} - -/***********************************************************************/ - -static UINT16 ppc_read16_unaligned(address_space &space, UINT32 a) -{ - return ((UINT16)ppc.read8(space, a+0) << 8) | ((UINT16)ppc.read8(space, a+1) << 0); -} - -static UINT32 ppc_read32_unaligned(address_space &space, UINT32 a) -{ - return ((UINT32)ppc.read8(space, a+0) << 24) | ((UINT32)ppc.read8(space, a+1) << 16) | - ((UINT32)ppc.read8(space, a+2) << 8) | ((UINT32)ppc.read8(space, a+3) << 0); -} - -static UINT64 ppc_read64_unaligned(address_space &space, UINT32 a) -{ - return ((UINT64)READ32(space, a+0) << 32) | (UINT64)(READ32(space, a+4)); -} - -static void ppc_write16_unaligned(address_space &space, UINT32 a, UINT16 d) -{ - ppc.write8(space, a+0, (UINT8)(d >> 8)); - ppc.write8(space, a+1, (UINT8)(d)); -} - -static void ppc_write32_unaligned(address_space &space, UINT32 a, UINT32 d) -{ - ppc.write8(space, a+0, (UINT8)(d >> 24)); - ppc.write8(space, a+1, (UINT8)(d >> 16)); - ppc.write8(space, a+2, (UINT8)(d >> 8)); - ppc.write8(space, a+3, (UINT8)(d >> 0)); -} - -static void ppc_write64_unaligned(address_space &space, UINT32 a, UINT64 d) -{ - ppc.write32(space, a+0, (UINT32)(d >> 32)); - ppc.write32(space, a+4, (UINT32)(d)); -} - -/***********************************************************************/ - -#define DSISR_PAGE 0x40000000 -#define DSISR_PROT 0x08000000 -#define DSISR_STORE 0x02000000 - -enum -{ - PPC_TRANSLATE_DATA = 0x0000, - PPC_TRANSLATE_CODE = 0x0001, - - PPC_TRANSLATE_READ = 0x0000, - PPC_TRANSLATE_WRITE = 0x0002, - - PPC_TRANSLATE_NOEXCEPTION = 0x0004 -}; - -static int ppc_is_protected(UINT32 pp, int flags) -{ - if (flags & PPC_TRANSLATE_WRITE) - { - if ((pp & 0x00000003) != 0x00000002) - return TRUE; - } - else - { - if ((pp & 0x00000003) == 0x00000000) - return TRUE; - } - return FALSE; -} - -static int ppc_translate_address(offs_t *addr_ptr, int flags) -{ - const BATENT *bat; - UINT32 address; - UINT32 sr, vsid, hash; - UINT32 pteg_address; - UINT32 target_pte, bl, mask; - UINT64 pte; - UINT64 *pteg_ptr[2]; - int i, hash_type; - UINT32 dsisr = DSISR_PROT; - - bat = (flags & PPC_TRANSLATE_CODE) ? ppc.ibat : ppc.dbat; - - address = *addr_ptr; - - /* first check the block address translation table */ - for (i = 0; i < 4; i++) - { - if (bat[i].u & ((MSR & MSR_PR) ? 0x00000001 : 0x00000002)) - { - bl = bat[i].u & 0x00001FFC; - mask = (~bl << 15) & 0xFFFE0000; - - if ((address & mask) == (bat[i].u & 0xFFFE0000)) - { - if (ppc_is_protected(bat[i].l, flags)) - goto exception; - - *addr_ptr = (bat[i].l & 0xFFFE0000) - | (address & ((bl << 15) | 0x0001FFFF)); - return 1; - } - } - } - - /* now try page address translation */ - sr = ppc.sr[(address >> 28) & 0x0F]; - if (sr & 0x80000000) - { - /* direct store translation */ - if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) - fatalerror("ppc: direct store translation not yet implemented\n"); - return 0; - } - else - { - /* is no execute is set? */ - if ((flags & PPC_TRANSLATE_CODE) && (sr & 0x10000000)) - goto exception; - - vsid = sr & 0x00FFFFFF; - hash = (vsid & 0x0007FFFF) ^ ((address >> 12) & 0xFFFF); - target_pte = (vsid << 7) | ((address >> 22) & 0x3F) | 0x80000000; - - /* we have to try both types of hashes */ - for (hash_type = 0; hash_type <= 1; hash_type++) - { - pteg_address = (ppc.sdr1 & 0xFFFF0000) - | (((ppc.sdr1 & 0x01FF) & (hash >> 10)) << 16) - | ((hash & 0x03FF) << 6); - - pteg_ptr[hash_type] = ppc->program->get_read_ptr(pteg_address); - if (pteg_ptr[hash_type]) - { - for (i = 0; i < 8; i++) - { - pte = pteg_ptr[hash_type][i]; - - /* is valid? */ - if (((pte >> 32) & 0xFFFFFFFF) == target_pte) - { - if (ppc_is_protected((UINT32) pte, flags)) - goto exception; - - *addr_ptr = ((UINT32) (pte & 0xFFFFF000)) - | (address & 0x0FFF); - return 1; - } - } - } - - hash ^= 0x7FFFF; - target_pte ^= 0x40; - } - - if (DUMP_PAGEFAULTS) - { - osd_printf_debug("PAGE FAULT: address=%08X PC=%08X SDR1=%08X MSR=%08X\n", address, ppc.pc, ppc.sdr1, ppc.msr); - osd_printf_debug("\n"); - - for (i = 0; i < 4; i++) - { - bl = bat[i].u & 0x00001FFC; - mask = (~bl << 15) & 0xFFFE0000; - osd_printf_debug(" BAT[%d]=%08X%08X (A & %08X = %08X)\n", i, bat[i].u, bat[i].l, - mask, bat[i].u & 0xFFFE0000); - } - osd_printf_debug("\n"); - osd_printf_debug(" VSID=%06X HASH=%05X HASH\'=%05X\n", vsid, hash, hash ^ 0x7FFFF); - - for (hash_type = 0; hash_type <= 1; hash_type++) - { - if (pteg_ptr[hash_type]) - { - for (i = 0; i < 8; i++) - { - pte = pteg_ptr[hash_type][i]; - osd_printf_debug(" PTE[%i%c]=%08X%08X\n", - i, - hash_type ? '\'' : ' ', - (unsigned) (pte >> 32), - (unsigned) (pte >> 0)); - } - } - } - } - } - - dsisr = DSISR_PAGE; - -exception: - /* lookup failure - exception */ - if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) - { - if (flags & PPC_TRANSLATE_CODE) - { - ppc_exception(EXCEPTION_ISI); - } - else - { - ppc.dar = address; - if (flags & PPC_TRANSLATE_WRITE) - ppc.dsisr = dsisr | DSISR_STORE; - else - ppc.dsisr = dsisr; - - ppc_exception(EXCEPTION_DSI); - } - } - return 0; -} - -static int ppc_translate_address_cb(address_spacenum space, offs_t *addr) -{ - int success = 1; - - if (space == AS_PROGRAM) - { - if (MSR & MSR_DR) - success = ppc_translate_address(addr, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION); - } - return success; -} - -static UINT8 ppc_read8_translated(address_space &space, offs_t address) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ); - return space.read_byte(address); -} - -static UINT16 ppc_read16_translated(address_space &space, offs_t address) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ); - return space.read_word(address); -} - -static UINT32 ppc_read32_translated(address_space &space, offs_t address) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ); - return space.read_dword(address); -} - -static UINT64 ppc_read64_translated(address_space &space, offs_t address) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ); - return space.read_qword(address); -} - -static void ppc_write8_translated(address_space &space, offs_t address, UINT8 data) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE); - space.write_byte(address, data); -} - -static void ppc_write16_translated(address_space &space, offs_t address, UINT16 data) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE); - space.write_word(address, data); -} - -static void ppc_write32_translated(address_space &space, offs_t address, UINT32 data) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE); - space.write_dword(address, data); -} - -static void ppc_write64_translated(address_space &space, offs_t address, UINT64 data) -{ - ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE); - space.write_qword(address, data); -} - -#ifndef PPC_DRC -static UINT32 ppc_readop_translated(address_space &space, offs_t address) -{ - ppc_translate_address(&address, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ); - return space.read_dword(address); -} -#endif - -/***********************************************************************/ - - -static CPU_DISASSEMBLE( ppc ) -{ - UINT32 op; - op = BIG_ENDIANIZE_INT32(*((UINT32 *) oprom)); - return ppc_dasm_one(buffer, pc, op); -} - -/***********************************************************************/ - -static CPU_READOP( ppc ) -{ - if (!(ppc.msr & MSR_IR)) - return 0; - - *value = 0; - - if (ppc_translate_address(&offset, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION)) - { - switch(size) - { - case 1: *value = ppc.program->read_byte(offset); break; - case 2: *value = ppc.program->read_word(offset); break; - case 4: *value = ppc.program->read_dword(offset); break; - case 8: *value = ppc.program->read_qword(offset); break; - } - } - - return 1; -} - -static CPU_READ( ppc ) -{ - if (!(ppc.msr & MSR_DR)) - return 0; - - *value = 0; - - if (ppc_translate_address(&offset, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION)) - { - switch(size) - { - case 1: *value = ppc.program->read_byte(offset); break; - case 2: *value = ppc.program->read_word(offset); break; - case 4: *value = ppc.program->read_dword(offset); break; - case 8: *value = ppc.program->read_qword(offset); break; - } - } - - return 1; -} - -static CPU_WRITE( ppc ) -{ - if (!(ppc.msr & MSR_DR)) - return 0; - - if (ppc_translate_address(&offset, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE | PPC_TRANSLATE_NOEXCEPTION)) - { - switch(size) - { - case 1: ppc.program->write_byte(offset, value); break; - case 2: ppc.program->write_word(offset, value); break; - case 4: ppc.program->write_dword(offset, value); break; - case 8: ppc.program->write_qword(offset, value); break; - } - } - - return 1; -} diff --git a/src/devices/cpu/powerpc/ppc_ops.h b/src/devices/cpu/powerpc/ppc_ops.h deleted file mode 100644 index b44e92a016b..00000000000 --- a/src/devices/cpu/powerpc/ppc_ops.h +++ /dev/null @@ -1,152 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -#pragma once - -#ifndef __PPC_OPS_H__ -#define __PPC_OPS_H__ - -static PPC_OPCODE ppc_opcode_common[] = -{ - /*code subcode handler */ - { 31, 266, ppc_addx }, - { 31, 266 | 512, ppc_addx }, - { 31, 10, ppc_addcx }, - { 31, 10 | 512, ppc_addcx }, - { 31, 138, ppc_addex }, - { 31, 138 | 512, ppc_addex }, - { 14, -1, ppc_addi }, - { 12, -1, ppc_addic }, - { 13, -1, ppc_addic_rc }, - { 15, -1, ppc_addis }, - { 31, 234, ppc_addmex }, - { 31, 234 | 512, ppc_addmex }, - { 31, 202, ppc_addzex }, - { 31, 202 | 512, ppc_addzex }, - { 31, 28, ppc_andx }, - { 31, 28 | 512, ppc_andx }, - { 31, 60, ppc_andcx }, - { 28, -1, ppc_andi_rc }, - { 29, -1, ppc_andis_rc }, - { 18, -1, ppc_bx }, - { 16, -1, ppc_bcx }, - { 19, 528, ppc_bcctrx }, - { 19, 16, ppc_bclrx }, - { 31, 0, ppc_cmp }, - { 11, -1, ppc_cmpi }, - { 31, 32, ppc_cmpl }, - { 10, -1, ppc_cmpli }, - { 31, 26, ppc_cntlzw }, - { 19, 257, ppc_crand }, - { 19, 129, ppc_crandc }, - { 19, 289, ppc_creqv }, - { 19, 225, ppc_crnand }, - { 19, 33, ppc_crnor }, - { 19, 449, ppc_cror }, - { 19, 417, ppc_crorc }, - { 19, 193, ppc_crxor }, - { 31, 86, ppc_dcbf }, - { 31, 470, ppc_dcbi }, - { 31, 54, ppc_dcbst }, - { 31, 278, ppc_dcbt }, - { 31, 246, ppc_dcbtst }, - { 31, 1014, ppc_dcbz }, - { 31, 491, ppc_divwx }, - { 31, 491 | 512, ppc_divwx }, - { 31, 459, ppc_divwux }, - { 31, 459 | 512, ppc_divwux }, - { 31, 854, ppc_eieio }, - { 31, 284, ppc_eqvx }, - { 31, 954, ppc_extsbx }, - { 31, 922, ppc_extshx }, - { 31, 982, ppc_icbi }, - { 19, 150, ppc_isync }, - { 34, -1, ppc_lbz }, - { 35, -1, ppc_lbzu }, - { 31, 119, ppc_lbzux }, - { 31, 87, ppc_lbzx }, - { 42, -1, ppc_lha }, - { 43, -1, ppc_lhau }, - { 31, 375, ppc_lhaux }, - { 31, 343, ppc_lhax }, - { 31, 790, ppc_lhbrx }, - { 40, -1, ppc_lhz }, - { 41, -1, ppc_lhzu }, - { 31, 311, ppc_lhzux }, - { 31, 279, ppc_lhzx }, - { 46, -1, ppc_lmw }, - { 31, 597, ppc_lswi }, - { 31, 533, ppc_lswx }, - { 31, 20, ppc_lwarx }, - { 31, 534, ppc_lwbrx }, - { 32, -1, ppc_lwz }, - { 33, -1, ppc_lwzu }, - { 31, 55, ppc_lwzux }, - { 31, 23, ppc_lwzx }, - { 19, 0, ppc_mcrf }, - { 31, 512, ppc_mcrxr }, - { 31, 19, ppc_mfcr }, - { 31, 83, ppc_mfmsr }, - { 31, 339, ppc_mfspr }, - { 31, 144, ppc_mtcrf }, - { 31, 146, ppc_mtmsr }, - { 31, 467, ppc_mtspr }, - { 31, 75, ppc_mulhwx }, - { 31, 11, ppc_mulhwux }, - { 7, -1, ppc_mulli }, - { 31, 235, ppc_mullwx }, - { 31, 235 | 512, ppc_mullwx }, - { 31, 476, ppc_nandx }, - { 31, 104, ppc_negx }, - { 31, 104 | 512, ppc_negx }, - { 31, 124, ppc_norx }, - { 31, 444, ppc_orx }, - { 31, 412, ppc_orcx }, - { 24, -1, ppc_ori }, - { 25, -1, ppc_oris }, - { 19, 50, ppc_rfi }, - { 20, -1, ppc_rlwimix }, - { 21, -1, ppc_rlwinmx }, - { 23, -1, ppc_rlwnmx }, - { 17, -1, ppc_sc }, - { 31, 24, ppc_slwx }, - { 31, 792, ppc_srawx }, - { 31, 824, ppc_srawix }, - { 31, 536, ppc_srwx }, - { 38, -1, ppc_stb }, - { 39, -1, ppc_stbu }, - { 31, 247, ppc_stbux }, - { 31, 215, ppc_stbx }, - { 44, -1, ppc_sth }, - { 31, 918, ppc_sthbrx }, - { 45, -1, ppc_sthu }, - { 31, 439, ppc_sthux }, - { 31, 407, ppc_sthx }, - { 47, -1, ppc_stmw }, - { 31, 725, ppc_stswi }, - { 31, 661, ppc_stswx }, - { 36, -1, ppc_stw }, - { 31, 662, ppc_stwbrx }, - { 31, 150, ppc_stwcx_rc }, - { 37, -1, ppc_stwu }, - { 31, 183, ppc_stwux }, - { 31, 151, ppc_stwx }, - { 31, 40, ppc_subfx }, - { 31, 40 | 512, ppc_subfx }, - { 31, 8, ppc_subfcx }, - { 31, 8 | 512, ppc_subfcx }, - { 31, 136, ppc_subfex }, - { 31, 136 | 512, ppc_subfex }, - { 8, -1, ppc_subfic }, - { 31, 232, ppc_subfmex }, - { 31, 232 | 512, ppc_subfmex }, - { 31, 200, ppc_subfzex }, - { 31, 200 | 512, ppc_subfzex }, - { 31, 598, ppc_sync }, - { 31, 4, ppc_tw }, - { 3, -1, ppc_twi }, - { 31, 316, ppc_xorx }, - { 26, -1, ppc_xori }, - { 27, -1, ppc_xoris } -}; - -#endif /* __PPC_OPS_H__ */ diff --git a/src/devices/cpu/powerpc/ppc_ops.inc b/src/devices/cpu/powerpc/ppc_ops.inc deleted file mode 100644 index 86ccd8e2225..00000000000 --- a/src/devices/cpu/powerpc/ppc_ops.inc +++ /dev/null @@ -1,2810 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/* PowerPC common opcodes */ - -// it really seems like this should be elsewhere - like maybe the floating point checks can hang out someplace else -#include - -#ifndef PPC_DRC -static void ppc_unimplemented(UINT32 op) -{ - fatalerror("ppc: Unimplemented opcode %08X at %08X\n", op, ppc.pc); -} - -static void ppc_addx(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - - REG(RT) = ra + rb; - - if( OEBIT ) { - SET_ADD_OV(REG(RT), ra, rb); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_addcx(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - - REG(RT) = ra + rb; - - SET_ADD_CA(REG(RT), ra, rb); - - if( OEBIT ) { - SET_ADD_OV(REG(RT), ra, rb); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} -#endif - -static void ppc_addex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - UINT32 carry = (XER >> 29) & 0x1; - UINT32 tmp; - - tmp = rb + carry; - REG(RT) = ra + tmp; - - if( ADD_CA(tmp, rb, carry) || ADD_CA(REG(RT), ra, tmp) ) - XER |= XER_CA; - else - XER &= ~XER_CA; - - if( OEBIT ) { - SET_ADD_OV(REG(RT), ra, rb); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -#ifndef PPC_DRC -static void ppc_addi(UINT32 op) -{ - UINT32 i = SIMM16; - UINT32 a = RA; - - if( a ) - i += REG(a); - - REG(RT) = i; -} - -static void ppc_addic(UINT32 op) -{ - UINT32 i = SIMM16; - UINT32 ra = REG(RA); - - REG(RT) = ra + i; - - if( ADD_CA(REG(RT), ra, i) ) - XER |= XER_CA; - else - XER &= ~XER_CA; -} - -static void ppc_addic_rc(UINT32 op) -{ - UINT32 i = SIMM16; - UINT32 ra = REG(RA); - - REG(RT) = ra + i; - - if( ADD_CA(REG(RT), ra, i) ) - XER |= XER_CA; - else - XER &= ~XER_CA; - - SET_CR0(REG(RT)); -} - -static void ppc_addis(UINT32 op) -{ - UINT32 i = UIMM16 << 16; - UINT32 a = RA; - - if( a ) - i += REG(a); - - REG(RT) = i; -} -#endif - -static void ppc_addmex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 carry = (XER >> 29) & 0x1; - UINT32 tmp; - - tmp = ra + carry; - REG(RT) = tmp + -1; - - if( ADD_CA(tmp, ra, carry) || ADD_CA(REG(RT), tmp, -1) ) - XER |= XER_CA; - else - XER &= ~XER_CA; - - if( OEBIT ) { - SET_ADD_OV(REG(RT), ra, carry - 1); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_addzex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 carry = (XER >> 29) & 0x1; - - REG(RT) = ra + carry; - - if( ADD_CA(REG(RT), ra, carry) ) - XER |= XER_CA; - else - XER &= ~XER_CA; - - if( OEBIT ) { - SET_ADD_OV(REG(RT), ra, carry); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -#ifndef PPC_DRC -static void ppc_andx(UINT32 op) -{ - REG(RA) = REG(RS) & REG(RB); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_andcx(UINT32 op) -{ - REG(RA) = REG(RS) & ~REG(RB); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_andi_rc(UINT32 op) -{ - UINT32 i = UIMM16; - - REG(RA) = REG(RS) & i; - - SET_CR0(REG(RA)); -} - -static void ppc_andis_rc(UINT32 op) -{ - UINT32 i = UIMM16 << 16; - - REG(RA) = REG(RS) & i; - - SET_CR0(REG(RA)); -} - -static void ppc_bx(UINT32 op) -{ - INT32 li = op & 0x3fffffc; - if( li & 0x2000000 ) - li |= 0xfc000000; - - if( AABIT ) { - ppc.npc = li; - } else { - ppc.npc = ppc.pc + li; - } - - if( LKBIT ) { - LR = ppc.pc + 4; - } -} - -static void ppc_bcx(UINT32 op) -{ - int condition = check_condition_code(BO, BI); - - if( condition ) { - if( AABIT ) { - ppc.npc = SIMM16 & ~0x3; - } else { - ppc.npc = ppc.pc + (SIMM16 & ~0x3); - } - } - - if( LKBIT ) { - LR = ppc.pc + 4; - } -} - -static void ppc_bcctrx(UINT32 op) -{ - int condition = check_condition_code(BO, BI); - - if( condition ) { - ppc.npc = CTR & ~0x3; - } - - if( LKBIT ) { - LR = ppc.pc + 4; - } -} - -static void ppc_bclrx(UINT32 op) -{ - int condition = check_condition_code(BO, BI); - - if( condition ) { - ppc.npc = LR & ~0x3; - } - - if( LKBIT ) { - LR = ppc.pc + 4; - } -} - -static void ppc_cmp(UINT32 op) -{ - INT32 ra = REG(RA); - INT32 rb = REG(RB); - int d = CRFD; - - if( ra < rb ) - CR(d) = 0x8; - else if( ra > rb ) - CR(d) = 0x4; - else - CR(d) = 0x2; - - if( XER & XER_SO ) - CR(d) |= 0x1; -} - -static void ppc_cmpi(UINT32 op) -{ - INT32 ra = REG(RA); - INT32 i = SIMM16; - int d = CRFD; - - if( ra < i ) - CR(d) = 0x8; - else if( ra > i ) - CR(d) = 0x4; - else - CR(d) = 0x2; - - if( XER & XER_SO ) - CR(d) |= 0x1; -} - -static void ppc_cmpl(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - int d = CRFD; - - if( ra < rb ) - CR(d) = 0x8; - else if( ra > rb ) - CR(d) = 0x4; - else - CR(d) = 0x2; - - if( XER & XER_SO ) - CR(d) |= 0x1; -} - -static void ppc_cmpli(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 i = UIMM16; - int d = CRFD; - - if( ra < i ) - CR(d) = 0x8; - else if( ra > i ) - CR(d) = 0x4; - else - CR(d) = 0x2; - - if( XER & XER_SO ) - CR(d) |= 0x1; -} - -static void ppc_cntlzw(UINT32 op) -{ - int n = 0; - int t = RT; - UINT32 m = 0x80000000; - - while(n < 32) - { - if( REG(t) & m ) - break; - m >>= 1; - n++; - } - - REG(RA) = n; - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} -#endif - -static void ppc_crand(UINT32 op) -{ - int bit = RT; - int b = CRBIT(RA) & CRBIT(RB); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_crandc(UINT32 op) -{ - int bit = RT; - int b = CRBIT(RA) & ~CRBIT(RB); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_creqv(UINT32 op) -{ - int bit = RT; - int b = ~(CRBIT(RA) ^ CRBIT(RB)); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_crnand(UINT32 op) -{ - int bit = RT; - int b = ~(CRBIT(RA) & CRBIT(RB)); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_crnor(UINT32 op) -{ - int bit = RT; - int b = ~(CRBIT(RA) | CRBIT(RB)); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_cror(UINT32 op) -{ - int bit = RT; - int b = CRBIT(RA) | CRBIT(RB); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_crorc(UINT32 op) -{ - int bit = RT; - int b = CRBIT(RA) | ~CRBIT(RB); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -static void ppc_crxor(UINT32 op) -{ - int bit = RT; - int b = CRBIT(RA) ^ CRBIT(RB); - if( b & 0x1 ) - CR(bit / 4) |= _BIT(3-(bit % 4)); - else - CR(bit / 4) &= ~_BIT(3-(bit % 4)); -} - -#ifndef PPC_DRC -static void ppc_dcbf(UINT32 op) -{ -} - -static void ppc_dcbi(UINT32 op) -{ -} - -static void ppc_dcbst(UINT32 op) -{ -} - -static void ppc_dcbt(UINT32 op) -{ -} - -static void ppc_dcbtst(UINT32 op) -{ -} - -static void ppc_dcbz(UINT32 op) -{ -} -#endif - -static void ppc_divwx(UINT32 op) -{ - if( REG(RB) == 0 && REG(RA) < 0x80000000 ) - { - REG(RT) = 0; - if( OEBIT ) { - XER |= XER_SO | XER_OV; - } - } - else if( REG(RB) == 0 || (REG(RB) == 0xffffffff && REG(RA) == 0x80000000) ) - { - REG(RT) = 0xffffffff; - if( OEBIT ) { - XER |= XER_SO | XER_OV; - } - } - else - { - REG(RT) = (INT32)REG(RA) / (INT32)REG(RB); - if( OEBIT ) { - XER &= ~XER_OV; - } - } - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_divwux(UINT32 op) -{ - if( REG(RB) == 0 ) - { - REG(RT) = 0; - if( OEBIT ) { - XER |= XER_SO | XER_OV; - } - } - else - { - REG(RT) = (UINT32)REG(RA) / (UINT32)REG(RB); - if( OEBIT ) { - XER &= ~XER_OV; - } - } - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -#ifndef PPC_DRC -static void ppc_eieio(UINT32 op) -{ -} - -static void ppc_eqvx(UINT32 op) -{ - REG(RA) = ~(REG(RS) ^ REG(RB)); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_extsbx(UINT32 op) -{ - REG(RA) = (INT32)(INT8)REG(RS); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_extshx(UINT32 op) -{ - REG(RA) = (INT32)(INT16)REG(RS); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_icbi(UINT32 op) -{ -} - -static void ppc_isync(UINT32 op) -{ -} - -static void ppc_lbz(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - REG(RT) = (UINT32)READ8(ea); -} - -static void ppc_lbzu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - REG(RT) = (UINT32)READ8(ea); - REG(RA) = ea; -} - -static void ppc_lbzux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - REG(RT) = (UINT32)READ8(ea); - REG(RA) = ea; -} - -static void ppc_lbzx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - REG(RT) = (UINT32)READ8(ea); -} - -static void ppc_lha(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - REG(RT) = (INT32)(INT16)READ16(ea); -} - -static void ppc_lhau(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - REG(RT) = (INT32)(INT16)READ16(ea); - REG(RA) = ea; -} - -static void ppc_lhaux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - REG(RT) = (INT32)(INT16)READ16(ea); - REG(RA) = ea; -} - -static void ppc_lhax(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - REG(RT) = (INT32)(INT16)READ16(ea); -} - -static void ppc_lhbrx(UINT32 op) -{ - UINT32 ea; - UINT16 w; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - w = READ16(ea); - REG(RT) = (UINT32)BYTE_REVERSE16(w); -} - -static void ppc_lhz(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - REG(RT) = (UINT32)READ16(ea); -} - -static void ppc_lhzu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - REG(RT) = (UINT32)READ16(ea); - REG(RA) = ea; -} - -static void ppc_lhzux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - REG(RT) = (UINT32)READ16(ea); - REG(RA) = ea; -} - -static void ppc_lhzx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - REG(RT) = (UINT32)READ16(ea); -} -#endif - -static void ppc_lmw(UINT32 op) -{ - int r = RT; - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - while( r <= 31 ) - { - REG(r) = READ32(ea); - ea += 4; - r++; - } -} - -static void ppc_lswi(UINT32 op) -{ - int n, r, i; - UINT32 ea = 0; - if( RA != 0 ) - ea = REG(RA); - - if( RB == 0 ) - n = 32; - else - n = RB; - - r = RT - 1; - i = 0; - - while(n > 0) - { - if (i == 0) { - r = (r + 1) % 32; - REG(r) = 0; - } - REG(r) |= ((READ8(ea) & 0xff) << (24 - i)); - i += 8; - if (i == 32) { - i = 0; - } - ea++; - n--; - } -} - -static void ppc_lswx(UINT32 op) -{ - int n, r, i; - UINT32 ea = 0; - if( RA != 0 ) - ea = REG(RA); - - ea += REG(RB); - - n = ppc.xer & 0x7f; - - r = RT - 1; - i = 0; - - while(n > 0) - { - if (i == 0) { - r = (r + 1) % 32; - REG(r) = 0; - } - REG(r) |= ((READ8(ea) & 0xff) << (24 - i)); - i += 8; - if (i == 32) { - i = 0; - } - ea++; - n--; - } -} - -static void ppc_lwarx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - ppc.reserved_address = ea; - ppc.reserved = 1; - - REG(RT) = READ32(ea); -} - -#ifndef PPC_DRC -static void ppc_lwbrx(UINT32 op) -{ - UINT32 ea; - UINT32 w; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - w = READ32(ea); - REG(RT) = BYTE_REVERSE32(w); -} - -static void ppc_lwz(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - REG(RT) = READ32(ea); -} - -static void ppc_lwzu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - REG(RT) = READ32(ea); - REG(RA) = ea; -} - -static void ppc_lwzux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - REG(RT) = READ32(ea); - REG(RA) = ea; -} - -static void ppc_lwzx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - REG(RT) = READ32(ea); -} - -static void ppc_mcrf(UINT32 op) -{ - CR(RT >> 2) = CR(RA >> 2); -} - -static void ppc_mcrxr(UINT32 op) -{ - CR(RT >> 2) = (XER >> 28) & 0x0F; - XER &= ~0xf0000000; -} - -static void ppc_mfcr(UINT32 op) -{ - REG(RT) = ppc_get_cr(); -} - -static void ppc_mfmsr(UINT32 op) -{ - REG(RT) = ppc_get_msr(); -} - -static void ppc_mfspr(UINT32 op) -{ - REG(RT) = ppc_get_spr(SPR); -} -#endif - -static void ppc_mtcrf(UINT32 op) -{ - int fxm = FXM; - int t = RT; - - if( fxm & 0x80 ) CR(0) = (REG(t) >> 28) & 0xf; - if( fxm & 0x40 ) CR(1) = (REG(t) >> 24) & 0xf; - if( fxm & 0x20 ) CR(2) = (REG(t) >> 20) & 0xf; - if( fxm & 0x10 ) CR(3) = (REG(t) >> 16) & 0xf; - if( fxm & 0x08 ) CR(4) = (REG(t) >> 12) & 0xf; - if( fxm & 0x04 ) CR(5) = (REG(t) >> 8) & 0xf; - if( fxm & 0x02 ) CR(6) = (REG(t) >> 4) & 0xf; - if( fxm & 0x01 ) CR(7) = (REG(t) >> 0) & 0xf; -} - -#ifndef PPC_DRC -static void ppc_mtmsr(UINT32 op) -{ - ppc_set_msr(REG(RS)); -} - -static void ppc_mtspr(UINT32 op) -{ - ppc_set_spr(SPR, REG(RS)); -} - -static void ppc_mulhwx(UINT32 op) -{ - INT64 ra = (INT64)(INT32)REG(RA); - INT64 rb = (INT64)(INT32)REG(RB); - - REG(RT) = (UINT32)((ra * rb) >> 32); - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_mulhwux(UINT32 op) -{ - UINT64 ra = (UINT64)REG(RA); - UINT64 rb = (UINT64)REG(RB); - - REG(RT) = (UINT32)((ra * rb) >> 32); - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_mulli(UINT32 op) -{ - INT32 ra = (INT32)REG(RA); - INT32 i = SIMM16; - - REG(RT) = ra * i; -} - -static void ppc_mullwx(UINT32 op) -{ - INT64 ra = (INT64)(INT32)REG(RA); - INT64 rb = (INT64)(INT32)REG(RB); - INT64 r; - - r = ra * rb; - REG(RT) = (UINT32)r; - - if( OEBIT ) { - XER &= ~XER_OV; - - if( r != (INT64)(INT32)r ) - XER |= XER_OV | XER_SO; - } - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_nandx(UINT32 op) -{ - REG(RA) = ~(REG(RS) & REG(RB)); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_negx(UINT32 op) -{ - REG(RT) = -REG(RA); - - if( OEBIT ) { - if( REG(RT) == 0x80000000 ) - XER |= XER_OV | XER_SO; - else - XER &= ~XER_OV; - } - - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_norx(UINT32 op) -{ - REG(RA) = ~(REG(RS) | REG(RB)); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_orx(UINT32 op) -{ - REG(RA) = REG(RS) | REG(RB); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_orcx(UINT32 op) -{ - REG(RA) = REG(RS) | ~REG(RB); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_ori(UINT32 op) -{ - REG(RA) = REG(RS) | UIMM16; -} - -static void ppc_oris(UINT32 op) -{ - REG(RA) = REG(RS) | (UIMM16 << 16); -} - -static void ppc_rfi(UINT32 op) -{ - UINT32 msr; - ppc.npc = ppc_get_spr(SPR_SRR0); - msr = ppc_get_spr(SPR_SRR1); - ppc_set_msr( msr ); -} - -static void ppc_rlwimix(UINT32 op) -{ - UINT32 r; - UINT32 mask = GET_ROTATE_MASK(MB, ME); - UINT32 rs = REG(RS); - int sh = SH; - - r = (rs << sh) | (rs >> (32-sh)); - REG(RA) = (REG(RA) & ~mask) | (r & mask); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_rlwinmx(UINT32 op) -{ - UINT32 r; - UINT32 mask = GET_ROTATE_MASK(MB, ME); - UINT32 rs = REG(RS); - int sh = SH; - - r = (rs << sh) | (rs >> (32-sh)); - REG(RA) = r & mask; - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_rlwnmx(UINT32 op) -{ - UINT32 r; - UINT32 mask = GET_ROTATE_MASK(MB, ME); - UINT32 rs = REG(RS); - int sh = REG(RB) & 0x1f; - - r = (rs << sh) | (rs >> (32-sh)); - REG(RA) = r & mask; - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} -#endif - -#ifndef PPC_DRC -static void ppc_sc(UINT32 op) -{ - if (ppc.is603) { - ppc603_exception(EXCEPTION_SYSTEM_CALL); - } - if (ppc.is602) { - ppc602_exception(EXCEPTION_SYSTEM_CALL); - } - if (IS_PPC403()) { - ppc403_exception(EXCEPTION_SYSTEM_CALL); - } -} -#endif - -static void ppc_slwx(UINT32 op) -{ - int sh = REG(RB) & 0x3f; - - if( sh > 31 ) { - REG(RA) = 0; - } - else { - REG(RA) = REG(RS) << sh; - } - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_srawx(UINT32 op) -{ - int sh = REG(RB) & 0x3f; - - XER &= ~XER_CA; - - if( sh > 31 ) { - if (REG(RS) & 0x80000000) - REG(RA) = 0xffffffff; - else - REG(RA) = 0; - if( REG(RA) ) - XER |= XER_CA; - } - else { - REG(RA) = (INT32)(REG(RS)) >> sh; - if( ((INT32)(REG(RS)) < 0) && (REG(RS) & BITMASK_0(sh)) ) - XER |= XER_CA; - } - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_srawix(UINT32 op) -{ - int sh = SH; - - XER &= ~XER_CA; - if( ((INT32)(REG(RS)) < 0) && (REG(RS) & BITMASK_0(sh)) ) - XER |= XER_CA; - - REG(RA) = (INT32)(REG(RS)) >> sh; - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_srwx(UINT32 op) -{ - int sh = REG(RB) & 0x3f; - - if( sh > 31 ) { - REG(RA) = 0; - } - else { - REG(RA) = REG(RS) >> sh; - } - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -#ifndef PPC_DRC -static void ppc_stb(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - WRITE8(ea, (UINT8)REG(RS)); -} - -static void ppc_stbu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - WRITE8(ea, (UINT8)REG(RS)); - REG(RA) = ea; -} - -static void ppc_stbux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - WRITE8(ea, (UINT8)REG(RS)); - REG(RA) = ea; -} - -static void ppc_stbx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - WRITE8(ea, (UINT8)REG(RS)); -} - -static void ppc_sth(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - WRITE16(ea, (UINT16)REG(RS)); -} - -static void ppc_sthbrx(UINT32 op) -{ - UINT32 ea; - UINT16 w; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - w = REG(RS); - WRITE16(ea, (UINT16)BYTE_REVERSE16(w)); -} - -static void ppc_sthu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - WRITE16(ea, (UINT16)REG(RS)); - REG(RA) = ea; -} - -static void ppc_sthux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - WRITE16(ea, (UINT16)REG(RS)); - REG(RA) = ea; -} - -static void ppc_sthx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - WRITE16(ea, (UINT16)REG(RS)); -} -#endif - -static void ppc_stmw(UINT32 op) -{ - UINT32 ea; - int r = RS; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - while( r <= 31 ) - { - WRITE32(ea, REG(r)); - ea += 4; - r++; - } -} - -static void ppc_stswi(UINT32 op) -{ - int n, r, i; - UINT32 ea = 0; - if( RA != 0 ) - ea = REG(RA); - - if( RB == 0 ) - n = 32; - else - n = RB; - - r = RT - 1; - i = 0; - - while(n > 0) - { - if (i == 0) { - r = (r + 1) % 32; - } - WRITE8(ea, (REG(r) >> (24-i)) & 0xff); - i += 8; - if (i == 32) { - i = 0; - } - ea++; - n--; - } -} - -static void ppc_stswx(UINT32 op) -{ - int n, r, i; - UINT32 ea = 0; - if( RA != 0 ) - ea = REG(RA); - - ea += REG(RB); - - n = ppc.xer & 0x7f; - - r = RT - 1; - i = 0; - - while(n > 0) - { - if (i == 0) { - r = (r + 1) % 32; - } - WRITE8(ea, (REG(r) >> (24-i)) & 0xff); - i += 8; - if (i == 32) { - i = 0; - } - ea++; - n--; - } -} - -#ifndef PPC_DRC -static void ppc_stw(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = SIMM16; - else - ea = REG(RA) + SIMM16; - - WRITE32(ea, REG(RS)); -} - -static void ppc_stwbrx(UINT32 op) -{ - UINT32 ea; - UINT32 w; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - w = REG(RS); - WRITE32(ea, BYTE_REVERSE32(w)); -} -#endif - -static void ppc_stwcx_rc(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - if( ppc.reserved ) { - WRITE32(ea, REG(RS)); - - ppc.reserved = 0; - ppc.reserved_address = 0; - - CR(0) = 0x2; - if( XER & XER_SO ) - CR(0) |= 0x1; - } else { - CR(0) = 0; - if( XER & XER_SO ) - CR(0) |= 0x1; - } -} - -#ifndef PPC_DRC -static void ppc_stwu(UINT32 op) -{ - UINT32 ea = REG(RA) + SIMM16; - - WRITE32(ea, REG(RS)); - REG(RA) = ea; -} - -static void ppc_stwux(UINT32 op) -{ - UINT32 ea = REG(RA) + REG(RB); - - WRITE32(ea, REG(RS)); - REG(RA) = ea; -} - -static void ppc_stwx(UINT32 op) -{ - UINT32 ea; - - if( RA == 0 ) - ea = REG(RB); - else - ea = REG(RA) + REG(RB); - - WRITE32(ea, REG(RS)); -} - -static void ppc_subfx(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - REG(RT) = rb - ra; - - if( OEBIT ) { - SET_SUB_OV(REG(RT), rb, ra); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} -#endif - -static void ppc_subfcx(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - REG(RT) = rb - ra; - - SET_SUB_CA(REG(RT), rb, ra); - - if( OEBIT ) { - SET_SUB_OV(REG(RT), rb, ra); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -#ifndef PPC_DRC -static void ppc_subfex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 rb = REG(RB); - UINT32 carry = (XER >> 29) & 0x1; - UINT32 r; - - r = ~ra + carry; - REG(RT) = rb + r; - - SET_ADD_CA(r, ~ra, carry); /* step 1 carry */ - if( REG(RT) < r ) /* step 2 carry */ - XER |= XER_CA; - - if( OEBIT ) { - SET_SUB_OV(REG(RT), rb, ra); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_subfic(UINT32 op) -{ - UINT32 i = SIMM16; - UINT32 ra = REG(RA); - - REG(RT) = i - ra; - - SET_SUB_CA(REG(RT), i, ra); -} -#endif - -static void ppc_subfmex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 carry = (XER >> 29) & 0x1; - UINT32 r; - - r = ~ra + carry; - REG(RT) = r - 1; - - SET_SUB_CA(r, ~ra, carry); /* step 1 carry */ - if( REG(RT) < r ) - XER |= XER_CA; /* step 2 carry */ - - if( OEBIT ) { - SET_SUB_OV(REG(RT), -1, ra); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -static void ppc_subfzex(UINT32 op) -{ - UINT32 ra = REG(RA); - UINT32 carry = (XER >> 29) & 0x1; - - REG(RT) = ~ra + carry; - - SET_ADD_CA(REG(RT), ~ra, carry); - - if( OEBIT ) { - SET_SUB_OV(REG(RT), 0, REG(RA)); - } - if( RCBIT ) { - SET_CR0(REG(RT)); - } -} - -#ifndef PPC_DRC -static void ppc_sync(UINT32 op) -{ -} -#endif - -#ifndef PPC_DRC -static void ppc_tw(UINT32 op) -{ - int exception = 0; - INT32 a = REG(RA); - INT32 b = REG(RB); - int to = RT; - - if( (a < b) && (to & 0x10) ) { - exception = 1; - } - if( (a > b) && (to & 0x08) ) { - exception = 1; - } - if( (a == b) && (to & 0x04) ) { - exception = 1; - } - if( ((UINT32)a < (UINT32)b) && (to & 0x02) ) { - exception = 1; - } - if( ((UINT32)a > (UINT32)b) && (to & 0x01) ) { - exception = 1; - } - - if (exception) { - if (ppc.is603) { - ppc603_exception(EXCEPTION_TRAP); - } - if (ppc.is602) { - ppc602_exception(EXCEPTION_TRAP); - } - if (IS_PPC403()) { - ppc403_exception(EXCEPTION_TRAP); - } - } -} -#endif - -#ifndef PPC_DRC -static void ppc_twi(UINT32 op) -{ - int exception = 0; - INT32 a = REG(RA); - INT32 i = SIMM16; - int to = RT; - - if( (a < i) && (to & 0x10) ) { - exception = 1; - } - if( (a > i) && (to & 0x08) ) { - exception = 1; - } - if( (a == i) && (to & 0x04) ) { - exception = 1; - } - if( ((UINT32)a < (UINT32)i) && (to & 0x02) ) { - exception = 1; - } - if( ((UINT32)a > (UINT32)i) && (to & 0x01) ) { - exception = 1; - } - - if (exception) { - if (ppc.is603) { - ppc603_exception(EXCEPTION_TRAP); - } - if (ppc.is602) { - ppc602_exception(EXCEPTION_TRAP); - } - if (IS_PPC403()) { - ppc403_exception(EXCEPTION_TRAP); - } - } -} -#endif - -#ifndef PPC_DRC -static void ppc_xorx(UINT32 op) -{ - REG(RA) = REG(RS) ^ REG(RB); - - if( RCBIT ) { - SET_CR0(REG(RA)); - } -} - -static void ppc_xori(UINT32 op) -{ - REG(RA) = REG(RS) ^ UIMM16; -} - -static void ppc_xoris(UINT32 op) -{ - REG(RA) = REG(RS) ^ (UIMM16 << 16); -} - - - -static void ppc_invalid(UINT32 op) -{ - fatalerror("ppc: Invalid opcode %08X PC : %X\n", op, ppc.pc); -} -#endif - - -// Everything below is new from AJG - -//////////////////////////// -// !here are the 6xx ops! // -//////////////////////////// - -#define DOUBLE_SIGN (U64(0x8000000000000000)) -#define DOUBLE_EXP (U64(0x7ff0000000000000)) -#define DOUBLE_FRAC (U64(0x000fffffffffffff)) -#define DOUBLE_ZERO (0) - -/* - Floating point operations. -*/ - -INLINE int is_nan_double(FPR x) -{ - return( ((x.id & DOUBLE_EXP) == DOUBLE_EXP) && - ((x.id & DOUBLE_FRAC) != DOUBLE_ZERO) ); -} - -INLINE int is_qnan_double(FPR x) -{ - return( ((x.id & DOUBLE_EXP) == DOUBLE_EXP) && - ((x.id & U64(0x0007fffffffffff)) == U64(0x000000000000000)) && - ((x.id & U64(0x000800000000000)) == U64(0x000800000000000)) ); -} - -INLINE int is_snan_double(FPR x) -{ - return( ((x.id & DOUBLE_EXP) == DOUBLE_EXP) && - ((x.id & DOUBLE_FRAC) != DOUBLE_ZERO) && - ((x.id & U64(0x0008000000000000)) == DOUBLE_ZERO) ); -} - -INLINE int is_infinity_double(FPR x) -{ - return( ((x.id & DOUBLE_EXP) == DOUBLE_EXP) && - ((x.id & DOUBLE_FRAC) == DOUBLE_ZERO) ); -} - -INLINE int is_normalized_double(FPR x) -{ - UINT64 exp; - - exp = (x.id & DOUBLE_EXP) >> 52; - - return (exp >= 1) && (exp <= 2046); -} - -INLINE int is_denormalized_double(FPR x) -{ - return( ((x.id & DOUBLE_EXP) == 0) && - ((x.id & DOUBLE_FRAC) != DOUBLE_ZERO) ); -} - -INLINE int sign_double(FPR x) -{ - return ((x.id & DOUBLE_SIGN) != 0); -} - -INLINE INT64 round_to_nearest(FPR f) -{ - if (f.fd >= 0) - { - return (INT64)(f.fd + 0.5); - } - else - { - return -(INT64)(-f.fd + 0.5); - } -} - -INLINE INT64 round_toward_zero(FPR f) -{ - return (INT64)(f.fd); -} - -INLINE INT64 round_toward_positive_infinity(FPR f) -{ - double r = ceil(f.fd); - return (INT64)(r); -} - -INLINE INT64 round_toward_negative_infinity(FPR f) -{ - double r = floor(f.fd); - return (INT64)(r); -} - - -INLINE void set_fprf(FPR f) -{ - UINT32 fprf; - - // see page 3-30, 3-31 - - if (is_qnan_double(f)) - { - fprf = 0x11; - } - else if (is_infinity_double(f)) - { - if (sign_double(f)) // -INF - fprf = 0x09; - else // +INF - fprf = 0x05; - } - else if (is_normalized_double(f)) - { - if (sign_double(f)) // -Normalized - fprf = 0x08; - else // +Normalized - fprf = 0x04; - } - else if (is_denormalized_double(f)) - { - if (sign_double(f)) // -Denormalized - fprf = 0x18; - else // +Denormalized - fprf = 0x14; - } - else // Zero - { - if (sign_double(f)) // -Zero - fprf = 0x12; - else // +Zero - fprf = 0x02; - } - - ppc.fpscr &= ~0x0001f000; - ppc.fpscr |= (fprf << 12); -} - - - -#define SET_VXSNAN(a, b) if (is_snan_double(a) || is_snan_double(b)) ppc.fpscr |= 0x80000000 -#define SET_VXSNAN_1(c) if (is_snan_double(c)) ppc.fpscr |= 0x80000000 - - - - -static void ppc_lfs(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - if(a) - ea += REG(a); - - f.i = READ32(ea); - FPR(t).fd = (double)(f.f); -} - -static void ppc_lfsu(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - ea += REG(a); - - f.i = READ32(ea); - FPR(t).fd = (double)(f.f); - - REG(a) = ea; -} - -#ifndef PPC_DRC -static void ppc_lfd(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - - if(a) - ea += REG(a); - - FPR(t).id = READ64(ea); -} - -static void ppc_lfdu(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 d = RD; - - ea += REG(a); - - FPR(d).id = READ64(ea); - - REG(a) = ea; -} -#endif - -static void ppc_stfs(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - if(a) - ea += REG(a); - - f.f = (float)(FPR(t).fd); - WRITE32(ea, f.i); -} - -static void ppc_stfsu(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - ea += REG(a); - - f.f = (float)(FPR(t).fd); - WRITE32(ea, f.i); - - REG(a) = ea; -} - -#ifndef PPC_DRC -static void ppc_stfd(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - - if(a) - ea += REG(a); - - WRITE64(ea, FPR(t).id); -} - -static void ppc_stfdu(UINT32 op) -{ - UINT32 ea = SIMM16; - UINT32 a = RA; - UINT32 t = RT; - - ea += REG(a); - - WRITE64(ea, FPR(t).id); - - REG(a) = ea; -} - -static void ppc_lfdux(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 d = RD; - - ea += REG(a); - - FPR(d).id = READ64(ea); - - REG(a) = ea; -} - -static void ppc_lfdx(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 d = RD; - - if(a) - ea += REG(a); - - FPR(d).id = READ64(ea); -} -#endif - -static void ppc_lfsux(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - ea += REG(a); - - f.i = READ32(ea); - FPR(t).fd = (double)(f.f); - - REG(a) = ea; -} - -static void ppc_lfsx(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - if(a) - ea += REG(a); - - f.i = READ32(ea); - FPR(t).fd = (double)(f.f); -} - -static void ppc_mfsr(UINT32 op) -{ - UINT32 sr = (op >> 16) & 15; - UINT32 t = RT; - - CHECK_SUPERVISOR(); - - REG(t) = ppc.sr[sr]; -} - -static void ppc_mfsrin(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_SUPERVISOR(); - - REG(t) = ppc.sr[REG(b) >> 28]; -} - -static void ppc_mftb(UINT32 op) -{ - UINT32 x = SPRF; - - switch(x) - { - case 268: REG(RT) = (UINT32)(ppc_read_timebase()); break; - case 269: REG(RT) = (UINT32)(ppc_read_timebase() >> 32); break; - default: fatalerror("ppc: Invalid timebase register %d at %08X\n", x, ppc.pc); break; - } -} - -static void ppc_mtsr(UINT32 op) -{ - UINT32 sr = (op >> 16) & 15; - UINT32 t = RT; - - CHECK_SUPERVISOR(); - - ppc.sr[sr] = REG(t); -} - -static void ppc_mtsrin(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_SUPERVISOR(); - - ppc.sr[REG(b) >> 28] = REG(t); -} - -#ifndef PPC_DRC -static void ppc_dcba(UINT32 op) -{ - /* TODO: Cache not emulated so this opcode doesn't need to be implemented */ -} - -static void ppc_stfdux(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - - ea += REG(a); - - WRITE64(ea, FPR(t).id); - - REG(a) = ea; -} -#endif - -static void ppc_stfdx(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - - if(a) - ea += REG(a); - - WRITE64(ea, FPR(t).id); -} - -static void ppc_stfiwx(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - - if(a) - ea += REG(a); - - WRITE32(ea, (UINT32)FPR(t).id); -} - -static void ppc_stfsux(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - ea += REG(a); - - f.f = (float)(FPR(t).fd); - WRITE32(ea, f.i); - - REG(a) = ea; -} - -static void ppc_stfsx(UINT32 op) -{ - UINT32 ea = REG(RB); - UINT32 a = RA; - UINT32 t = RT; - FPR32 f; - - if(a) - ea += REG(a); - - f.f = (float)(FPR(t).fd); - - WRITE32(ea, f.i); -} - -#ifndef PPC_DRC -static void ppc_tlbia(UINT32 op) -{ - /* TODO: TLB not emulated so this opcode doesn't need to implemented */ -} - -static void ppc_tlbie(UINT32 op) -{ - /* TODO: TLB not emulated so this opcode doesn't need to implemented */ -} - -static void ppc_tlbsync(UINT32 op) -{ - /* TODO: TLB not emulated so this opcode doesn't need to implemented */ -} - -static void ppc_eciwx(UINT32 op) -{ - ppc_unimplemented(op); -} - -static void ppc_ecowx(UINT32 op) -{ - ppc_unimplemented(op); -} -#endif - -static void ppc_fabsx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - FPR(t).id = FPR(b).id & ~DOUBLE_SIGN; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_faddx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = FPR(a).fd + FPR(b).fd; - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fcmpo(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = (RT >> 2); - UINT32 c; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - if(is_nan_double(FPR(a)) || is_nan_double(FPR(b))) - { - c = 1; /* OX */ - if(is_snan_double(FPR(a)) || is_snan_double(FPR(b))) { - ppc.fpscr |= 0x01000000; /* VXSNAN */ - - if(!(ppc.fpscr & 0x40000000) || is_qnan_double(FPR(a)) || is_qnan_double(FPR(b))) - ppc.fpscr |= 0x00080000; /* VXVC */ - } - } - else if(FPR(a).fd < FPR(b).fd){ - c = 8; /* FX */ - } - else if(FPR(a).fd > FPR(b).fd){ - c = 4; /* FEX */ - } - else { - c = 2; /* VX */ - } - - CR(t) = c; - - ppc.fpscr &= ~0x0001F000; - ppc.fpscr |= (c << 12); -} - -static void ppc_fcmpu(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = (RT >> 2); - UINT32 c; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - if(is_nan_double(FPR(a)) || is_nan_double(FPR(b))) - { - c = 1; /* OX */ - if(is_snan_double(FPR(a)) || is_snan_double(FPR(b))) { - ppc.fpscr |= 0x01000000; /* VXSNAN */ - } - } - else if(FPR(a).fd < FPR(b).fd){ - c = 8; /* FX */ - } - else if(FPR(a).fd > FPR(b).fd){ - c = 4; /* FEX */ - } - else { - c = 2; /* VX */ - } - - CR(t) = c; - - ppc.fpscr &= ~0x0001F000; - ppc.fpscr |= (c << 12); -} - -static void ppc_fctiwx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - INT64 r = 0; - - // TODO: fix FPSCR flags FX,VXSNAN,VXCVI - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - switch(ppc.fpscr & 3) - { - case 0: r = (INT64)round_to_nearest(FPR(b)); break; - case 1: r = (INT64)round_toward_zero(FPR(b)); break; - case 2: r = (INT64)round_toward_positive_infinity(FPR(b)); break; - case 3: r = (INT64)round_toward_negative_infinity(FPR(b)); break; - } - - if(r > (INT64)((INT32)0x7FFFFFFF)) - { - FPR(t).id = 0x7FFFFFFF; - // FPSCR[FR] = 0 - // FPSCR[FI] = 1 - // FPSCR[XX] = 1 - } - else if(FPR(b).fd < (INT64)((INT32)0x80000000)) - { - FPR(t).id = 0x80000000; - // FPSCR[FR] = 1 - // FPSCR[FI] = 1 - // FPSCR[XX] = 1 - } - else - { - FPR(t).id = (UINT32)r; - // FPSCR[FR] = t.iw > t.fd - // FPSCR[FI] = t.iw == t.fd - // FPSCR[XX] = ? - } - - // FPSCR[FPRF] = undefined (leave it as is) - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fctiwzx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - INT64 r; - - // TODO: fix FPSCR flags FX,VXSNAN,VXCVI - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - r = round_toward_zero(FPR(b)); - - if(r > (INT64)((INT32)0x7fffffff)) - { - FPR(t).id = 0x7fffffff; - // FPSCR[FR] = 0 - // FPSCR[FI] = 1 - // FPSCR[XX] = 1 - - } - else if(r < (INT64)((INT32)0x80000000)) - { - FPR(t).id = 0x80000000; - // FPSCR[FR] = 1 - // FPSCR[FI] = 1 - // FPSCR[XX] = 1 - } - else - { - FPR(t).id = (UINT32)r; - // FPSCR[FR] = t.iw > t.fd - // FPSCR[FI] = t.iw == t.fd - // FPSCR[XX] = ? - } - - // FPSCR[FPRF] = undefined (leave it as is) - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fdivx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = FPR(a).fd / FPR(b).fd; - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmrx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - FPR(t).fd = FPR(b).fd; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnabsx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - FPR(t).id = FPR(b).id | DOUBLE_SIGN; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnegx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - FPR(t).id = FPR(b).id ^ DOUBLE_SIGN; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_frspx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - FPR(t).fd = (float)FPR(b).fd; - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_frsqrtex(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - FPR(t).fd = 1.0 / sqrt(FPR(b).fd); /* verify this */ - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fsqrtx(UINT32 op) -{ - /* NOTE: PPC603e doesn't support this opcode */ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - FPR(t).fd = (double)(sqrt(FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fsubx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = FPR(a).fd - FPR(b).fd; - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mffsx(UINT32 op) -{ - FPR(RT).id = (UINT32)ppc.fpscr; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mtfsb0x(UINT32 op) -{ - UINT32 crbD; - - crbD = (op >> 21) & 0x1F; - - if (crbD != 1 && crbD != 2) // these bits cannot be explicitly cleared - ppc.fpscr &= ~(1 << (31 - crbD)); - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mtfsb1x(UINT32 op) -{ - UINT32 crbD; - - crbD = (op >> 21) & 0x1F; - - if (crbD != 1 && crbD != 2) // these bits cannot be explicitly cleared - ppc.fpscr |= (1 << (31 - crbD)); - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mtfsfx(UINT32 op) -{ - UINT32 b = RB; - UINT32 f = FM; - - f = ppc_field_xlat[FM]; - - ppc.fpscr &= (~f) | ~(FPSCR_FEX | FPSCR_VX); - ppc.fpscr |= (UINT32)(FPR(b).id) & ~(FPSCR_FEX | FPSCR_VX); - - // FEX, VX - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mtfsfix(UINT32 op) -{ - UINT32 crfd = CRFD; - UINT32 imm = (op >> 12) & 0xF; - - /* - * According to the manual: - * - * If bits 0 and 3 of FPSCR are to be modified, they take the immediate - * value specified. Bits 1 and 2 (FEX and VX) are set according to the - * "usual rule" and not from IMM[1-2]. - * - * The "usual rule" is not emulated, so these bits simply aren't modified - * at all here. - */ - - crfd = (7 - crfd) * 4; // calculate LSB position of field - - if (crfd == 28) // field containing FEX and VX is special... - { // bits 1 and 2 of FPSCR must not be altered - ppc.fpscr &= 0x9fffffff; - ppc.fpscr |= (imm & 0x9fffffff); - } - - ppc.fpscr &= ~(0xf << crfd); // clear field - ppc.fpscr |= (imm << crfd); // insert new data - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_mcrfs(UINT32 op) -{ - UINT32 crfs, f; - crfs = CRFA; - - f = ppc.fpscr >> ((7 - crfs) * 4); // get crfS field from FPSCR - f &= 0xf; - - switch(crfs) // determine which exception bits to clear in FPSCR - { - case 0: // FX, OX - ppc.fpscr &= ~0x90000000; - break; - case 1: // UX, ZX, XX, VXSNAN - ppc.fpscr &= ~0x0f000000; - break; - case 2: // VXISI, VXIDI, VXZDZ, VXIMZ - ppc.fpscr &= ~0x00F00000; - break; - case 3: // VXVC - ppc.fpscr &= ~0x00080000; - break; - case 5: // VXSOFT, VXSQRT, VXCVI - ppc.fpscr &= ~0x00000e00; - break; - default: - break; - } - - CR(CRFD) = f; -} - -static void ppc_faddsx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = (float)(FPR(a).fd + FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fdivsx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = (float)(FPR(a).fd / FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fresx(UINT32 op) -{ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - FPR(t).fd = 1.0 / FPR(b).fd; /* ??? */ - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fsqrtsx(UINT32 op) -{ - /* NOTE: This opcode is not supported in PPC603e */ - UINT32 b = RB; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN_1(FPR(b)); - - FPR(t).fd = (float)(sqrt(FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fsubsx(UINT32 op) -{ - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - - FPR(t).fd = (float)(FPR(a).fd - FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmaddx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = ((FPR(a).fd * FPR(c).fd) + FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmsubx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = ((FPR(a).fd * FPR(c).fd) - FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmulx(UINT32 op) -{ - UINT32 c = RC; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(c)); - - FPR(t).fd = (FPR(a).fd * FPR(c).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnmaddx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (-((FPR(a).fd * FPR(c).fd) + FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnmsubx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (-((FPR(a).fd * FPR(c).fd) - FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fselx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - FPR(t).fd = (FPR(a).fd >= 0.0) ? FPR(c).fd : FPR(b).fd; - - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmaddsx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (float)((FPR(a).fd * FPR(c).fd) + FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmsubsx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (float)((FPR(a).fd * FPR(c).fd) - FPR(b).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fmulsx(UINT32 op) -{ - UINT32 c = RC; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - SET_VXSNAN(FPR(a), FPR(c)); - - FPR(t).fd = (float)(FPR(a).fd * FPR(c).fd); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnmaddsx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (float)(-((FPR(a).fd * FPR(c).fd) + FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -} - -static void ppc_fnmsubsx(UINT32 op) -{ - UINT32 c = RC; - UINT32 b = RB; - UINT32 a = RA; - UINT32 t = RT; - - CHECK_FPU_AVAILABLE(); - - SET_VXSNAN(FPR(a), FPR(b)); - SET_VXSNAN_1(FPR(c)); - - FPR(t).fd = (float)(-((FPR(a).fd * FPR(c).fd) - FPR(b).fd)); - - set_fprf(FPR(t)); - if( RCBIT ) { - SET_CR1(); - } -}