diff options
Diffstat (limited to 'src/devices/cpu/powerpc/ppcdrc.cpp')
-rw-r--r-- | src/devices/cpu/powerpc/ppcdrc.cpp | 271 |
1 files changed, 221 insertions, 50 deletions
diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 120328a50a0..b9c7484f1f9 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /*************************************************************************** - ppcdrc.c + ppcdrc.cpp Universal machine language-based PowerPC emulator. @@ -18,12 +18,10 @@ #include "ppc.h" #include "ppccom.h" #include "ppcfe.h" -#include "ppc_dasm.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" -#include "debugger.h" @@ -118,7 +116,7 @@ inline void ppc_device::load_fast_iregs(drcuml_block &block) { int regnum; - for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) + for (regnum = 0; regnum < std::size(m_regmap); regnum++) { if (m_regmap[regnum].is_int_register()) { @@ -137,7 +135,7 @@ void ppc_device::save_fast_iregs(drcuml_block &block) { int regnum; - for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) + for (regnum = 0; regnum < std::size(m_regmap); regnum++) { if (m_regmap[regnum].is_int_register()) { @@ -149,7 +147,7 @@ void ppc_device::save_fast_iregs(drcuml_block &block) inline void ppc_device::load_fast_fregs(drcuml_block &block) { - for (int regnum = 0; regnum < ARRAY_LENGTH(m_fdregmap); regnum++) + for (int regnum = 0; regnum < std::size(m_fdregmap); regnum++) { if (m_fdregmap[regnum].is_float_register()) { @@ -160,7 +158,7 @@ inline void ppc_device::load_fast_fregs(drcuml_block &block) void ppc_device::save_fast_fregs(drcuml_block &block) { - for (int regnum = 0; regnum < ARRAY_LENGTH(m_fdregmap); regnum++) + for (int regnum = 0; regnum < std::size(m_fdregmap); regnum++) { if (m_fdregmap[regnum].is_float_register()) { @@ -268,7 +266,7 @@ void ppc_device::ppcdrc_set_options(uint32_t options) void ppc_device::ppcdrc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) { - if (m_fastram_select < ARRAY_LENGTH(m_fastram)) + if (m_fastram_select < std::size(m_fastram)) { m_fastram[m_fastram_select].start = start; m_fastram[m_fastram_select].end = end; @@ -285,7 +283,7 @@ void ppc_device::ppcdrc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void ppc_device::ppcdrc_add_hotspot(offs_t pc, uint32_t opcode, uint32_t cycles) { - if (m_hotspot_select < ARRAY_LENGTH(m_hotspot)) + if (m_hotspot_select < std::size(m_hotspot)) { m_hotspot[m_hotspot_select].pc = pc; m_hotspot[m_hotspot_select].opcode = opcode; @@ -383,7 +381,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) const opcode_desc *desclist; bool override = false; - g_profiler.start(PROFILER_DRC_COMPILE); + auto profile = g_profiler.start(PROFILER_DRC_COMPILE); /* get a description of this sequence */ desclist = m_drcfe->describe_code(pc); @@ -467,7 +465,6 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) /* end the sequence */ block.end(); - g_profiler.stop(); succeeded = true; } catch (drcuml_block::abort_compilation &) @@ -778,11 +775,11 @@ void ppc_device::static_generate_tlb_mismatch() UML_SHR(block, I1, I0, 12); // shr i1,i0,12 UML_LOAD(block, I2, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword UML_MOV(block, mem(&m_core->param0), I0); // mov [param0],i0 - UML_MOV(block, mem(&m_core->param1), TRANSLATE_FETCH); // mov [param1],TRANSLATE_FETCH + UML_MOV(block, mem(&m_core->param1), TR_FETCH); // mov [param1],TR_FETCH UML_CALLC(block, (c_function)cfunc_ppccom_mismatch, this); UML_CALLC(block, (c_function)cfunc_ppccom_tlb_fill, this); // callc tlbfill,ppc UML_LOAD(block, I1, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword - UML_TEST(block, I1, VTLB_FETCH_ALLOWED); // test i1,VTLB_FETCH_ALLOWED + UML_TEST(block, I1, FETCH_ALLOWED); // test i1,FETCH_ALLOWED UML_JMPc(block, COND_Z, isi = label++); // jmp isi,z UML_CMP(block, I2, 0); // cmp i2,0 UML_JMPc(block, COND_NZ, exit = label++); // jmp exit,nz @@ -1010,9 +1007,9 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite int ramnum; if (mode & MODE_USER) - translate_type = iswrite ? TRANSLATE_WRITE_USER : TRANSLATE_READ_USER; + translate_type = iswrite ? TR_UWRITE : TR_UREAD; else - translate_type = iswrite ? TRANSLATE_WRITE : TRANSLATE_READ; + translate_type = iswrite ? TR_WRITE : TR_READ; /* begin generating */ drcuml_block &block(m_drcuml->begin_block(1024)); @@ -1024,32 +1021,30 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite /* check for unaligned accesses and break into two */ if (!ismasked && size != 1) { - /* in little-endian mode, anything misaligned generates an exception */ if ((mode & MODE_LITTLE_ENDIAN) || masked == nullptr || !(m_cap & PPCCAP_MISALIGNED)) { + /* in little-endian mode, anything misaligned generates an exception */ UML_TEST(block, I0, size - 1); // test i0,size-1 - UML_JMPc(block, COND_NZ, alignex = label++); // jmp alignex,nz + UML_JMPc(block, COND_NZ, alignex = label++); // jmp alignex,nz } - - /* in big-endian mode, it's more complicated */ else { - /* 8-byte accesses must be word-aligned */ + /* in big-endian mode, it's more complicated */ if (size == 8) { + /* 8-byte accesses must be word-aligned */ UML_TEST(block, I0, 3); // test i0,3 - UML_JMPc(block, COND_NZ, alignex = label++); // jmp alignex,nz + UML_JMPc(block, COND_NZ, alignex = label++); // jmp alignex,nz /* word aligned accesses need to be broken up */ UML_TEST(block, I0, 4); // test i0,4 UML_JMPc(block, COND_NZ, unaligned = label++); // jmp unaligned, nz } - - /* unaligned 2 and 4 byte accesses need to be broken up */ else { + /* unaligned 2 and 4 byte accesses need to be broken up */ UML_TEST(block, I0, size - 1); // test i0,size-1 - UML_JMPc(block, COND_NZ, unaligned = label++); // jmp unaligned,nz + UML_JMPc(block, COND_NZ, unaligned = label++); // jmp unaligned,nz } } } @@ -1057,18 +1052,18 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite /* general case: assume paging and perform a translation */ if (((m_cap & PPCCAP_OEA) && (mode & MODE_DATA_TRANSLATION)) || (iswrite && (m_cap & PPCCAP_4XX) && (mode & MODE_PROTECTION))) { - UML_SHR(block, I3, I0, 12); // shr i3,i0,12 - UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword - UML_TEST(block, I3, (uint64_t)1 << translate_type); // test i3,1 << translate_type - UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z - UML_LABEL(block, tlbreturn = label++); // tlbreturn: - UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000 + UML_SHR(block, I3, I0, 12); // shr i3,i0,12 + UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4); // load i3,[vtlb],i3,dword + UML_TEST(block, I3, (uint64_t)1 << translate_type); // test i3,1 << translate_type + UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z + UML_LABEL(block, tlbreturn = label++); // tlbreturn: + UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000 } else if (m_cap & PPCCAP_4XX) UML_AND(block, I0, I0, 0x7fffffff); // and i0,i0,0x7fffffff UML_XOR(block, I0, I0, (mode & MODE_LITTLE_ENDIAN) ? (8 - size) : 0); // xor i0,i0,8-size - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) == 0) + if (!debugger_enabled()) for (ramnum = 0; ramnum < PPC_MAX_FASTRAM; ramnum++) if (m_fastram[ramnum].base != nullptr && (!iswrite || !m_fastram[ramnum].readonly)) { @@ -1468,7 +1463,7 @@ void ppc_device::static_generate_lsw_entries(int mode) char temp[20]; /* allocate a handle */ - sprintf(temp, "lsw%d", regnum); + snprintf(temp, 20, "lsw%d", regnum); alloc_handle(m_drcuml.get(), &m_lsw[mode][regnum], temp); UML_HANDLE(block, *m_lsw[mode][regnum]); // handle lsw<regnum> UML_LABEL(block, regnum); // regnum: @@ -1520,7 +1515,7 @@ void ppc_device::static_generate_stsw_entries(int mode) char temp[20]; /* allocate a handle */ - sprintf(temp, "stsw%d", regnum); + snprintf(temp, 20, "stsw%d", regnum); alloc_handle(m_drcuml.get(), &m_stsw[mode][regnum], temp); UML_HANDLE(block, *m_stsw[mode][regnum]); // handle stsw<regnum> UML_LABEL(block, regnum); // regnum: @@ -1716,7 +1711,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta } /* if we are debugging, call the debugger */ - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + if (debugger_enabled()) { UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc save_fast_iregs(block); // <save fastregs> @@ -1739,25 +1734,31 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta if (PRINTF_MMU) { const char *text = "Compiler page fault @ %08X\n"; - UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + if (sizeof(uintptr_t) == 8) + UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + else + UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text UML_MOV(block, mem(&m_core->arg0), desc->pc); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug } UML_EXH(block, *m_tlb_mismatch, 0); // exh tlb_mismatch,0 } - /* validate our TLB entry at this PC; if we fail, we need to handle it */ - if ((desc->flags & OPFLAG_VALIDATE_TLB) && (m_core->mode & MODE_DATA_TRANSLATION)) + // validate our TLB entry at this PC; if we fail, we need to handle it + // TODO: this code is highly sus based on the PPC architecture manual, but I'll only disable for 601 for now + if ((desc->flags & OPFLAG_VALIDATE_TLB) && (m_core->mode & MODE_DATA_TRANSLATION) && !(m_cap & PPCCAP_601BAT)) { const vtlb_entry *tlbtable = vtlb_table(); - /* if we currently have a valid TLB read entry, we just verify */ if (tlbtable[desc->pc >> 12] != 0) { if (PRINTF_MMU) { const char *text = "Checking TLB at @ %08X\n"; - UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + if (sizeof(uintptr_t) == 8) + UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + else + UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text UML_MOV(block, mem(&m_core->arg0), desc->pc); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug } @@ -1772,7 +1773,10 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta if (PRINTF_MMU) { const char *text = "No valid TLB @ %08X\n"; - UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + if (sizeof(uintptr_t) == 8) + UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text + else + UML_MOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text UML_MOV(block, mem(&m_core->arg0), desc->pc); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug } @@ -2018,6 +2022,23 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, // muls rd,rd,ra,simm return true; + case 0x9: /* DOZI (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + UML_AND(block, I0, op, 0xffff); + UML_CMP(block, R32(G_RA(op)), I0); // cmp ra, I0 + UML_JMPc(block, COND_B, compiler->labelnum); // bae 0: + + UML_XOR(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RD(op))); // xor rd, rd, rd (rd = 0) + UML_JMP(block, compiler->labelnum + 1); // jmp 1: + + UML_LABEL(block, compiler->labelnum++); // 0: + UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), I0); + UML_ADD(block, R32(G_RD(op)), R32(G_RD(op)), 0x1); + + UML_LABEL(block, compiler->labelnum++); // 1: + return true; + case 0x0e: /* ADDI */ UML_ADD(block, R32(G_RD(op)), R32Z(G_RA(op)), (int16_t)G_SIMM(op)); // add rd,ra,simm return true; @@ -2250,12 +2271,15 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, case 0x2e: /* LMW */ UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) UML_MOV(block, mem(&m_core->tempaddr), R32Z(G_RA(op))); // mov [tempaddr],ra + for (int regnum = G_RD(op); regnum < 32; regnum++) { UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op))); // add i0,[tempaddr],simm + 4*(regnum-rd) UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align - UML_MOV(block, R32(regnum), I0); // mov regnum,i0 + + if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31)) + UML_MOV(block, R32(regnum), I0); // mov regnum,i0 } generate_update_cycles(block, compiler, desc->pc + 4, true); // <update cycles> return true; @@ -2672,10 +2696,19 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co case 0x0eb: /* MULLWx */ case 0x2eb: /* MULLWOx */ - UML_MULS(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // muls rd,rd,ra,rb + // The flags are calculated based on the resulting 32-bit value from the 32x32=32 multiplication + // reference: example 4 https://www.ibm.com/docs/en/aix/7.2?topic=set-mullw-muls-multiply-low-word-instruction + UML_MULSLW(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // mulslw rd,ra,rb generate_compute_flags(block, desc, op & M_RC, ((op & M_OE) ? XER_OV : 0), false);// <update flags> return true; + case 0x6b: /* MUL (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + UML_MULU(block, SPR32(SPR601_MQ), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // mulu mq, rd, ra, rb + generate_compute_flags(block, desc, op & M_RC, ((op & M_OE) ? XER_OV | XER_SO : 0), false); // <update flags> + return true; + case 0x1cb: /* DIVWUx */ case 0x3cb: /* DIVWUOx */ UML_CMP(block, R32(G_RB(op)), 0x0); // cmp rb, #0 @@ -2703,6 +2736,68 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co UML_LABEL(block, compiler->labelnum++); // 1: return true; + case 0x14b: /* DIV (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + UML_MOV(block, I0, R32(G_RA(op))); + UML_MOV(block, I1, SPR32(SPR601_MQ)); + UML_DSHL(block, I0, I0, 32); // I0 = RA << 32 + UML_DOR(block, I0, I0, I1); // I0 |= MQ + UML_JMPc(block, COND_NZ, compiler->labelnum); // bne 0: + + UML_MOV(block, R32(G_RD(op)), 0x0); // mov rd, #0 + if (op & M_OE) + { + UML_OR(block, XERSO32, XERSO32, 0x1); // SO |= 1 + UML_OR(block, SPR32(SPR_XER), SPR32(SPR_XER), XER_OV); // OV |= 1 + } + if (op & M_RC) + { + UML_MOV(block, CR32(0), 0x2); // CR = EQ + UML_AND(block, CR32(0), CR32(0), ~0x1); + UML_OR(block, CR32(0), CR32(0), XERSO32); + } + + UML_JMP(block, compiler->labelnum + 1); // jmp 1: + + UML_LABEL(block, compiler->labelnum++); + UML_MOV(block, I1, R32(G_RB(op))); + UML_DSEXT(block, I1, I1, SIZE_DWORD); + UML_DDIVS(block, I0, I1, I0, I1); + UML_MOV(block, R32(G_RD(op)), I0); + UML_MOV(block, SPR32(SPR601_MQ), I1); + generate_compute_flags(block, desc, op & M_RC, ((op & M_OE) ? XER_OV | XER_SO : 0), false); // <update flags> + UML_LABEL(block, compiler->labelnum++); // 1: + return true; + + case 0x16b: /* DIVS (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + UML_CMP(block, R32(G_RB(op)), 0x0); // cmp rb, #0 + UML_JMPc(block, COND_NZ, compiler->labelnum); // bne 0: + + UML_MOV(block, R32(G_RD(op)), 0x0); // mov rd, #0 + if (op & M_OE) + { + UML_OR(block, XERSO32, XERSO32, 0x1); // SO |= 1 + UML_OR(block, SPR32(SPR_XER), SPR32(SPR_XER), XER_OV); // OV |= 1 + } + if (op & M_RC) + { + UML_MOV(block, CR32(0), 0x2); // CR = EQ + UML_AND(block, CR32(0), CR32(0), ~0x1); + UML_OR(block, CR32(0), CR32(0), XERSO32); + } + + UML_JMP(block, compiler->labelnum + 1); // jmp 1: + + UML_LABEL(block, compiler->labelnum++); // 0: + UML_DIVS(block, R32(G_RD(op)), SPR32(SPR601_MQ), R32(G_RA(op)), R32(G_RB(op))); // divs rd,mq,ra,rb + generate_compute_flags(block, desc, op & M_RC, ((op & M_OE) ? XER_OV : 0), false); // <update flags> + + UML_LABEL(block, compiler->labelnum++); // 1: + return true; + case 0x1eb: /* DIVWx */ case 0x3eb: /* DIVWOx */ UML_CMP(block, R32(G_RB(op)), 0x0); // cmp rb, #0 @@ -2756,6 +2851,78 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co UML_LABEL(block, compiler->labelnum++); // 3: return true; + case 0x108: /* DOZ (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra, rb + UML_JMPc(block, COND_B, compiler->labelnum); // bae 0: + + UML_XOR(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RD(op))); // xor rd, rd, rd (rd = 0) + UML_JMP(block, compiler->labelnum+1); // jmp 1: + + UML_LABEL(block, compiler->labelnum++); // 0: + UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); + UML_ADD(block, R32(G_RD(op)), R32(G_RD(op)), 0x1); + + UML_LABEL(block, compiler->labelnum++); // 1: + if (op & M_OE) + { + UML_OR(block, XERSO32, XERSO32, 0x1); // SO |= 1 + UML_OR(block, SPR32(SPR_XER), SPR32(SPR_XER), XER_OV); // OV |= 1 + } + if (op & M_RC) + { + UML_TEST(block, R32(G_RD(op)), ~0); // test rd,~0 + generate_compute_flags(block, desc, op & M_RC, 0, false); // <update flags> + } + return true; + + case 0x168: /* ABS (POWER) */ + case 0x1e8: /* NABS (POWER) */ + assert(m_cap & PPCCAP_LEGACY_POWER); + + // is rA already the correct sign (positive for ABS, negative for NABS)? + UML_CMP(block, R32(G_RA(op)), 0); + if (op & 0x080) + { + UML_JMPc(block, COND_L, compiler->labelnum); // bl 0: + } + else + { + UML_JMPc(block, COND_GE, compiler->labelnum); // bge 0: + } + + UML_SUB(block, I0, 0, R32(G_RA(op))); // sub 0, ra (make positive) + UML_JMP(block, compiler->labelnum + 1); // jmp 1: + + UML_LABEL(block, compiler->labelnum++); // 0: + UML_MOV(block, I0, R32(G_RA(op))); + + UML_LABEL(block, compiler->labelnum++); // 1: + UML_MOV(block, R32(G_RD(op)), I0); // mov rd, I0 + if (op & M_RC) + { + UML_GETFLGS(block, I0, FLAG_Z | FLAG_V | FLAG_C | FLAG_S); // getflgs i0,zvcs + UML_LOAD(block, I0, m_cmp_cr_table, I0, SIZE_DWORD, SCALE_x4); // load i0,cmp_cr_table,i0,dword + } + if (op & M_OE) + { + UML_OR(block, CR32(G_CRFD(op)), I0, XERSO32); // or [crn],i0,[xerso] + } + return true; + + case 0x21d: /* MASKIR (POWER) */ + UML_AND(block, I0, R32(G_RS(op)), R32(G_RB(op))); // and i0, rs, rb + UML_XOR(block, I1, R32(G_RB(op)), 0xffffffff); // xor i1, rb, 0xffffffff + UML_AND(block, I1, I1, R32(G_RA(op))); // and i1, i1, ra + UML_OR(block, R32(G_RA(op)), I0, I1); // or ra, i0, i1 + if (op & M_RC) + { + UML_GETFLGS(block, R32(G_RA(op)), FLAG_Z | FLAG_V | FLAG_C | FLAG_S); // getflgs i0,zvcs + UML_LOAD(block, I0, m_cmp_cr_table, I0, SIZE_DWORD, SCALE_x4); // load i0,cmp_cr_table,i0,dword + } + return true; + case 0x01c: /* ANDx */ UML_AND(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // and ra,rs,rb generate_compute_flags(block, desc, op & M_RC, 0, false); // <update flags> @@ -3066,9 +3233,11 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co case 0x215: /* LSWX */ UML_ADD(block, mem(&m_core->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb - UML_AND(block, mem(&m_core->swcount), SPR32(SPR_XER), 0x7f); // and [swcount],[xer],0x7f - UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), mem(&m_core->swcount));// sub icount,icount,[swcount] - UML_CALLHc(block, COND_NZ, *m_lsw[m_core->mode][G_RD(op)]); // call lsw[rd],nz + UML_AND(block, I0, SPR32(SPR_XER), 0x7f); // and i0,[xer],0x7f + UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I0);// sub icount,icount,i0 + UML_MOV(block, mem(&m_core->swcount), I0); // mov [swcount],i0 + UML_TEST(block, I0, I0); // test i0,i0 + UML_CALLHc(block, COND_NZ, *m_lsw[m_core->mode][G_RD(op)]); // call lsw[rd] generate_update_cycles(block, compiler, desc->pc + 4, true); // <update cycles> return true; @@ -3218,8 +3387,10 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co case 0x295: /* STSWX */ UML_ADD(block, mem(&m_core->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb - UML_AND(block, mem(&m_core->swcount), SPR32(SPR_XER), 0x7f); // and [swcount],[xer],0x7f - UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), mem(&m_core->swcount));// sub icount,icount,[swcount] + UML_AND(block, I0, SPR32(SPR_XER), 0x7f); // and i0,[xer],0x7f + UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I0);// sub icount,icount,i0 + UML_MOV(block, mem(&m_core->swcount), I0); // mov [swcount],i0 + UML_TEST(block, I0, I0); // test i0,i0 UML_CALLHc(block, COND_NZ, *m_stsw[m_core->mode][G_RD(op)]); // call stsw[rd] generate_update_cycles(block, compiler, desc->pc + 4, true); // <update cycles> return true; @@ -3405,7 +3576,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co return true; case 0x200: /* MCRXR */ - UML_ROLAND(block, I0, SPR32(SPR_XER), 28, 0x0f); // roland i0,[xer],28,0x0f + UML_ROLAND(block, I0, SPR32(SPR_XER), 4, 0x0f); // roland i0,[xer],4,0x0f UML_SHL(block, I1, XERSO32, 3); // shl i1,[xerso],3 UML_OR(block, CR32(G_CRFD(op)), I0, I1); // or [crd],i0,i1 UML_AND(block, SPR32(SPR_XER), SPR32(SPR_XER), ~0xf0000000); // and [xer],[xer],~0xf0000000 @@ -3793,7 +3964,7 @@ void ppc_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32 if (m_drcuml->logging()) { std::ostringstream stream; - powerpc_disassembler::dasm_one(stream, pc, op); + m_dasm.dasm_one(stream, pc, op); block.append_comment("%08X: %s", pc, stream.str()); // comment } } @@ -3982,7 +4153,7 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent) if (desclist->flags & OPFLAG_VIRTUAL_NOOP) buffer << "<virtual nop>"; else - powerpc_disassembler::dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); } else buffer << "???"; |