diff options
| author | 2026-03-02 09:25:23 +1100 | |
|---|---|---|
| committer | 2026-03-02 09:25:23 +1100 | |
| commit | 366b485b037b404a4a71f1caa77a4cacb83e17ef (patch) | |
| tree | 5a952cf72bc53d6c1032738f21725e8ae55f152e /src/devices/cpu/powerpc/ppcdrc.cpp | |
| parent | ac492c02708b92ce76400214204a4fa9713d0a1a (diff) | |
Allow recompiling CPU cores to define their own opcode descriptions.
The base opcode description now only has the parts that are used by the
base recompiler front-end. CPU cores are free to define their own
extensions as they see fit without being limited to pre-defined fields.
The base recompiler front-end is now a template, eliminating the virtual
member functions. It no longer has any dependencies on libemu, which
paves the way to decoupling the recompiler front-ends and allowing the
instruction analysis to be tested without the rest of the emulator.
Also added a compile-time option to disable ASTAT flag update elision in
the SHARC recompiler, and fixed some recompiler front-end bugs.
Diffstat (limited to 'src/devices/cpu/powerpc/ppcdrc.cpp')
| -rw-r--r-- | src/devices/cpu/powerpc/ppcdrc.cpp | 209 |
1 files changed, 112 insertions, 97 deletions
diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 38eaa3a6908..ecb4fe09024 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -16,10 +16,10 @@ #include "emu.h" #include "ppc.h" + #include "ppccom.h" #include "ppcfe.h" -#include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -348,9 +348,11 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) block.append_comment("-------------------------"); // comment /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) + for (seqlast = seqhead; seqlast; seqlast = seqlast->next()) + { + if (seqlast->end_sequence()) break; + } assert(seqlast != nullptr); /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ @@ -379,7 +381,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) generate_checksum_block(block, &compiler, seqhead, seqlast); // <checksum> /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + if (seqhead->is_branch_target()) UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 /* iterate over instructions in the sequence and compile them */ @@ -387,7 +389,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) generate_sequence_instruction(block, &compiler, curdesc); // <instruction> /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) + if (seqlast->return_to_start()) nextpc = pc; /* otherwise we just go to the next instruction */ @@ -398,7 +400,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc) generate_update_cycles(block, &compiler, nextpc, true); // <subtract cycles> /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ - if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) + if (seqlast->can_change_modes()) UML_HASHJMP(block, mem(&m_core->mode), nextpc, *m_nocode);// hashjmp <mode>,nextpc,nocode else if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) UML_HASHJMP(block, m_core->mode, nextpc, *m_nocode);// hashjmp <mode>,nextpc,nocode @@ -1573,11 +1575,11 @@ void ppc_device::generate_checksum_block(drcuml_block &block, compiler_state *co /* loose verify or single instruction: just compare and fail */ if (!(m_drcoptions & PPCDRC_STRICT_VERIFY) || seqhead->next() == nullptr) { - if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) + if (!seqhead->virtual_noop()) { const void *base = m_prptr(seqhead->physpc); UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword - UML_CMP(block, I0, seqhead->opptr.l[0]); // cmp i0,*opptr + UML_CMP(block, I0, seqhead->opptr); // cmp i0,*opptr UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc } } @@ -1587,28 +1589,32 @@ void ppc_device::generate_checksum_block(drcuml_block &block, compiler_state *co { #if 0 for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) + { + if (!curdesc->virtual_noop()) { const void *base = m_prptr(seqhead->physpc); - UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword - UML_CMP(block, I0, curdesc->opptr.l[0]); // cmp i0,*opptr - UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc + UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); + UML_CMP(block, I0, curdesc->opptr); + UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); } + } #else uint32_t sum = 0; const void *base = m_prptr(seqhead->physpc); - UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword - sum += seqhead->opptr.l[0]; + UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); + sum += seqhead->opptr; for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) + { + if (!curdesc->virtual_noop()) { base = m_prptr(curdesc->physpc); - UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword - UML_ADD(block, I0, I0, I1); // add i0,i0,i1 - sum += curdesc->opptr.l[0]; + UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I0, I0, I1); + sum += curdesc->opptr; } - UML_CMP(block, I0, sum); // cmp i0,sum - UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc + } + UML_CMP(block, I0, sum); + UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); #endif } } @@ -1624,8 +1630,8 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta int hotnum; /* add an entry for the log */ - if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP)) - log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]); + if (m_drcuml->logging() && !desc->virtual_noop()) + log_add_disasm_comment(block, desc->pc, desc->opptr); /* set the PC map variable */ UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc @@ -1635,7 +1641,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta /* is this a hotspot? */ for (hotnum = 0; hotnum < PPC_MAX_HOTSPOTS; hotnum++) - if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr.l[0] == m_hotspot[hotnum].opcode) + if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr == m_hotspot[hotnum].opcode) { compiler->cycles += m_hotspot[hotnum].cycles; break; @@ -1661,7 +1667,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta } /* if we hit an unmapped address, fatal error */ - if (desc->flags & OPFLAG_COMPILER_UNMAPPED) + if (desc->compiler_unmapped()) { UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc save_fast_iregs(block); // <save fastregs> @@ -1670,7 +1676,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta } /* if we hit a compiler page fault, it's just like a TLB mismatch */ - if (desc->flags & OPFLAG_COMPILER_PAGE_FAULT) + if (desc->compiler_page_fault()) { if (PRINTF_MMU) { @@ -1687,7 +1693,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta // 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)) + if (desc->validate_tlb() && (m_core->mode & MODE_DATA_TRANSLATION) && !(m_cap & PPCCAP_601BAT)) { const vtlb_entry *tlbtable = vtlb_table(); @@ -1725,23 +1731,25 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta } } - /* if this is an invalid opcode, generate the exception now */ - if (desc->flags & OPFLAG_INVALID_OPCODE) - UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000 - - /* if this is a privileged opcode in user mode, generate the exception */ - else if ((desc->flags & OPFLAG_PRIVILEGED) && (m_core->mode & MODE_USER)) + if (desc->invalid_opcode()) + { + // if this is an invalid opcode, generate the exception now + UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); + } + else if (desc->privileged() && (m_core->mode & MODE_USER)) + { + // if this is a privileged opcode in user mode, generate the exception UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x40000); // exh exception_program,0x40000 - - /* otherwise, unless this is a virtual no-op, it's a regular instruction */ - else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) + } + else if (!desc->virtual_noop()) { - /* compile the instruction */ + // otherwise, unless this is a virtual no-op, it's a regular instruction + // compile the instruction if (!generate_opcode(block, compiler, desc)) { - UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc - UML_MOV(block, mem(&m_core->arg0), desc->opptr.l[0]); // mov [arg0],*desc->opptr.l - UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc + UML_MOV(block, mem(&m_core->pc), desc->pc); + UML_MOV(block, mem(&m_core->arg0), desc->opptr); + UML_CALLC(block, cfunc_unimplemented, this); } } } @@ -1758,9 +1766,9 @@ void ppc_device::generate_compute_flags(drcuml_block &block, const opcode_desc * /* modify inputs based on required flags */ if (!DISABLE_FLAG_OPTIMIZATIONS) { - if (!(desc->regreq[3] & frontend::REGFLAG_XER_CA)) + if (!frontend::REGFLAG_XER_CA(desc->regreq)) xermask &= ~XER_CA; - if (!(desc->regreq[2] & frontend::REGFLAG_CR(0))) + if (!frontend::REGFLAG_CR(desc->regreq, 0)) updatecr = 0; } xerflags = ((xermask & XER_OV) ? uml::FLAG_V : 0) | ((xermask & XER_CA) ? uml::FLAG_C : 0); @@ -1845,11 +1853,11 @@ void ppc_device::generate_fp_flags(drcuml_block &block, const opcode_desc *desc, /* for now, only handle the FPRF field */ if (updatefprf) { - int regnum = G_RD(desc->opptr.l[0]); + int regnum = G_RD(desc->opptr); if (m_fdregmap[regnum].is_float_register()) UML_FDMOV(block, mem(&m_core->f[regnum]), freg(m_fdregmap[regnum].freg() - REG_F0)); - UML_MOV(block, mem(&m_core->param0), G_RD(desc->opptr.l[0])); + UML_MOV(block, mem(&m_core->param0), G_RD(desc->opptr)); UML_CALLC(block, (c_function)cfunc_ppccom_update_fprf, this); } } @@ -1879,7 +1887,7 @@ void ppc_device::generate_branch(drcuml_block &block, compiler_state *compiler, if (desc->targetpc != BRANCH_TARGET_DYNAMIC) { generate_update_cycles(block, &compiler_temp, desc->targetpc, true); // <subtract cycles> - if (desc->flags & OPFLAG_INTRABLOCK_BRANCH) + if (desc->intrablock_branch()) UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000 else UML_HASHJMP(block, m_core->mode, desc->targetpc, *m_nocode); @@ -1933,7 +1941,7 @@ void ppc_device::generate_branch_bo(drcuml_block &block, compiler_state *compile bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc) { - uint32_t op = desc->opptr.l[0]; + uint32_t op = desc->opptr; uint32_t opswitch = op >> 26; switch (opswitch) @@ -2331,7 +2339,7 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, bool ppc_device::generate_instruction_13(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc) { - uint32_t op = desc->opptr.l[0]; + uint32_t op = desc->opptr; uint32_t opswitch = (op >> 1) & 0x3ff; switch (opswitch) @@ -2468,7 +2476,7 @@ bool ppc_device::generate_instruction_13(drcuml_block &block, compiler_state *co bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc) { - uint32_t op = desc->opptr.l[0]; + uint32_t op = desc->opptr; uint32_t opswitch = (op >> 1) & 0x3ff; int item; @@ -2963,7 +2971,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co UML_CMP(block, I2, 0x00000020); // cmp rb,0x20 UML_JMPc(block, COND_S, compiler->labelnum); // bs 1: - if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA)) + if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq)) { // for shift amt > 32, carry flag is the sign bit of Rs and the sign bit fills all bit positions UML_TEST(block, R32(G_RS(op)), 0x80000000); @@ -2974,7 +2982,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co UML_JMP(block, compiler->labelnum+1); // bra 2: UML_LABEL(block, compiler->labelnum++); // 1: - if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA)) + if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq)) { UML_SHL(block, I1, 0xffffffff, I2); // shl i1,0xffffffff,i2 UML_XOR(block, I1, I1, ~0); // xor i1,i1,~0 @@ -2995,7 +3003,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co return true; case 0x338: /* SRAWIx */ - if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA)) + if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq)) { UML_AND(block, I0, R32(G_RS(op)), ~(0xffffffff << (G_SH(op) & 31)));// and i0,rs,~(0xffffffff << (sh & 31)) UML_SAR(block, I1, R32(G_RS(op)), 31); // sar i1,rs,31 @@ -3618,7 +3626,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co bool ppc_device::generate_instruction_3b(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc) { - uint32_t op = desc->opptr.l[0]; + uint32_t op = desc->opptr; uint32_t opswitch = (op >> 1) & 0x1f; switch (opswitch) @@ -3726,7 +3734,7 @@ bool ppc_device::generate_instruction_3b(drcuml_block &block, compiler_state *co bool ppc_device::generate_instruction_3f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc) { - uint32_t op = desc->opptr.l[0]; + uint32_t op = desc->opptr; uint32_t opswitch = (op >> 1) & 0x3ff; if (opswitch & 0x10) @@ -3916,52 +3924,49 @@ void ppc_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32 flags -------------------------------------------------*/ -const char *ppc_device::log_desc_flags_to_string(uint32_t flags) +const char *ppc_device::log_desc_flags_to_string(const opcode_desc &desc) { static char tempbuf[30]; char *dest = tempbuf; /* branches */ - if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH) + if (desc.is_unconditional_branch()) *dest++ = 'U'; - else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH) + else if (desc.is_conditional_branch()) *dest++ = 'C'; else *dest++ = '.'; /* intrablock branches */ - *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.'; + *dest++ = desc.intrablock_branch() ? 'i' : '.'; /* branch targets */ - *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.'; + *dest++ = desc.is_branch_target() ? 'B' : '.'; /* delay slots */ - *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.'; + *dest++ = desc.in_delay_slot() ? 'D' : '.'; /* exceptions */ - if (flags & OPFLAG_WILL_CAUSE_EXCEPTION) + if (desc.will_cause_exception()) *dest++ = 'E'; - else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION) + else if (desc.can_cause_exception()) *dest++ = 'e'; else *dest++ = '.'; /* read/write */ - if (flags & OPFLAG_READS_MEMORY) + if (desc.reads_memory()) *dest++ = 'R'; - else if (flags & OPFLAG_WRITES_MEMORY) + else if (desc.writes_memory()) *dest++ = 'W'; else *dest++ = '.'; /* TLB validation */ - *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.'; - - /* TLB modification */ - *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.'; + *dest++ = desc.validate_tlb() ? 'V' : '.'; /* redispatch */ - *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.'; + *dest++ = desc.redispatch() ? 'R' : '.'; return tempbuf; } @@ -3970,7 +3975,7 @@ const char *ppc_device::log_desc_flags_to_string(uint32_t flags) log_register_list - log a list of GPR registers -------------------------------------------------*/ -void ppc_device::log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist) +void ppc_device::log_register_list(const char *string, const std::bitset<128> ®list, const std::bitset<128> *regnostarlist) { static const char *const crtext[4] = { "lt", "gt", "eq", "so" }; int count = 0; @@ -3978,92 +3983,102 @@ void ppc_device::log_register_list(const char *string, const uint32_t *reglist, int crnum; /* skip if nothing */ - if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0 && reglist[3] == 0) + if (reglist.none()) return; m_drcuml->log_printf("[%s:", string); for (regnum = 0; regnum < 32; regnum++) - if (reglist[0] & frontend::REGFLAG_R(regnum)) + { + if (frontend::REGFLAG_R(reglist, regnum)) { m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist != nullptr && !(regnostarlist[0] & frontend::REGFLAG_R(regnum))) + if (regnostarlist && !frontend::REGFLAG_R(*regnostarlist, regnum)) m_drcuml->log_printf("*"); } + } for (regnum = 0; regnum < 32; regnum++) - if (reglist[1] & frontend::REGFLAG_FR(regnum)) + { + if (frontend::REGFLAG_FR(reglist, regnum)) { m_drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist != nullptr && !(regnostarlist[1] & frontend::REGFLAG_FR(regnum))) + if (regnostarlist && !frontend::REGFLAG_FR(*regnostarlist, regnum)) m_drcuml->log_printf("*"); } + } for (regnum = 0; regnum < 8; regnum++) - if (reglist[2] & frontend::REGFLAG_CR(regnum)) + { + if (frontend::REGFLAG_CR(reglist, regnum)) { - if ((reglist[2] & frontend::REGFLAG_CR(regnum)) == frontend::REGFLAG_CR(regnum) && (regnostarlist == nullptr || (regnostarlist[2] & frontend::REGFLAG_CR(regnum)) == frontend::REGFLAG_CR(regnum))) + if ((frontend::REGFLAG_CR(reglist, regnum) == 0x0f) && (!regnostarlist || (frontend::REGFLAG_CR(*regnostarlist, regnum) == 0x0f))) { m_drcuml->log_printf("%scr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist != nullptr && !(regnostarlist[2] & frontend::REGFLAG_CR(regnum))) + if (regnostarlist && !frontend::REGFLAG_CR(*regnostarlist, regnum)) m_drcuml->log_printf("*"); } else { for (crnum = 0; crnum < 4; crnum++) - if (reglist[2] & frontend::REGFLAG_CR_BIT(regnum * 4 + crnum)) + { + if (frontend::REGFLAG_CR_BIT(reglist, regnum * 4 + crnum)) { m_drcuml->log_printf("%scr%d[%s]", (count++ == 0) ? "" : ",", regnum, crtext[crnum]); - if (regnostarlist != nullptr && !(regnostarlist[2] & frontend::REGFLAG_CR_BIT(regnum * 4 + crnum))) + if (regnostarlist && !frontend::REGFLAG_CR_BIT(*regnostarlist, regnum * 4 + crnum)) m_drcuml->log_printf("*"); } + } } } + } - if (reglist[3] & frontend::REGFLAG_XER_CA) + if (frontend::REGFLAG_XER_CA(reglist)) { m_drcuml->log_printf("%sxer_ca", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_CA)) + if (regnostarlist && !frontend::REGFLAG_XER_CA(*regnostarlist)) m_drcuml->log_printf("*"); } - if (reglist[3] & frontend::REGFLAG_XER_OV) + if (frontend::REGFLAG_XER_OV(reglist)) { m_drcuml->log_printf("%sxer_ov", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_OV)) + if (regnostarlist && !frontend::REGFLAG_XER_OV(*regnostarlist)) m_drcuml->log_printf("*"); } - if (reglist[3] & frontend::REGFLAG_XER_SO) + if (frontend::REGFLAG_XER_SO(reglist)) { m_drcuml->log_printf("%sxer_so", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_SO)) + if (regnostarlist && !frontend::REGFLAG_XER_SO(*regnostarlist)) m_drcuml->log_printf("*"); } - if (reglist[3] & frontend::REGFLAG_XER_COUNT) + if (frontend::REGFLAG_XER_COUNT(reglist)) { m_drcuml->log_printf("%sxer_count", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_COUNT)) + if (regnostarlist && !frontend::REGFLAG_XER_COUNT(*regnostarlist)) m_drcuml->log_printf("*"); } - if (reglist[3] & frontend::REGFLAG_CTR) + if (frontend::REGFLAG_CTR(reglist)) { m_drcuml->log_printf("%sctr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_CTR)) + if (regnostarlist && !frontend::REGFLAG_CTR(*regnostarlist)) m_drcuml->log_printf("*"); } - if (reglist[3] & frontend::REGFLAG_LR) + if (frontend::REGFLAG_LR(reglist)) { m_drcuml->log_printf("%slr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_LR)) + if (regnostarlist && !frontend::REGFLAG_LR(*regnostarlist)) m_drcuml->log_printf("*"); } for (regnum = 0; regnum < 8; regnum++) - if (reglist[3] & frontend::REGFLAG_FPSCR(regnum)) + { + if (frontend::REGFLAG_FPSCR(reglist, regnum)) { m_drcuml->log_printf("%sfpscr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_FPSCR(regnum))) + if (regnostarlist && !frontend::REGFLAG_FPSCR(*regnostarlist, regnum)) m_drcuml->log_printf("*"); } + } m_drcuml->log_printf("] "); } @@ -4090,20 +4105,20 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent) /* disassemble the current instruction and output it to the log */ if (m_drcuml->logging() || m_drcuml->logging_native()) { - if (desclist->flags & OPFLAG_VIRTUAL_NOOP) + if (desclist->virtual_noop()) buffer << "<virtual nop>"; else - m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr); } else buffer << "???"; buffer.put('\0'); - m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), &buffer.vec()[0]); + m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(*desclist), &buffer.vec()[0]); /* output register states */ log_register_list("use", desclist->regin, nullptr); - log_register_list("mod", desclist->regout, desclist->regreq); + log_register_list("mod", desclist->regout, &desclist->regreq); m_drcuml->log_printf("\n"); /* if we have a delay slot, output it recursively */ @@ -4111,7 +4126,7 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent) log_opcode_desc(desclist->delay.first(), indent + 1); /* at the end of a sequence add a dividing line */ - if (desclist->flags & OPFLAG_END_SEQUENCE) + if (desclist->end_sequence()) m_drcuml->log_printf("-----\n"); } } |
