diff options
| author | 2026-03-05 03:43:49 +1100 | |
|---|---|---|
| committer | 2026-03-05 03:43:49 +1100 | |
| commit | 3c6ffd84b0ae8c7138ea7199ebc8d74e77be0f3e (patch) | |
| tree | 01c4e52cbea7c7f4e160176ea4069e79d8988ce2 | |
| parent | d18fa74d69d49353f4e6dd3fd0afd9dd6591a30d (diff) | |
-cpu/e132xs: Log analysed instructions in UML log when using recompiler.
-cpu/powerpc: Modernised recompiler front-end code, improved instruction
analysis logging.
-cpu/sh: Cleaned up instruction analysis logging a little
-util/client_ws.hpp, util/server_ws_impl.hpp, capcom/cps2comm.cpp:
Updated some use of deprecation ASIO APIs.
-nakajima/nakajies.cpp: Use range-based loops.
24 files changed, 1149 insertions, 925 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 9bf32fcaf66..3490ca9d4f9 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -1046,17 +1046,18 @@ if CPUS["E1"] then files { MAME_DIR .. "src/devices/cpu/e132xs/e132xs.cpp", MAME_DIR .. "src/devices/cpu/e132xs/e132xs.h", - MAME_DIR .. "src/devices/cpu/e132xs/32xsdefs.h", - MAME_DIR .. "src/devices/cpu/e132xs/e132xsop.hxx", - MAME_DIR .. "src/devices/cpu/e132xs/e132xsfe.cpp", MAME_DIR .. "src/devices/cpu/e132xs/e132xsdrc.cpp", MAME_DIR .. "src/devices/cpu/e132xs/e132xsdrc_ops.hxx", + MAME_DIR .. "src/devices/cpu/e132xs/e132xsop.hxx", + MAME_DIR .. "src/devices/cpu/e132xs/e1defs.h", + MAME_DIR .. "src/devices/cpu/e132xs/e1fe.cpp", + MAME_DIR .. "src/devices/cpu/e132xs/e1fe.h", } end if opt_tool(CPUS, "E1") then - table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/e132xs/32xsdasm.cpp") - table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/e132xs/32xsdasm.h") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/e132xs/e1dasm.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/e132xs/e1dasm.h") end -------------------------------------------------- diff --git a/src/devices/cpu/e132xs/32xsdasm.h b/src/devices/cpu/e132xs/32xsdasm.h deleted file mode 100644 index 32f9c6df587..00000000000 --- a/src/devices/cpu/e132xs/32xsdasm.h +++ /dev/null @@ -1,46 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Pierpaolo Prazzoli -/* - - Hyperstone disassembler - written by Pierpaolo Prazzoli - -*/ - -#ifndef MAME_CPU_E132XS_32XSDASM_H -#define MAME_CPU_E132XS_32XSDASM_H - -#pragma once - -#include <string_view> - - -class hyperstone_disassembler : public util::disasm_interface -{ -public: - struct config - { - virtual ~config() = default; - - virtual bool get_h() const = 0; - }; - - hyperstone_disassembler(config *conf); - virtual ~hyperstone_disassembler() = default; - - virtual u32 opcode_alignment() const override; - virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; - -private: - config *m_config; - - int size; - - uint32_t LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes); - uint32_t RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes); - int32_t Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag); - int32_t PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes); - uint32_t RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes); -}; - -#endif diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index 6d4b1792552..34117a70486 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli /******************************************************************** - Hyperstone cpu emulator + Hyperstone E1 CPU emulator written by Pierpaolo Prazzoli Hyperstone models: @@ -91,9 +91,9 @@ #include "emu.h" #include "e132xs.h" -#include "e132xsfe.h" -#include "32xsdefs.h" +#include "e1defs.h" +#include "e1fe.h" #include "emuopts.h" @@ -160,6 +160,7 @@ hyperstone_device::hyperstone_device( : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map) , m_io_config("io", ENDIANNESS_BIG, io_data_width, io_addr_bits, (io_data_width == 16) ? -1 : -2) + , m_disassembler(nullptr) // for logging - pass nullptr so output doesn't depend on state , m_cache(CACHE_SIZE + sizeof(internal_hyperstone_state)) , m_drcuml(nullptr) , m_drcfe(nullptr) diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index 55bf264f8ac..ba78ff17272 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -5,7 +5,7 @@ #pragma once -#include "32xsdasm.h" +#include "e1dasm.h" #include "cpu/drcuml.h" @@ -439,6 +439,7 @@ private: FILE *m_trace_log; #endif + hyperstone_disassembler m_disassembler; drc_cache m_cache; std::unique_ptr<drcuml_state> m_drcuml; std::unique_ptr<frontend> m_drcfe; @@ -477,6 +478,7 @@ private: void flush_drc_cache(); void generate_invariant(); void code_compile_block(uint8_t mode, offs_t pc); + void log_descriptions(const opcode_desc *desc_list, unsigned indent); //void load_fast_iregs(drcuml_block &block); //void save_fast_iregs(drcuml_block &block); void static_generate_helpers(drcuml_block &block, uml::code_label &label); diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp index 88b7bdc11fa..c3bb9fb22d2 100644 --- a/src/devices/cpu/e132xs/e132xsdrc.cpp +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -4,13 +4,17 @@ #include "emu.h" #include "e132xs.h" -#include "32xsdefs.h" -#include "e132xsfe.h" +#include "e1defs.h" +#include "e1fe.h" #include "cpu/drcumlsh.h" +#include "util/vecstream.h" -/* map variables */ +#include <locale> + + +// map variables #define MAPVAR_PC M0 #define MAPVAR_CYCLES M1 @@ -266,8 +270,10 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc) auto profile = g_profiler.start(PROFILER_DRC_COMPILE); - /* get a description of this sequence */ + // describe a sequence of instructions const opcode_desc *desclist = m_drcfe->describe_code(pc); + if (m_drcuml->logging()) + log_descriptions(desclist, 0); bool succeeded = false; while (!succeeded) @@ -352,6 +358,60 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc) } } +void hyperstone_device::log_descriptions(const opcode_desc *desc_list, unsigned indent) +{ + util::ovectorstream buffer; + buffer.imbue(std::locale::classic()); + + // assume no indent is the start of a sequence and needs a heading + if (!indent) + m_drcuml->log_printf("\nDescriptor list @ %08X\n", desc_list->pc); + + for ( ; desc_list; desc_list = desc_list->next()) + { + buffer.clear(); + buffer.seekp(0); + desc_list->log_flags(buffer); + buffer.put('\0'); + + m_drcuml->log_printf("%08X t:%08X f:%s: ", desc_list->pc, desc_list->targetpc, &buffer.vec()[0]); + + // disassemble the current instruction and output it to the log + buffer.clear(); + buffer.seekp(0); + util::stream_format(buffer, "%*s", 4 * indent, ""); + if (desc_list->virtual_noop()) + buffer << "<virtual nop>"; + else + m_disassembler.disassemble_one(buffer, desc_list->pc, desc_list->opptr); + buffer.put('\0'); + m_drcuml->log_printf("%-36s", &buffer.vec()[0]); + + // output register dependencies + buffer.clear(); + buffer.seekp(0); + if (!desc_list->regin.none()) + { + desc_list->log_registers_used(buffer); + if (!desc_list->regout.none()) + buffer << ' '; + } + if (!desc_list->regout.none()) + desc_list->log_registers_modified(buffer); + buffer.put('\0'); + m_drcuml->log_printf("%s\n", &buffer.vec()[0]); + + // if we have a delay slot, output it recursively + if (desc_list->delay.first()) + log_descriptions(desc_list->delay.first(), indent + 1); + + // at the end of a sequence add a dividing line + if (desc_list->end_sequence()) + m_drcuml->log_printf("-----\n"); + } +} + + /*************************************************************************** STATIC CODEGEN ***************************************************************************/ diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx index 7131bdba505..af0795bea2b 100644 --- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -3873,7 +3873,6 @@ void hyperstone_device::generate_call(drcuml_block &block, compiler_state &compi dst_code = 16; UML_BFXU(block, I3, DRC_SR, FP_SHIFT, 7); - UML_MOV(block, I1, desc->imm); if (SrcGlobal) { diff --git a/src/devices/cpu/e132xs/32xsdasm.cpp b/src/devices/cpu/e132xs/e1dasm.cpp index 286ef747dde..fe8e64b4d9e 100644 --- a/src/devices/cpu/e132xs/32xsdasm.cpp +++ b/src/devices/cpu/e132xs/e1dasm.cpp @@ -2,14 +2,17 @@ // copyright-holders:Pierpaolo Prazzoli /* - Hyperstone disassembler + Hyperstone E1 disassembler written by Pierpaolo Prazzoli */ #include "emu.h" -#include "32xsdasm.h" -#include "32xsdefs.h" +#include "e1dasm.h" + +#include "e1defs.h" + +#include <cassert> namespace { @@ -128,7 +131,8 @@ void format_addsub( -uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes) +template <typename T> +uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw) { uint16_t next_op; uint32_t const_val; @@ -143,7 +147,7 @@ uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std:: size = 4; pc += 2; - next_op = opcodes.r16(pc); + next_op = read_hw(pc); if (E_BIT(next_op)) { @@ -152,7 +156,7 @@ uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std:: size = 6; pc += 2; - next_op2 = opcodes.r16(pc); + next_op2 = read_hw(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -170,7 +174,8 @@ uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std:: return const_val; } -uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes) +template <typename T> +uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw) { uint16_t next_op; uint32_t const_val; @@ -188,7 +193,7 @@ uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std:: size = 4; pc += 2; - next_op = opcodes.r16(pc); + next_op = read_hw(pc); if (E_BIT(next_op)) { @@ -197,7 +202,7 @@ uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std:: size = 6; pc += 2; - next_op2 = opcodes.r16(pc); + next_op2 = read_hw(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -217,7 +222,8 @@ uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std:: return const_val; } -int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag) +template <typename T> +int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw, unsigned h_flag) { uint16_t imm1, imm2; int32_t ret; @@ -237,9 +243,9 @@ int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op case 17: pc += 2; - imm1 = opcodes.r16(pc); + imm1 = read_hw(pc); pc += 2; - imm2 = opcodes.r16(pc); + imm2 = read_hw(pc); ret = (imm1 << 16) | imm2; size = 6; @@ -248,14 +254,14 @@ int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op case 18: pc += 2; - ret = opcodes.r16(pc); + ret = read_hw(pc); size = 4; return ret; case 19: pc += 2; - ret = (int32_t) (0xffff0000 | opcodes.r16(pc)); + ret = (int32_t) (0xffff0000 | read_hw(pc)); size = 4; return ret; @@ -301,7 +307,8 @@ int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op } } -int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes) +template <typename T> +int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, T &&read_hw) { int32_t ret; @@ -313,7 +320,7 @@ int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data pc += 2; - next = opcodes.r16(pc); + next = read_hw(pc); ret = (op & 0x7f) << 16; @@ -333,7 +340,8 @@ int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data return (pc + ret); } -uint32_t hyperstone_disassembler::RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes) +template <typename T> +uint32_t hyperstone_disassembler::RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, T &&read_hw) { uint32_t ret; @@ -353,7 +361,7 @@ uint32_t hyperstone_disassembler::RRdis_format(std::string_view &source, std::st size = 6; - next = opcodes.r16(pc + 4); + next = read_hw(pc + 4); ret = next; ret |= ( ( next_op & 0xfff ) << 16 ); @@ -384,15 +392,35 @@ hyperstone_disassembler::hyperstone_disassembler(config *conf) : m_config(conf) { } +offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return do_disassemble(stream, pc, [&opcodes] (offs_t addr) { return opcodes.r16(addr); }); +} + +offs_t hyperstone_disassembler::disassemble_one(std::ostream &stream, offs_t pc, const uint16_t *opptr) +{ + return do_disassemble( + stream, + pc, + [pc, opptr] (offs_t addr) + { + assert(addr >= pc); + assert(addr < (pc + 6)); + return opptr[(addr - pc) >> 1]; + }); +} + + /*****************************/ /* Main disassembly function */ /*****************************/ -offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +template <typename T> +offs_t hyperstone_disassembler::do_disassemble(std::ostream &stream, offs_t pc, T &&read_hw) { std::string_view source, dest; uint32_t flags = 0; - const uint16_t op = opcodes.r16(pc); + const uint16_t op = read_hw(pc); size = 2; @@ -401,7 +429,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con const uint8_t source_bit = SOURCEBIT(op); const uint8_t dest_bit = DESTBIT(op); - const int h_flag = m_config->get_h(); + const int h_flag = m_config ? m_config->get_h() : 0; const uint8_t op_num = (op & 0xff00) >> 8; @@ -465,7 +493,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con size = 4; pc += 2; - const uint16_t ilm1 = opcodes.r16(pc); + const uint16_t ilm1 = read_hw(pc); const int xcode = X_CODE(ilm1); @@ -478,7 +506,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con size = 6; pc += 2; - const uint16_t ilm2 = opcodes.r16(pc); + const uint16_t ilm2 = read_hw(pc); lim = ((ilm1 & 0xfff) << 16) | ilm2; } @@ -499,7 +527,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // MASK case 0x14: case 0x15: case 0x16: case 0x17: { - const uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); + const uint32_t const_val = RRconst_format(source, dest, op, pc, read_hw); util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val); if (!source_bit && (source_code == PC_REGISTER)) util::stream_format(stream, " ; $%x", uint32_t((pc + size) & const_val)); @@ -509,7 +537,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x18: case 0x19: case 0x1a: case 0x1b: // SUM case 0x1c: case 0x1d: case 0x1e: case 0x1f: // SUMS { - const uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); + const uint32_t const_val = RRconst_format(source, dest, op, pc, read_hw); util::stream_format(stream, "SUM%c %s, %s, $%x", (op_num & 0x4) ? 'S' : ' ', dest, @@ -601,7 +629,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // CMPI case 0x60: case 0x61: case 0x62: case 0x63: { - const uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + const uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); util::stream_format(stream, "CMPI %s, $%x", dest, imm); } break; @@ -609,7 +637,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // MOVI case 0x64: case 0x65: case 0x66: case 0x67: { - const uint32_t imm = Rimm_format(dest, op, pc, opcodes, h_flag); + const uint32_t imm = Rimm_format(dest, op, pc, read_hw, h_flag); util::stream_format(stream, "MOVI %s, $%x", dest, imm); } break; @@ -622,7 +650,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con } else { - const uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + const uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); util::stream_format(stream, "%-7s %s, $%x", (op_num & 0x4) ? "ADDSI" : "ADDI", dest, imm); if (!dest_bit && (dest_code == PC_REGISTER)) util::stream_format(stream, " ; $%x", uint32_t(pc + size + imm)); @@ -637,7 +665,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con } else { - uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); if (DASM_N_VALUE(op) == 31) imm = 0x7fffffff; //bit 31 = 0, others = 1 @@ -648,7 +676,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // ANDNI case 0x74: case 0x75: case 0x76: case 0x77: { - uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); if (DASM_N_VALUE(op) == 31) imm = 0x7fffffff; //bit 31 = 0, others = 1 @@ -661,7 +689,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // ORI case 0x78: case 0x79: case 0x7a: case 0x7b: { - const uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + const uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); util::stream_format(stream, "ORI %s, $%x", dest, imm); if (!dest_bit && (dest_code == PC_REGISTER)) @@ -672,7 +700,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // XORI case 0x7c: case 0x7d: case 0x7e: case 0x7f: { - const uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); + const uint32_t imm = Rimm_format(dest, op, pc, read_hw, 0); util::stream_format(stream, "XORI %s, $%x", dest, imm); if (!dest_bit && (dest_code == PC_REGISTER)) @@ -735,8 +763,8 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x90: case 0x91: case 0x92: case 0x93: // LDxx.D/A/IOD/IOA case 0x98: case 0x99: case 0x9a: case 0x9b: // STxx.D/A/IOD/IOA { - const uint16_t next_op = opcodes.r16(pc + 2); - const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); + const uint16_t next_op = read_hw(pc + 2); + const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, read_hw); if (size == 2) size = 4; @@ -797,8 +825,8 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x94: case 0x95: case 0x96: case 0x97: // LDxx.N/S case 0x9c: case 0x9d: case 0x9e: case 0x9f: // STxx.N/S { - const uint16_t next_op = opcodes.r16(pc + 2); - const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); + const uint16_t next_op = read_hw(pc + 2); + const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, read_hw); if (size == 2) size = 4; @@ -931,7 +959,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con LL_format(source, dest, op); pc += 2; - const uint16_t extended_op = opcodes.r16(pc); + const uint16_t extended_op = read_hw(pc); size = 4; @@ -1039,7 +1067,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0xeb: // DBGT case 0xec: // DBR { - const int32_t rel = PCrel_format(op, pc, opcodes) + 2; + const int32_t rel = PCrel_format(op, pc, read_hw) + 2; util::stream_format(stream, "D%-6s $%x", Bxx[op_num & 0xf], rel); if (op_num != 0xec) flags = STEP_COND | step_over_extra(1); @@ -1055,7 +1083,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con // CALL case 0xee: case 0xef: { - const uint32_t const_val = LRconst_format(source, dest, op, pc, opcodes); + const uint32_t const_val = LRconst_format(source, dest, op, pc, read_hw); util::stream_format(stream, "CALL %s, %s, $%x", dest, (!source_bit && (source_code == SR_REGISTER)) ? "0" : source, const_val); if (!source_bit && (source_code == PC_REGISTER)) @@ -1078,7 +1106,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0xfb: // BGT case 0xfc: // BR { - const int32_t rel = PCrel_format(op, pc, opcodes) + 2; + const int32_t rel = PCrel_format(op, pc, read_hw) + 2; util::stream_format(stream, "%-7s $%x", Bxx[op_num & 0xf], rel); if (op_num != 0xfc) flags = STEP_COND; diff --git a/src/devices/cpu/e132xs/e1dasm.h b/src/devices/cpu/e132xs/e1dasm.h new file mode 100644 index 00000000000..4a3803cc513 --- /dev/null +++ b/src/devices/cpu/e132xs/e1dasm.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Pierpaolo Prazzoli +/* + + Hyperstone E1 disassembler + written by Pierpaolo Prazzoli + +*/ + +#ifndef MAME_CPU_E132XS_E1DASM_H +#define MAME_CPU_E132XS_E1DASM_H + +#pragma once + +#include <iosfwd> +#include <string_view> + + +class hyperstone_disassembler : public util::disasm_interface +{ +public: + struct config + { + virtual ~config() = default; + + virtual bool get_h() const = 0; + }; + + hyperstone_disassembler(config *conf); + virtual ~hyperstone_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t disassemble_one(std::ostream &stream, offs_t pc, const uint16_t *opptr); + +private: + config *m_config; + + int size; // FIXME: not concurrency-safe + + template <typename T> offs_t do_disassemble(std::ostream &stream, offs_t pc, T &&read_hw); + + template <typename T> uint32_t LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw); + template <typename T> uint32_t RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw); + template <typename T> int32_t Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, T &&read_hw, unsigned h_flag); + template <typename T> int32_t PCrel_format(uint16_t op, offs_t pc, T &&read_hw); + template <typename T> uint32_t RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, T &&read_hw); +}; + +#endif // MAME_CPU_E132XS_E1DASM_H diff --git a/src/devices/cpu/e132xs/32xsdefs.h b/src/devices/cpu/e132xs/e1defs.h index 9dad4d780c5..860d04bbb2e 100644 --- a/src/devices/cpu/e132xs/32xsdefs.h +++ b/src/devices/cpu/e132xs/e1defs.h @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli -#ifndef MAME_CPU_E132XS_32XSDEFS_H -#define MAME_CPU_E132XS_32XSDEFS_H +#ifndef MAME_CPU_E132XS_E1DEFS_H +#define MAME_CPU_E132XS_E1DEFS_H #pragma once @@ -244,4 +244,4 @@ constexpr int FP_SHIFT = 25; //other bits are reversed, in particular 7 - 5 for the operating system. //the user program can only change the above 2 flags -#endif // MAME_CPU_E132XS_32XSDEFS_H +#endif // MAME_CPU_E132XS_E1DEFS_H diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e1fe.cpp index 1eb0de91382..6b8852a0f6c 100644 --- a/src/devices/cpu/e132xs/e132xsfe.cpp +++ b/src/devices/cpu/e132xs/e1fe.cpp @@ -2,21 +2,120 @@ // copyright-holders:Vas Crabb /*************************************************************************** - e132xsfe.cpp + e1fe.cpp Hyperstone E1 instruction decoder ***************************************************************************/ #include "emu.h" -#include "e132xsfe.h" +#include "e1fe.h" -#include "32xsdefs.h" +#include "e1defs.h" #include "cpu/drcfe.ipp" +void hyperstone_device::opcode_desc::log_flags(std::ostream &stream) const +{ + // branches + if (is_unconditional_branch()) + stream << 'U'; + else if (is_conditional_branch()) + stream << 'C'; + else + stream << '.'; + + // intrablock branches + stream << (intrablock_branch() ? 'i' : '.'); + + // branch targets + stream << (is_branch_target() ? 'B' : '.'); + + // delay slots + stream << (in_delay_slot() ? 'D' : '.'); + + // check H flag + stream << (check_h() ? 'H' : '.'); + + // modes + stream << (can_change_modes() ? 'M' : '.'); + + // exceptions + if (will_cause_exception()) + stream << 'E'; + else if (can_cause_exception()) + stream << 'e'; + else + stream << '.'; + + // read/write + if (reads_memory()) + stream << 'R'; + else if (writes_memory()) + stream << 'W'; + else + stream << '.'; + + // TLB validation + stream << (validate_tlb() ? 'V' : '.'); + + // redispatch + stream << (redispatch() ? 'R' : '.'); +} + +void hyperstone_device::opcode_desc::log_registers_used(std::ostream &stream) const +{ + stream << "[use:"; + log_register_list(stream, regin, nullptr); + stream << ']'; +} + +void hyperstone_device::opcode_desc::log_registers_modified(std::ostream &stream) const +{ + stream << "[mod:"; + log_register_list(stream, regout, ®req); + stream << ']'; +} + +void hyperstone_device::opcode_desc::log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist) +{ + int count = 0; + + for (int regnum = 0; regnum < 32; regnum++) + { + if (reglist[REG_G0 + regnum]) + { + if (count++) + stream << ','; + stream << 'G' << regnum; + if (regnostarlist && !(*regnostarlist)[REG_G0 + regnum]) + stream << '*'; + } + } + + const auto log_bit = + [&stream, &count, ®list, ®nostarlist] (size_t bit, const char *name) + { + if (reglist[bit]) + { + if (count++) + stream << ','; + stream << name; + if (regnostarlist && !(*regnostarlist)[bit]) + stream << '*'; + } + }; + + log_bit(REG_C, "C"); + log_bit(REG_Z, "Z"); + log_bit(REG_N, "N"); + log_bit(REG_V, "V"); + log_bit(REG_FP, "FP"); +} + + hyperstone_device::frontend::frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) : drc_frontend_base(cpu.space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence) , m_cpu(cpu) @@ -409,7 +508,11 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc if (desc.dst_local || desc.src_local) desc.set_fp_used(); if (!desc.dst_local || !desc.src_local) + { + if (!prev || prev->regout[SR_REGISTER]) + desc.set_check_h(); desc.regin.set(SR_REGISTER); // only the H bit is used + } if (!desc.src_local) { desc.set_g_used(desc.src_code); @@ -418,6 +521,8 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc if (!desc.dst_local) { desc.set_can_cause_exception(); + desc.set_g_used(desc.dst_code); + desc.set_g_used(desc.dst_code + 16); desc.set_g_modified(desc.dst_code); desc.set_g_modified(desc.dst_code + 16); if (desc.dst_code == PC_REGISTER) @@ -594,14 +699,14 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc else desc.set_znv_modified(); // negs break; - case 0x60: // cmpi global,imm - case 0x61: // cmpi global,imm - case 0x62: // cmpi local,imm - case 0x63: // cmpi local,imm - case 0x70: // cmpbi global,imm - case 0x71: // cmpbi global,imm - case 0x72: // cmpbi local,imm - case 0x73: // cmpbi local,imm + case 0x60: // cmpi global + case 0x61: // cmpi global + case 0x62: // cmpi local + case 0x63: // cmpi local + case 0x70: // cmpbi global + case 0x71: // cmpbi global + case 0x72: // cmpbi local + case 0x73: // cmpbi local decode_rimm(desc, op & 0x1000); if (desc.dst_local) desc.set_fp_used(); @@ -612,10 +717,14 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc else desc.set_cznv_modified(); // cmpi break; - case 0x64: // movi global,imm - case 0x65: // movi global,imm + case 0x64: // movi global + case 0x65: // movi global decode_rimm(desc, false); desc.set_can_cause_exception(); + if (!prev || prev->regout[SR_REGISTER]) + desc.set_check_h(); + desc.set_g_used(desc.dst_code); + desc.set_g_used(desc.dst_code + 16); desc.regin.set(SR_REGISTER); // only the H bit is used desc.set_g_modified(desc.dst_code); desc.set_g_modified(desc.dst_code + 16); @@ -630,20 +739,20 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_end_sequence(); } break; - case 0x66: // movi local,imm - case 0x67: // movi local,imm + case 0x66: // movi local + case 0x67: // movi local decode_rimm(desc, false); desc.set_fp_used(); desc.set_znv_modified(); break; - case 0x68: // addi global,imm - case 0x69: // addi global,imm - case 0x6a: // addi local,imm - case 0x6b: // addi local,imm - case 0x6c: // addsi global,imm - case 0x6d: // addsi global,imm - case 0x6e: // addsi local,imm - case 0x6f: // addsi local,imm + case 0x68: // addi global + case 0x69: // addi global + case 0x6a: // addi local + case 0x6b: // addi local + case 0x6c: // addsi global + case 0x6d: // addsi global + case 0x6e: // addsi local + case 0x6f: // addsi local decode_rimm(desc, false); if (op & 0x0400) desc.set_can_cause_exception(); // addsi @@ -667,12 +776,12 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc else desc.set_cznv_modified(); // addi break; - case 0x74: // andni global,imm - case 0x75: // andni global,imm - case 0x78: // ori global,imm - case 0x79: // ori global,imm - case 0x7c: // xori global,imm - case 0x7d: // xori global,imm + case 0x74: // andni global + case 0x75: // andni global + case 0x78: // ori global + case 0x79: // ori global + case 0x7c: // xori global + case 0x7d: // xori global decode_rimm(desc, !(op & 0x0800)); desc.set_g_used(desc.dst_code); desc.set_g_modified(desc.dst_code); @@ -689,12 +798,12 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc } desc.set_z_modified(); break; - case 0x76: // andni local,imm - case 0x77: // andni local,imm - case 0x7a: // ori local,imm - case 0x7b: // ori local,imm - case 0x7e: // xori local,imm - case 0x7f: // xori local,imm + case 0x76: // andni local + case 0x77: // andni local + case 0x7a: // ori local + case 0x7b: // ori local + case 0x7e: // xori local + case 0x7f: // xori local decode_rimm(desc, !(op & 0x0800)); desc.set_fp_used(); desc.set_z_modified(); diff --git a/src/devices/cpu/e132xs/e132xsfe.h b/src/devices/cpu/e132xs/e1fe.h index f3075a415c8..97354a950f2 100644 --- a/src/devices/cpu/e132xs/e132xsfe.h +++ b/src/devices/cpu/e132xs/e1fe.h @@ -2,13 +2,13 @@ // copyright-holders:Vas Crabb /*************************************************************************** - e132xsfe.h + e1fe.h Hyperstone E1 instruction decoder ***************************************************************************/ -#ifndef MAME_CPU_E132XS_E132XSFE_H -#define MAME_CPU_E132XS_E132XSFE_H +#ifndef MAME_CPU_E132XS_E1FE_H +#define MAME_CPU_E132XS_E1FE_H #pragma once @@ -19,6 +19,7 @@ #include <algorithm> #include <cassert> #include <bitset> +#include <iosfwd> class hyperstone_device::opcode_desc : public opcode_desc_base<opcode_desc, 40> @@ -70,13 +71,11 @@ public: void set_z_modified() { - regout.set(REG_SR); regout.set(REG_Z); } void set_znv_modified() { - regout.set(REG_SR); regout.set(REG_Z); regout.set(REG_N); regout.set(REG_V); @@ -84,7 +83,6 @@ public: void set_czn_modified() { - regout.set(REG_SR); regout.set(REG_C); regout.set(REG_Z); regout.set(REG_N); @@ -92,7 +90,6 @@ public: void set_cznv_modified() { - regout.set(REG_SR); regout.set(REG_C); regout.set(REG_Z); regout.set(REG_N); @@ -101,7 +98,6 @@ public: void set_fp_modified() { - regout.set(REG_SR); regout.set(REG_FP); } @@ -111,10 +107,12 @@ public: bool v_calc_required() const { return regreq[REG_V] || in_delay_slot(); } bool condition_calc_required() const { return regreq[REG_C] || regreq[REG_Z] || regreq[REG_N] || regreq[REG_V] || in_delay_slot(); } + void set_check_h() { m_extra_flags.set(CHECK_H); } void set_can_change_modes() { m_extra_flags.set(CAN_CHANGE_MODES); } void set_reads_memory() { m_extra_flags.set(READS_MEMORY); } void set_writes_memory() { m_extra_flags.set(WRITES_MEMORY); } + bool check_h() const { return m_extra_flags[CHECK_H]; } bool can_change_modes() const { return m_extra_flags[CAN_CHANGE_MODES]; } bool reads_memory() const { return m_extra_flags[READS_MEMORY]; } bool writes_memory() const { return m_extra_flags[WRITES_MEMORY]; } @@ -146,6 +144,10 @@ public: m_extra_flags.reset(); } + void log_flags(std::ostream &stream) const; + void log_registers_used(std::ostream &stream) const; + void log_registers_modified(std::ostream &stream) const; + protected: enum { @@ -164,13 +166,16 @@ protected: enum { - CAN_CHANGE_MODES = 0, + CHECK_H = 0, + CAN_CHANGE_MODES, READS_MEMORY, WRITES_MEMORY, EXTRA_FLAG_COUNT }; + static void log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist); + std::bitset<EXTRA_FLAG_COUNT> m_extra_flags; }; @@ -207,4 +212,4 @@ private: hyperstone_device &m_cpu; }; -#endif // MAME_CPU_E132XS_E132XSFE_H +#endif // MAME_CPU_E132XS_E1FE_H diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h index d00bcac10a1..86292a1dba5 100644 --- a/src/devices/cpu/powerpc/ppc.h +++ b/src/devices/cpu/powerpc/ppc.h @@ -16,12 +16,10 @@ #include "ppc_dasm.h" #include "cpu/drcuml.h" -#include "cpu/drcumlsh.h" #include "divtlb.h" #include <algorithm> -#include <bitset> /*************************************************************************** @@ -700,8 +698,6 @@ protected: bool generate_instruction_3b(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc); bool generate_instruction_3f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc); void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op); - const char *log_desc_flags_to_string(const opcode_desc &desc); - void log_register_list(const char *string, const std::bitset<128> ®list, const std::bitset<128> *regnostarlist); void log_opcode_desc(const opcode_desc *desclist, int indent); private: diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 1ced08d9dc5..ee0c9b664bc 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -23,6 +23,10 @@ #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" +#include "util/vecstream.h" + +#include <locale> + /*************************************************************************** @@ -1764,9 +1768,9 @@ void ppc_device::generate_compute_flags(drcuml_block &block, const opcode_desc * /* modify inputs based on required flags */ if (!DISABLE_FLAG_OPTIMIZATIONS) { - if (!frontend::REGFLAG_XER_CA(desc->regreq)) + if (!desc->xer_ca_required()) xermask &= ~XER_CA; - if (!frontend::REGFLAG_CR(desc->regreq, 0)) + if (!desc->cr_required(0)) updatecr = 0; } const uint32_t xerflags = ((xermask & XER_OV) ? uml::FLAG_V : 0) | ((xermask & XER_CA) ? uml::FLAG_C : 0); @@ -2969,7 +2973,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 || frontend::REGFLAG_XER_CA(desc->regreq)) + if (DISABLE_FLAG_OPTIMIZATIONS || desc->xer_ca_required()) { // 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); @@ -2980,7 +2984,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 || frontend::REGFLAG_XER_CA(desc->regreq)) + if (DISABLE_FLAG_OPTIMIZATIONS || desc->xer_ca_required()) { UML_SHL(block, I1, 0xffffffff, I2); // shl i1,0xffffffff,i2 UML_XOR(block, I1, I1, ~0); // xor i1,i1,~0 @@ -3001,7 +3005,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co return true; case 0x338: /* SRAWIx */ - if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq)) + if (DISABLE_FLAG_OPTIMIZATIONS || desc->xer_ca_required()) { 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 @@ -3917,213 +3921,56 @@ void ppc_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32 /*------------------------------------------------- - log_desc_flags_to_string - generate a string - representing the instruction description - flags --------------------------------------------------*/ - -const char *ppc_device::log_desc_flags_to_string(const opcode_desc &desc) -{ - static char tempbuf[30]; - char *dest = tempbuf; - - /* branches */ - if (desc.is_unconditional_branch()) - *dest++ = 'U'; - else if (desc.is_conditional_branch()) - *dest++ = 'C'; - else - *dest++ = '.'; - - /* intrablock branches */ - *dest++ = desc.intrablock_branch() ? 'i' : '.'; - - /* branch targets */ - *dest++ = desc.is_branch_target() ? 'B' : '.'; - - /* delay slots */ - *dest++ = desc.in_delay_slot() ? 'D' : '.'; - - /* exceptions */ - if (desc.will_cause_exception()) - *dest++ = 'E'; - else if (desc.can_cause_exception()) - *dest++ = 'e'; - else - *dest++ = '.'; - - /* read/write */ - if (desc.reads_memory()) - *dest++ = 'R'; - else if (desc.writes_memory()) - *dest++ = 'W'; - else - *dest++ = '.'; - - /* TLB validation */ - *dest++ = desc.validate_tlb() ? 'V' : '.'; - - /* redispatch */ - *dest++ = desc.redispatch() ? 'R' : '.'; - return tempbuf; -} - - -/*------------------------------------------------- - log_register_list - log a list of GPR registers --------------------------------------------------*/ - -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; - int regnum; - int crnum; - - /* skip if nothing */ - if (reglist.none()) - return; - - m_drcuml->log_printf("[%s:", string); - - for (regnum = 0; regnum < 32; regnum++) - { - if (frontend::REGFLAG_R(reglist, regnum)) - { - m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist && !frontend::REGFLAG_R(*regnostarlist, regnum)) - m_drcuml->log_printf("*"); - } - } - - for (regnum = 0; regnum < 32; regnum++) - { - if (frontend::REGFLAG_FR(reglist, regnum)) - { - m_drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist && !frontend::REGFLAG_FR(*regnostarlist, regnum)) - m_drcuml->log_printf("*"); - } - } - - for (regnum = 0; regnum < 8; regnum++) - { - if (frontend::REGFLAG_CR(reglist, 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 && !frontend::REGFLAG_CR(*regnostarlist, regnum)) - m_drcuml->log_printf("*"); - } - else - { - for (crnum = 0; crnum < 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 && !frontend::REGFLAG_CR_BIT(*regnostarlist, regnum * 4 + crnum)) - m_drcuml->log_printf("*"); - } - } - } - } - } - - if (frontend::REGFLAG_XER_CA(reglist)) - { - m_drcuml->log_printf("%sxer_ca", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_XER_CA(*regnostarlist)) - m_drcuml->log_printf("*"); - } - if (frontend::REGFLAG_XER_OV(reglist)) - { - m_drcuml->log_printf("%sxer_ov", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_XER_OV(*regnostarlist)) - m_drcuml->log_printf("*"); - } - if (frontend::REGFLAG_XER_SO(reglist)) - { - m_drcuml->log_printf("%sxer_so", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_XER_SO(*regnostarlist)) - m_drcuml->log_printf("*"); - } - if (frontend::REGFLAG_XER_COUNT(reglist)) - { - m_drcuml->log_printf("%sxer_count", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_XER_COUNT(*regnostarlist)) - m_drcuml->log_printf("*"); - } - if (frontend::REGFLAG_CTR(reglist)) - { - m_drcuml->log_printf("%sctr", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_CTR(*regnostarlist)) - m_drcuml->log_printf("*"); - } - if (frontend::REGFLAG_LR(reglist)) - { - m_drcuml->log_printf("%slr", (count++ == 0) ? "" : ","); - if (regnostarlist && !frontend::REGFLAG_LR(*regnostarlist)) - m_drcuml->log_printf("*"); - } - - for (regnum = 0; regnum < 8; regnum++) - { - if (frontend::REGFLAG_FPSCR(reglist, regnum)) - { - m_drcuml->log_printf("%sfpscr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist && !frontend::REGFLAG_FPSCR(*regnostarlist, regnum)) - m_drcuml->log_printf("*"); - } - } - - m_drcuml->log_printf("] "); -} - - -/*------------------------------------------------- log_opcode_desc - log a list of descriptions -------------------------------------------------*/ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent) { util::ovectorstream buffer; + buffer.imbue(std::locale::classic()); - /* open the file, creating it if necessary */ + // assume no indent is the start of a sequence and needs a heading if (indent == 0) m_drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); - /* output each descriptor */ + // output each description for ( ; desclist != nullptr; desclist = desclist->next()) { buffer.clear(); buffer.seekp(0); + desclist->log_flags(buffer); + buffer.put('\0'); + m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: ", desclist->pc, desclist->physpc, desclist->targetpc, &buffer.vec()[0]); - /* disassemble the current instruction and output it to the log */ - if (m_drcuml->logging() || m_drcuml->logging_native()) - { - if (desclist->virtual_noop()) - buffer << "<virtual nop>"; - else - m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr); - } + // disassemble the current instruction and output it to the log + buffer.clear(); + buffer.seekp(0); + if (desclist->virtual_noop()) + buffer << "<virtual nop>"; else - buffer << "???"; - + m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr); 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), &buffer.vec()[0]); + m_drcuml->log_printf("%-30s", &buffer.vec()[0]); - /* output register states */ - log_register_list("use", desclist->regin, nullptr); - log_register_list("mod", desclist->regout, &desclist->regreq); - m_drcuml->log_printf("\n"); + // output register dependencies + buffer.clear(); + buffer.seekp(0); + if (!desclist->regin.none()) + { + desclist->log_registers_used(buffer); + if (!desclist->regout.none()) + buffer << ' '; + } + if (!desclist->regout.none()) + desclist->log_registers_modified(buffer); + buffer.put('\0'); + m_drcuml->log_printf("%s\n", &buffer.vec()[0]); - /* if we have a delay slot, output it recursively */ + // if we have a delay slot, output it recursively if (desclist->delay.first() != nullptr) log_opcode_desc(desclist->delay.first(), indent + 1); - /* at the end of a sequence add a dividing line */ + // at the end of a sequence add a dividing line if (desclist->end_sequence()) m_drcuml->log_printf("-----\n"); } diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp index 6b8be8061fe..e970e6706f8 100644 --- a/src/devices/cpu/powerpc/ppcfe.cpp +++ b/src/devices/cpu/powerpc/ppcfe.cpp @@ -16,38 +16,166 @@ #include "cpu/drcfe.ipp" -//************************************************************************** -// MACROS -//************************************************************************** -#define GPR_USED(desc, x) do { (desc).regin.set(REG_BIT_R0 + x); } while (0) -#define GPR_USED_OR_ZERO(desc, x) do { if (x) GPR_USED((desc), x); } while (0) -#define GPR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_R0 + x); } while (0) +/*------------------------------------------------- + log_flags - write a string representing the + instruction description flags to a stream +-------------------------------------------------*/ + +void ppc_device::opcode_desc::log_flags(std::ostream &stream) const +{ + // branches + if (is_unconditional_branch()) + stream << 'U'; + else if (is_conditional_branch()) + stream << 'C'; + else + stream << '.'; + + // intrablock branches + stream << (intrablock_branch() ? 'i' : '.'); + + // branch targets + stream << (is_branch_target() ? 'B' : '.'); + + // delay slots + stream << (in_delay_slot() ? 'D' : '.'); + + // exceptions + if (will_cause_exception()) + stream << 'E'; + else if (can_cause_exception()) + stream << 'e'; + else + stream << '.'; + + // read/write + if (reads_memory()) + stream << 'R'; + else if (writes_memory()) + stream << 'W'; + else + stream << '.'; -#define FPR_USED(desc, x) do { (desc).regin.set(REG_BIT_FR0 + x); } while (0) -#define FPR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_FR0 + x); } while (0) + // TLB validation + stream << (validate_tlb() ? 'V' : '.'); -#define CR_USED(desc, x) do { CR_BIT_USED((desc), (x * 4) + 0); CR_BIT_USED((desc), (x * 4) + 1); CR_BIT_USED((desc), (x * 4) + 2); CR_BIT_USED((desc), (x * 4) + 3); } while (0) -#define CR_BIT_USED(desc, x) do { (desc).regin.set(64 + 31 - x); } while (0) -#define CR_MODIFIED(desc, x) do { CR_BIT_MODIFIED((desc), (x * 4) + 0); CR_BIT_MODIFIED((desc), (x * 4) + 1); CR_BIT_MODIFIED((desc), (x * 4) + 2); CR_BIT_MODIFIED((desc), (x * 4) + 3); } while (0) -#define CR_BIT_MODIFIED(desc, x) do { (desc).regout.set(64 + 31 - x); } while (0) + // redispatch + stream << (redispatch() ? 'R' : '.'); +} -#define XER_CA_USED(desc) do { (desc).regin.set(REG_BIT_XER_CA); } while (0) -#define XER_OV_USED(desc) do { (desc).regin.set(REG_BIT_XER_OV); } while (0) -#define XER_SO_USED(desc) do { (desc).regin.set(REG_BIT_XER_SO); } while (0) -#define XER_COUNT_USED(desc) do { (desc).regin.set(REG_BIT_XER_COUNT); } while (0) -#define XER_CA_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_CA); } while (0) -#define XER_OV_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_OV); } while (0) -#define XER_SO_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_SO); } while (0) -#define XER_COUNT_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_COUNT); } while (0) -#define CTR_USED(desc) do { (desc).regin.set(REG_BIT_CTR); } while (0) -#define CTR_MODIFIED(desc) do { (desc).regout.set(REG_BIT_CTR); } while (0) -#define LR_USED(desc) do { (desc).regin.set(REG_BIT_LR); } while (0) -#define LR_MODIFIED(desc) do { (desc).regout.set(REG_BIT_LR); } while (0) +/*------------------------------------------------- + log_register_list - log a list of registers +-------------------------------------------------*/ + +void ppc_device::opcode_desc::log_registers_used(std::ostream &stream) const +{ + stream << "[use:"; + log_register_list(stream, regin, nullptr); + stream << ']'; +} -#define FPSCR_USED(desc, x) do { (desc).regin.set(REG_BIT_FPSCR0 + x); } while (0) -#define FPSCR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_FPSCR0 + x); } while (0) +void ppc_device::opcode_desc::log_registers_modified(std::ostream &stream) const +{ + stream << "[mod:"; + log_register_list(stream, regout, ®req); + stream << ']'; +} + +void ppc_device::opcode_desc::log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist) +{ + static const char *const crtext[4] = { "lt", "gt", "eq", "so" }; + int count = 0; + + for (int regnum = 0; regnum < 32; regnum++) + { + if (reglist[REG_BIT_R0 + regnum]) + { + if (count++) + stream << ','; + stream << 'r' << regnum; + if (regnostarlist && !(*regnostarlist)[REG_BIT_R0 + regnum]) + stream << '*'; + } + } + + for (int regnum = 0; regnum < 32; regnum++) + { + if (reglist[REG_BIT_FR0 + regnum]) + { + if (count++) + stream << ','; + stream << "fr" << regnum; + if (regnostarlist && !(*regnostarlist)[REG_BIT_FR0 + regnum]) + stream << '*'; + } + } + + for (int regnum = 0; regnum < 8; regnum++) + { + if (!reg_cr(reglist, regnum)) + continue; + + if (count++) + stream << ','; + stream << "cr" << regnum; + if ((reg_cr(reglist, regnum) == 0x0f) && (!regnostarlist || (reg_cr(*regnostarlist, regnum) == 0x0f) || !reg_cr(*regnostarlist, regnum))) + { + if (regnostarlist && !reg_cr(*regnostarlist, regnum)) + stream << '*'; + } + else + { + int crcount = 0; + stream << '['; + for (int crnum = 0; crnum < 4; crnum++) + { + if (reg_cr_bit(reglist, (regnum * 4) + crnum)) + { + if (crcount++) + stream << ','; + stream << crtext[crnum]; + if (regnostarlist && !reg_cr_bit(*regnostarlist, (regnum * 4) + crnum)) + stream << '*'; + } + } + stream << ']'; + } + } + + const auto log_bit = + [&stream, &count, ®list, ®nostarlist] (size_t bit, const char *name) + { + if (reglist[bit]) + { + if (count++) + stream << ','; + stream << name; + if (regnostarlist && !(*regnostarlist)[bit]) + stream << '*'; + } + }; + + log_bit(REG_BIT_XER_CA, "xer_ca"); + log_bit(REG_BIT_XER_OV, "xer_ov"); + log_bit(REG_BIT_XER_SO, "xer_so"); + log_bit(REG_BIT_XER_COUNT, "xer_count"); + log_bit(REG_BIT_CTR, "ctr"); + log_bit(REG_BIT_LR, "lr"); + + for (int regnum = 0; regnum < 8; regnum++) + { + if (reglist[REG_BIT_FPSCR0 + regnum]) + { + if (count++) + stream << ','; + stream << "fpscr" << regnum; + if (regnostarlist && !(*regnostarlist)[REG_BIT_FPSCR0 + regnum]) + stream << '*'; + } + } +} @@ -117,15 +245,15 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) return false; case 0x03: // TWI - GPR_USED(desc, G_RA(op)); + desc.set_gpr_used(G_RA(op)); desc.set_can_cause_exception(); if (is_603_class()) desc.cycles = 2; // 603 return true; case 0x07: // MULLI - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); if (is_403_class()) desc.cycles = 4; // 4XX else if (is_601_class()) @@ -142,53 +270,53 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) return false; } - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); return true; case 0x0e: // ADDI case 0x0f: // ADDIS - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); return true; case 0x0a: // CMPLI case 0x0b: // CMPI - GPR_USED(desc, G_RA(op)); - XER_SO_USED(desc); - CR_MODIFIED(desc, G_CRFD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_xer_so_used(); + desc.set_cr_modified(G_CRFD(op)); return true; case 0x08: // SUBFIC case 0x0c: // ADDIC - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ca_modified(); return true; case 0x0d: // ADDIC. - GPR_USED(desc, G_RA(op)); - XER_SO_USED(desc); - GPR_MODIFIED(desc, G_RT(op)); - XER_CA_MODIFIED(desc); - CR_MODIFIED(desc, 0); + desc.set_gpr_used(G_RA(op)); + desc.set_xer_so_used(); + desc.set_gpr_modified(G_RT(op)); + desc.set_xer_ca_modified(); + desc.set_cr_modified(0); return true; case 0x10: // BCx if (!(G_BO(op) & 0x10)) { - CR_BIT_USED(desc, G_BI(op)); + desc.set_cr_bit_used(G_BI(op)); // branch folding - if (prev == nullptr || REGFLAG_CR(prev->regout) == 0) + if (!prev || (prev->cr_modified() == 0)) desc.cycles = 0; } if (!(G_BO(op) & 0x04)) { - CTR_USED(desc); - CTR_MODIFIED(desc); + desc.set_ctr_used(); + desc.set_ctr_modified(); } if (op & M_LK) - LR_MODIFIED(desc); + desc.set_lr_modified(); if ((G_BO(op) & 0x14) == 0x14) { desc.set_is_unconditional_branch(); @@ -218,7 +346,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x12: // Bx if (op & M_LK) - LR_MODIFIED(desc); + desc.set_lr_modified(); desc.set_is_unconditional_branch(); desc.set_end_sequence(); desc.targetpc = ((int32_t)(G_LI(op) << 8) >> 6) + ((op & M_AA) ? 0 : desc.pc); @@ -231,34 +359,34 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) return describe_13(op, desc, prev); case 0x14: // RLWIMIx - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x15: // RLWINMx - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x17: // RLWNMx - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; @@ -266,16 +394,16 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x19: // ORIS case 0x1a: // XORI case 0x1b: // XORIS - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); return true; case 0x1c: // ANDI. case 0x1d: // ANDIS. - GPR_USED(desc, G_RS(op)); - XER_SO_USED(desc); - GPR_MODIFIED(desc, G_RA(op)); - CR_MODIFIED(desc, 0); + desc.set_gpr_used(G_RS(op)); + desc.set_xer_so_used(); + desc.set_gpr_modified(G_RA(op)); + desc.set_cr_modified(0); return true; case 0x1f: // 0x1f group @@ -285,8 +413,8 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x22: // LBZ case 0x28: // LHZ case 0x2a: // LHA - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_reads_memory(); return true; @@ -296,17 +424,17 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x2b: // LHAU if (G_RA(op) == 0 || G_RA(op) == G_RD(op)) return false; - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_gpr_modified(G_RA(op)); desc.set_reads_memory(); return true; case 0x24: // STW case 0x26: // STB case 0x2c: // STH - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RS(op)); desc.set_writes_memory(); return true; @@ -315,28 +443,28 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x2d: // STHU if (G_RA(op) == 0) return false; - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); desc.set_writes_memory(); return true; case 0x2e: // LMW - GPR_USED_OR_ZERO(desc, G_RA(op)); + desc.set_gpr_used_or_zero(G_RA(op)); for (regnum = G_RD(op); regnum < 32; regnum++) { if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31)) - GPR_MODIFIED(desc, regnum); + desc.set_gpr_modified(regnum); } desc.set_reads_memory(); desc.cycles = 32 - G_RD(op); return true; case 0x2f: // STMW - GPR_USED_OR_ZERO(desc, G_RA(op)); + desc.set_gpr_used_or_zero(G_RA(op)); for (regnum = G_RS(op); regnum < 32; regnum++) - GPR_USED(desc, regnum); + desc.set_gpr_used(regnum); desc.set_writes_memory(); desc.cycles = 32 - G_RS(op); return true; @@ -345,8 +473,8 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x32: // LFD if (!(m_ppc.m_cap & PPCCAP_FPU)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_fpr_modified(G_RD(op)); desc.set_reads_memory(); return true; @@ -356,9 +484,9 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) return false; if (G_RA(op) == 0) return false; - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RA(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_fpr_modified(G_RD(op)); desc.set_reads_memory(); return true; @@ -366,8 +494,8 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x36: // STFD if (!(m_ppc.m_cap & PPCCAP_FPU)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - FPR_USED(desc, G_RS(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_fpr_used(G_RS(op)); desc.set_writes_memory(); return true; @@ -377,9 +505,9 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) return false; if (G_RA(op) == 0) return false; - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RA(op)); - FPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_fpr_used(G_RS(op)); desc.set_writes_memory(); return true; @@ -407,24 +535,24 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc switch (opswitch) { case 0x000: // MTCRF - CR_USED(desc, G_CRFS(op)); - CR_MODIFIED(desc, G_CRFD(op)); + desc.set_cr_used(G_CRFS(op)); + desc.set_cr_modified(G_CRFD(op)); // CR logical folding - if (prev == nullptr || REGFLAG_CR(prev->regout) == 0) + if (!prev || (prev->cr_modified() == 0)) desc.cycles = 0; return true; case 0x010: // BCLRx - LR_USED(desc); + desc.set_lr_used(); if (!(G_BO(op) & 0x10)) - CR_BIT_USED(desc, G_BI(op)); + desc.set_cr_bit_used(G_BI(op)); if (!(G_BO(op) & 0x04)) { - CTR_USED(desc); - CTR_MODIFIED(desc); + desc.set_ctr_used(); + desc.set_ctr_modified(); } if (op & M_LK) - LR_MODIFIED(desc); + desc.set_lr_modified(); if ((G_BO(op) & 0x14) == 0x14) { desc.set_is_unconditional_branch(); @@ -445,11 +573,11 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc case 0x121: // CREQV case 0x1a1: // CRORC case 0x1c1: // CROR - CR_BIT_USED(desc, G_CRBA(op)); - CR_BIT_USED(desc, G_CRBB(op)); - CR_BIT_MODIFIED(desc, G_CRBD(op)); + desc.set_cr_bit_used(G_CRBA(op)); + desc.set_cr_bit_used(G_CRBB(op)); + desc.set_cr_bit_modified(G_CRBD(op)); // CR logical folding - if (prev == nullptr || REGFLAG_CR(prev->regout) == 0) + if (!prev || (prev->cr_modified() == 0)) desc.cycles = 0; return true; @@ -489,13 +617,13 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc return true; case 0x210: // BCCTRx - CTR_USED(desc); + desc.set_ctr_used(); if (!(G_BO(op) & 0x10)) - CR_BIT_USED(desc, G_BI(op)); + desc.set_cr_bit_used(G_BI(op)); if (!(G_BO(op) & 0x04)) return false; if (op & M_LK) - LR_MODIFIED(desc); + desc.set_lr_modified(); if ((G_BO(op) & 0x14) == 0x14) { desc.set_is_unconditional_branch(); @@ -556,15 +684,15 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x000: // CMP case 0x020: // CMPL - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - XER_SO_USED(desc); - CR_MODIFIED(desc, G_CRFD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_xer_so_used(); + desc.set_cr_modified(G_CRFD(op)); return true; case 0x004: // TW - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); desc.set_can_cause_exception(); if (is_603_class()) desc.cycles = 2; // 603 @@ -572,28 +700,28 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x008: // SUBFCx case 0x00a: // ADDCx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ca_modified(); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x088: // SUBFEx case 0x08a: // ADDEx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - XER_CA_USED(desc); - GPR_MODIFIED(desc, G_RD(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_xer_ca_used(); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ca_modified(); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; @@ -601,27 +729,27 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x0ca: // ADDZEx case 0x0e8: // SUBFMEx case 0x0ea: // ADDMEx - GPR_USED(desc, G_RA(op)); - XER_CA_USED(desc); - GPR_MODIFIED(desc, G_RD(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_xer_ca_used(); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ca_modified(); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x00b: // MULHWUx case 0x04b: // MULHWx case 0x0eb: // MULLWx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } if (is_403_class()) desc.cycles = 4; // 4XX @@ -635,13 +763,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x1cb: // DIVWUx case 0x1eb: // DIVWx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } if (is_403_class()) desc.cycles = 33; // 4XX @@ -655,63 +783,63 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x028: // SUBFx case 0x10a: // ADDx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x208: // SUBFCOx case 0x20a: // ADDCOx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); + desc.set_xer_ca_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x288: // SUBFEOx case 0x28a: // ADDEOx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - XER_CA_USED(desc); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_xer_ca_used(); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); + desc.set_xer_ca_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x2c8: // SUBFZEOx case 0x2ca: // ADDZEOx case 0x2e8: // SUBFMEOx case 0x2ea: // ADDMEOx - GPR_USED(desc, G_RA(op)); - XER_CA_USED(desc); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_xer_ca_used(); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); + desc.set_xer_ca_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x2eb: // MULLWOx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); if (is_403_class()) desc.cycles = 4; // 4XX else if (is_601_class()) @@ -724,13 +852,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x3cb: // DIVWUOx case 0x3eb: // DIVWOx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); if (is_403_class()) desc.cycles = 33; // 4XX else if (is_601_class()) @@ -743,25 +871,25 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x228: // SUBFOx case 0x30a: // ADDOx - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x013: // MFCR - CR_USED(desc, 0); - CR_USED(desc, 1); - CR_USED(desc, 2); - CR_USED(desc, 3); - CR_USED(desc, 4); - CR_USED(desc, 5); - CR_USED(desc, 6); - CR_USED(desc, 7); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_cr_used(0); + desc.set_cr_used(1); + desc.set_cr_used(2); + desc.set_cr_used(3); + desc.set_cr_used(4); + desc.set_cr_used(5); + desc.set_cr_used(6); + desc.set_cr_used(7); + desc.set_gpr_modified(G_RD(op)); return true; case 0x136: // ECIWX @@ -775,9 +903,9 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x157: // LHAX case 0x216: // LWBRX case 0x316: // LHBRX - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_reads_memory(); return true; @@ -790,38 +918,38 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x19c: // ORCx case 0x1bc: // ORx case 0x1dc: // NANDx - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x218: // SRWx case 0x318: // SRAWx - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_xer_ca_modified(); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x01a: // CNTLZWx case 0x39a: // EXTSHx case 0x3ba: // EXTSBx - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; @@ -833,15 +961,15 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x3d6: // ICBI if (!(m_ppc.m_cap & (PPCCAP_VEA | PPCCAP_4XX))) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); return true; case 0x1d6: // DCBI if (!(m_ppc.m_cap & (PPCCAP_OEA | PPCCAP_4XX))) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -852,26 +980,26 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x177: // LHAUX if (G_RA(op) == 0 || G_RA(op) == G_RD(op)) return false; - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_gpr_modified(G_RA(op)); desc.set_reads_memory(); return true; case 0x153: // MFSPR - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_modified(G_RD(op)); spr = compute_spr(G_SPR(op)); if (spr == SPR_LR) - LR_USED(desc); + desc.set_lr_used(); if (spr == SPR_CTR) - CTR_USED(desc); + desc.set_ctr_used(); if (spr == SPR_XER) { - XER_COUNT_USED(desc); - XER_CA_USED(desc); - XER_OV_USED(desc); - XER_SO_USED(desc); + desc.set_xer_count_used(); + desc.set_xer_ca_used(); + desc.set_xer_ov_used(); + desc.set_xer_so_used(); } if (spr & 0x010) { @@ -887,7 +1015,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return true; case 0x053: // MFMSR - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_can_cause_exception(); desc.set_can_expose_external_int(); desc.set_privileged(); @@ -896,14 +1024,14 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return true; case 0x253: // MFSR - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; case 0x293: // MFSRIN - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -911,45 +1039,45 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x173: // MFTB if (!(m_ppc.m_cap & PPCCAP_VEA)) return false; - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_modified(G_RD(op)); spr = compute_spr(G_SPR(op)); if (spr == SPRVEA_TBL_R) desc.cycles = POWERPC_COUNT_READ_TBL; return true; case 0x068: // NEGx - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x268: // NEGOx - GPR_USED(desc, G_RA(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x090: // MTCRF - GPR_USED(desc, G_RS(op)); - if (G_CRM(op) & 0x80) CR_MODIFIED(desc, 0); - if (G_CRM(op) & 0x40) CR_MODIFIED(desc, 1); - if (G_CRM(op) & 0x20) CR_MODIFIED(desc, 2); - if (G_CRM(op) & 0x10) CR_MODIFIED(desc, 3); - if (G_CRM(op) & 0x08) CR_MODIFIED(desc, 4); - if (G_CRM(op) & 0x04) CR_MODIFIED(desc, 5); - if (G_CRM(op) & 0x02) CR_MODIFIED(desc, 6); - if (G_CRM(op) & 0x01) CR_MODIFIED(desc, 7); + desc.set_gpr_used(G_RS(op)); + if (G_CRM(op) & 0x80) desc.set_cr_modified(0); + if (G_CRM(op) & 0x40) desc.set_cr_modified(1); + if (G_CRM(op) & 0x20) desc.set_cr_modified(2); + if (G_CRM(op) & 0x10) desc.set_cr_modified(3); + if (G_CRM(op) & 0x08) desc.set_cr_modified(4); + if (G_CRM(op) & 0x04) desc.set_cr_modified(5); + if (G_CRM(op) & 0x02) desc.set_cr_modified(6); + if (G_CRM(op) & 0x01) desc.set_cr_modified(7); return true; case 0x092: // MTMSR - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RS(op)); desc.set_can_cause_exception(); desc.set_end_sequence(); desc.set_privileged(); @@ -963,24 +1091,24 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x0d2: // MTSR if (!(m_ppc.m_cap & PPCCAP_OEA)) return false; - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RS(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; case 0x1d3: // MTSPR - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RS(op)); spr = compute_spr(G_SPR(op)); if (spr == SPR_LR) - LR_MODIFIED(desc); + desc.set_lr_modified(); if (spr == SPR_CTR) - CTR_MODIFIED(desc); + desc.set_ctr_modified(); if (spr == SPR_XER) { - XER_COUNT_MODIFIED(desc); - XER_CA_MODIFIED(desc); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_xer_count_modified(); + desc.set_xer_ca_modified(); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); } if (spr & 0x010) { @@ -999,9 +1127,9 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x197: // STHX case 0x296: // STWBRX case 0x396: // STHBRX - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_used(G_RS(op)); desc.set_writes_memory(); return true; @@ -1010,18 +1138,18 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x1b7: // STHUX if (G_RA(op) == 0) return false; - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); desc.set_writes_memory(); return true; case 0x0f2: // MTSRIN if (!(m_ppc.m_cap & PPCCAP_OEA)) return false; - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RB(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -1029,7 +1157,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x132: // TLBIE if (!(m_ppc.m_cap & PPCCAP_OEA)) return false; - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used(G_RB(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -1050,21 +1178,21 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return true; case 0x200: // MCRXR - XER_CA_USED(desc); - XER_OV_USED(desc); - XER_SO_USED(desc); - CR_MODIFIED(desc, G_CRFD(op)); - XER_CA_MODIFIED(desc); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_xer_ca_used(); + desc.set_xer_ov_used(); + desc.set_xer_so_used(); + desc.set_cr_modified(G_CRFD(op)); + desc.set_xer_ca_modified(); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); return true; case 0x215: // LSWX - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - XER_COUNT_USED(desc); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_xer_count_used(); for (regnum = 0; regnum < 32; regnum++) - GPR_MODIFIED(desc, regnum); + desc.set_gpr_modified(regnum); desc.set_reads_memory(); return true; @@ -1072,9 +1200,9 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x257: // LFDX if (!(m_ppc.m_cap & PPCCAP_FPU)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); desc.set_reads_memory(); return true; @@ -1099,34 +1227,34 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; if (G_RA(op) == 0) return false; - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_fpr_modified(G_RD(op)); desc.set_reads_memory(); return true; case 0x255: // LSWI - GPR_USED_OR_ZERO(desc, G_RA(op)); + desc.set_gpr_used_or_zero(G_RA(op)); for (regnum = 0; regnum < ((G_NB(op) - 1) & 0x1f) + 1; regnum += 4) - GPR_MODIFIED(desc, (G_RD(op) + regnum / 4) % 32); + desc.set_gpr_modified((G_RD(op) + regnum / 4) % 32); desc.set_reads_memory(); desc.cycles = (((G_NB(op) - 1) & 0x1f) + 1 + 3) / 4; return true; case 0x295: // STSWX - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - XER_COUNT_USED(desc); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_xer_count_used(); for (regnum = 0; regnum < 32; regnum++) - GPR_USED(desc, regnum); + desc.set_gpr_used(regnum); desc.set_writes_memory(); return true; case 0x2d5: // STSWI - GPR_USED_OR_ZERO(desc, G_RA(op)); + desc.set_gpr_used_or_zero(G_RA(op)); for (regnum = 0; regnum < ((G_NB(op) - 1) & 0x1f) + 1; regnum += 4) - GPR_USED(desc, (G_RD(op) + regnum / 4) % 32); + desc.set_gpr_used((G_RD(op) + regnum / 4) % 32); desc.set_writes_memory(); desc.cycles = (((G_NB(op) - 1) & 0x1f) + 1 + 3) / 4; return true; @@ -1136,9 +1264,9 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x3d7: // STFIWX if (!(m_ppc.m_cap & PPCCAP_FPU)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - FPR_USED(desc, G_RS(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_fpr_used(G_RS(op)); desc.set_writes_memory(); return true; @@ -1148,29 +1276,29 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; if (G_RA(op) == 0) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); - FPR_USED(desc, G_RS(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_fpr_used(G_RS(op)); desc.set_writes_memory(); return true; case 0x338: // SRAWIx - GPR_USED(desc, G_RS(op)); - GPR_MODIFIED(desc, G_RA(op)); - XER_CA_MODIFIED(desc); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_modified(G_RA(op)); + desc.set_xer_ca_modified(); if (op & M_RC) { - XER_SO_USED(desc); - CR_MODIFIED(desc, 0); + desc.set_xer_so_used(); + desc.set_cr_modified(0); } return true; case 0x3f6: // DCBZ if (!(m_ppc.m_cap & (PPCCAP_VEA | PPCCAP_4XX))) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); desc.set_writes_memory(); return true; @@ -1179,8 +1307,8 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x3c6: // ICCCI if (!(m_ppc.m_cap & PPCCAP_4XX)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -1189,9 +1317,9 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x3e6: // ICREAD if (!(m_ppc.m_cap & PPCCAP_4XX)) return false; - GPR_USED_OR_ZERO(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RT(op)); + desc.set_gpr_used_or_zero(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RT(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -1199,7 +1327,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x143: // MFDCR if (!(m_ppc.m_cap & PPCCAP_4XX)) return false; - GPR_MODIFIED(desc, G_RD(op)); + desc.set_gpr_modified(G_RD(op)); desc.set_can_cause_exception(); desc.set_privileged(); return true; @@ -1207,7 +1335,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x1c3: // MTDCR if (!(m_ppc.m_cap & PPCCAP_4XX)) return false; - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RS(op)); desc.set_can_cause_exception(); desc.set_can_expose_external_int(); desc.set_privileged(); @@ -1216,7 +1344,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x083: // WRTEE if (!(m_ppc.m_cap & PPCCAP_4XX)) return false; - GPR_USED(desc, G_RS(op)); + desc.set_gpr_used(G_RS(op)); desc.set_can_expose_external_int(); return true; @@ -1243,13 +1371,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; } - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x6b: // MUL (POWER) @@ -1258,13 +1386,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; } - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x108: // DOZ (POWER) @@ -1273,13 +1401,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; } - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x168: // ABS (POWER) @@ -1289,13 +1417,13 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; } - GPR_USED(desc, G_RA(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RD(op)); - XER_OV_MODIFIED(desc); - XER_SO_MODIFIED(desc); + desc.set_gpr_used(G_RA(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RD(op)); + desc.set_xer_ov_modified(); + desc.set_xer_so_modified(); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; case 0x21d: // MASKIR (POWER) @@ -1304,11 +1432,11 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; } - GPR_USED(desc, G_RS(op)); - GPR_USED(desc, G_RB(op)); - GPR_MODIFIED(desc, G_RA(op)); + desc.set_gpr_used(G_RS(op)); + desc.set_gpr_used(G_RB(op)); + desc.set_gpr_modified(G_RA(op)); if (op & M_RC) - CR_MODIFIED(desc, 0); + desc.set_cr_modified(0); return true; } @@ -1332,59 +1460,59 @@ bool ppc_device::frontend::describe_3b(uint32_t op, opcode_desc &desc, const opc switch (opswitch) { case 0x12: // FDIVSx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); if (is_601_class()) desc.cycles = 17; // 601 else if (is_603_class()) desc.cycles = 18; // 603 else desc.cycles = 17; // ??? - FPSCR_MODIFIED(desc, 4); + desc.set_fpscr_modified(4); return true; case 0x14: // FSUBSx case 0x15: // FADDSx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; case 0x19: // FMULSx - not the same form as FSUB/FADD! - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_REGC(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_REGC(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; case 0x16: // FSQRTSx case 0x18: // FRESx - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; case 0x1c: // FMSUBSx case 0x1d: // FMADDSx case 0x1e: // FNMSUBSx case 0x1f: // FNMADDSx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_USED(desc, G_REGC(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_used(G_REGC(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; } @@ -1411,56 +1539,56 @@ bool ppc_device::frontend::describe_3f(uint32_t op, opcode_desc &desc, const opc switch (opswitch) { case 0x12: // FDIVx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); if (is_601_class()) desc.cycles = 31; // 601 else if (is_603_class()) desc.cycles = 33; // 603 else desc.cycles = 31; // ??? - FPSCR_MODIFIED(desc, 4); + desc.set_fpscr_modified(4); return true; case 0x19: // FMULx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_REGC(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_REGC(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); desc.cycles = 2; // 601/603 - FPSCR_MODIFIED(desc, 4); + desc.set_fpscr_modified(4); return true; case 0x14: // FSUBx case 0x15: // FADDx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; case 0x16: // FSQRTx case 0x1a: // FSQRTEx - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); - FPSCR_MODIFIED(desc, 4); + desc.set_cr_modified(1); + desc.set_fpscr_modified(4); return true; case 0x17: // FSELx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_USED(desc, G_REGC(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_used(G_REGC(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); desc.cycles = 2; // 601/603 return true; @@ -1468,14 +1596,14 @@ bool ppc_device::frontend::describe_3f(uint32_t op, opcode_desc &desc, const opc case 0x1d: // FMADDx case 0x1e: // FNMSUBx case 0x1f: // FNMADDx - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - FPR_USED(desc, G_REGC(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_used(G_REGC(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); desc.cycles = 2; // 601/603 - FPSCR_MODIFIED(desc, 4); + desc.set_fpscr_modified(4); return true; } } @@ -1490,62 +1618,62 @@ bool ppc_device::frontend::describe_3f(uint32_t op, opcode_desc &desc, const opc case 0x000: // FCMPU case 0x020: // FCMPO - FPR_USED(desc, G_RA(op)); - FPR_USED(desc, G_RB(op)); - CR_MODIFIED(desc, G_CRFD(op)); + desc.set_fpr_used(G_RA(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_cr_modified(G_CRFD(op)); return true; case 0x00c: // FRSPx case 0x00e: // FCTIWx case 0x00f: // FCTIWZx - FPSCR_MODIFIED(desc, 4); + desc.set_fpscr_modified(4); [[fallthrough]]; case 0x028: // FNEGx case 0x048: // FMRx case 0x088: // FNABSx case 0x108: // FABSx - FPR_USED(desc, G_RB(op)); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpr_used(G_RB(op)); + desc.set_fpr_modified(G_RD(op)); if (op & M_RC) - CR_MODIFIED(desc, 1); + desc.set_cr_modified(1); return true; case 0x026: // MTFSB1x case 0x046: // MTFSB0x - FPSCR_MODIFIED(desc, G_CRBD(op) / 4); + desc.set_fpscr_modified(G_CRBD(op) / 4); return true; case 0x040: // MCRFS - FPSCR_USED(desc, G_CRFS(op)); - CR_MODIFIED(desc, G_CRFD(op)); + desc.set_fpscr_used(G_CRFS(op)); + desc.set_cr_modified(G_CRFD(op)); return true; case 0x086: // MTFSFIx - FPSCR_MODIFIED(desc, G_CRFD(op)); + desc.set_fpscr_modified(G_CRFD(op)); return true; case 0x247: // MFFSx - FPSCR_USED(desc, 0); - FPSCR_USED(desc, 1); - FPSCR_USED(desc, 2); - FPSCR_USED(desc, 3); - FPSCR_USED(desc, 4); - FPSCR_USED(desc, 5); - FPSCR_USED(desc, 6); - FPSCR_USED(desc, 7); - FPR_MODIFIED(desc, G_RD(op)); + desc.set_fpscr_used(0); + desc.set_fpscr_used(1); + desc.set_fpscr_used(2); + desc.set_fpscr_used(3); + desc.set_fpscr_used(4); + desc.set_fpscr_used(5); + desc.set_fpscr_used(6); + desc.set_fpscr_used(7); + desc.set_fpr_modified(G_RD(op)); return true; case 0x2c7: // MTFSFx - FPR_USED(desc, G_RB(op)); - if (G_CRM(op) & 0x80) FPSCR_MODIFIED(desc, 0); - if (G_CRM(op) & 0x40) FPSCR_MODIFIED(desc, 1); - if (G_CRM(op) & 0x20) FPSCR_MODIFIED(desc, 2); - if (G_CRM(op) & 0x10) FPSCR_MODIFIED(desc, 3); - if (G_CRM(op) & 0x08) FPSCR_MODIFIED(desc, 4); - if (G_CRM(op) & 0x04) FPSCR_MODIFIED(desc, 5); - if (G_CRM(op) & 0x02) FPSCR_MODIFIED(desc, 6); - if (G_CRM(op) & 0x01) FPSCR_MODIFIED(desc, 7); + desc.set_fpr_used(G_RB(op)); + if (G_CRM(op) & 0x80) desc.set_fpscr_modified(0); + if (G_CRM(op) & 0x40) desc.set_fpscr_modified(1); + if (G_CRM(op) & 0x20) desc.set_fpscr_modified(2); + if (G_CRM(op) & 0x10) desc.set_fpscr_modified(3); + if (G_CRM(op) & 0x08) desc.set_fpscr_modified(4); + if (G_CRM(op) & 0x04) desc.set_fpscr_modified(5); + if (G_CRM(op) & 0x02) desc.set_fpscr_modified(6); + if (G_CRM(op) & 0x01) desc.set_fpscr_modified(7); return true; } } diff --git a/src/devices/cpu/powerpc/ppcfe.h b/src/devices/cpu/powerpc/ppcfe.h index b72f9256fb9..c3483db3dd7 100644 --- a/src/devices/cpu/powerpc/ppcfe.h +++ b/src/devices/cpu/powerpc/ppcfe.h @@ -17,6 +17,8 @@ #include "cpu/drcfe.h" #include <bitset> +#include <cassert> +#include <iosfwd> //************************************************************************** @@ -32,6 +34,45 @@ public: u32 cycles; // number of cycles needed to execute + void set_gpr_used(unsigned n) { regin.set(REG_BIT_R0 + n); } + void set_gpr_used_or_zero(unsigned n) { if (n) set_gpr_used(n); } + void set_gpr_modified(unsigned n) { regout.set(REG_BIT_R0 + n); } + + void set_fpr_used(unsigned n) { regin.set(REG_BIT_FR0 + n); } + void set_fpr_modified(unsigned n) { regout.set(REG_BIT_FR0 + n); } + + void set_cr_used(unsigned n) { set_cr_bit_used((n * 4) + 0); set_cr_bit_used((n * 4) + 1); set_cr_bit_used((n * 4) + 2); set_cr_bit_used((n * 4) + 3); } + void set_cr_bit_used(unsigned n) { regin.set(64 + 31 - n); } + void set_cr_modified(unsigned n) { set_cr_bit_modified((n * 4) + 0); set_cr_bit_modified((n * 4) + 1); set_cr_bit_modified((n * 4) + 2); set_cr_bit_modified((n * 4) + 3); } + void set_cr_bit_modified(unsigned n) { regout.set(64 + 31 - n); } + + void set_xer_ca_used() { regin.set(REG_BIT_XER_CA); } + void set_xer_ov_used() { regin.set(REG_BIT_XER_OV); } + void set_xer_so_used() { regin.set(REG_BIT_XER_SO); } + void set_xer_count_used() { regin.set(REG_BIT_XER_COUNT); } + void set_xer_ca_modified() { regout.set(REG_BIT_XER_CA); } + void set_xer_ov_modified() { regout.set(REG_BIT_XER_OV); } + void set_xer_so_modified() { regout.set(REG_BIT_XER_SO); } + void set_xer_count_modified() { regout.set(REG_BIT_XER_COUNT); } + + void set_ctr_used() { regin.set(REG_BIT_CTR); } + void set_lr_used() { regin.set(REG_BIT_LR); } + void set_ctr_modified() { regout.set(REG_BIT_CTR); } + void set_lr_modified() { regout.set(REG_BIT_LR); } + + void set_fpscr_used(unsigned n) { regin.set(REG_BIT_FPSCR0 + n); } + void set_fpscr_modified(unsigned n) { regout.set(REG_BIT_FPSCR0 + n); } + + uint32_t cr_modified() const { return regmask_field<64, 32>(regout); } + uint8_t cr_modified(unsigned n) const { return reg_cr(regout, n); } + uint32_t cr_required() const { return regmask_field<64, 32>(regreq); } + uint8_t cr_required(unsigned n) const { return reg_cr(regreq, n); } + + bool xer_ca_required() const { return regreq[REG_BIT_XER_CA]; } + bool xer_ov_required() const { return regreq[REG_BIT_XER_OV]; } + bool xer_so_required() const { return regreq[REG_BIT_XER_SO]; } + bool xer_count_required() const { return regreq[REG_BIT_XER_COUNT]; } + void set_can_expose_external_int() { m_extra_flags.set(CAN_EXPOSE_EXTERNAL_INT); } void set_privileged() { m_extra_flags.set(PRIVILEGED); } void set_compiler_unmapped() { m_extra_flags.set(COMPILER_UNMAPPED); } @@ -48,6 +89,8 @@ public: void reset(offs_t curpc, bool in_delay_slot) { + static_assert(REG_BIT_COUNT <= 128); + opcode_desc_base::reset(curpc, in_delay_slot); physpc = curpc; @@ -56,9 +99,28 @@ public: m_extra_flags.reset(); } + void log_flags(std::ostream &stream) const; + void log_registers_used(std::ostream &stream) const; + void log_registers_modified(std::ostream &stream) const; + protected: enum { + REG_BIT_R0 = 0, + REG_BIT_FR0 = 32, + REG_BIT_XER_CA = 96, + REG_BIT_XER_OV, + REG_BIT_XER_SO, + REG_BIT_XER_COUNT, + REG_BIT_CTR, + REG_BIT_LR, + REG_BIT_FPSCR0, + + REG_BIT_COUNT = REG_BIT_FPSCR0 + 8 + }; + + enum + { CAN_EXPOSE_EXTERNAL_INT = 0, PRIVILEGED, COMPILER_UNMAPPED, @@ -69,27 +131,24 @@ protected: EXTRA_FLAG_COUNT }; + // TODO: uncomment constexpr when GCC/GNU libstdc++ catch up + static /*constexpr*/ bool reg_cr_bit(const regmask &r, unsigned n) + { + return r[64 + 31 - n]; + } + static /*constexpr*/ uint8_t reg_cr(const regmask &r, unsigned n) + { + return uint8_t(((r << ((4 * n) + 32)) >> (128 - 4)).to_ulong()); + } + + static void log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist); + std::bitset<EXTRA_FLAG_COUNT> m_extra_flags; }; class ppc_device::frontend : public drc_frontend_base<opcode_desc> { public: - // TODO: uncomment constexpr when GCC/GNU libstdc++ catch up - static constexpr bool REGFLAG_R(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_R0 + n]; } - static constexpr bool REGFLAG_RZ(const opcode_desc::regmask &r, unsigned n) { return n && REGFLAG_R(r, n); } - static constexpr bool REGFLAG_FR(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_FR0 + n]; } - static /*constexpr*/ uint32_t REGFLAG_CR(const opcode_desc::regmask &r) { return uint32_t(((r << 32) >> (128 - 32)).to_ulong()); } - static /*constexpr*/ uint8_t REGFLAG_CR(const opcode_desc::regmask &r, unsigned n) { return uint8_t(((r << ((4 * n) + 32)) >> (128 - 4)).to_ulong()); } - static constexpr bool REGFLAG_CR_BIT(const opcode_desc::regmask &r, unsigned n) { return r[64 + 31 - n]; } - static constexpr bool REGFLAG_XER_CA(const opcode_desc::regmask &r) { return r[REG_BIT_XER_CA]; } - static constexpr bool REGFLAG_XER_OV(const opcode_desc::regmask &r) { return r[REG_BIT_XER_OV]; } - static constexpr bool REGFLAG_XER_SO(const opcode_desc::regmask &r) { return r[REG_BIT_XER_SO]; } - static constexpr bool REGFLAG_XER_COUNT(const opcode_desc::regmask &r) { return r[REG_BIT_XER_COUNT]; } - static constexpr bool REGFLAG_CTR(const opcode_desc::regmask &r) { return r[REG_BIT_CTR]; } - static constexpr bool REGFLAG_LR(const opcode_desc::regmask &r) { return r[REG_BIT_LR]; } - static constexpr bool REGFLAG_FPSCR(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_FPSCR0 + n]; } - // construction/destruction frontend(ppc_device &ppc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); ~frontend(); @@ -97,23 +156,10 @@ public: opcode_desc const *describe_code(offs_t startpc); protected: - enum - { - REG_BIT_R0 = 0, - REG_BIT_FR0 = 32, - REG_BIT_XER_CA = 96, - REG_BIT_XER_OV, - REG_BIT_XER_SO, - REG_BIT_XER_COUNT, - REG_BIT_CTR, - REG_BIT_LR, - REG_BIT_FPSCR0 - }; - bool describe(opcode_desc &desc, const opcode_desc *prev); // inlines - uint32_t compute_spr(uint32_t spr) const { return ((spr >> 5) | (spr << 5)) & 0x3ff; } + static constexpr uint32_t compute_spr(uint32_t spr) { return ((spr >> 5) | (spr << 5)) & 0x3ff; } bool is_403_class() const { return (m_ppc.m_flavor == ppc_device::PPC_MODEL_403GA || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GB || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GC || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GCX || m_ppc.m_flavor == ppc_device::PPC_MODEL_405GP); } bool is_601_class() const { return (m_ppc.m_flavor == ppc_device::PPC_MODEL_601); } bool is_602_class() const { return (m_ppc.m_flavor == ppc_device::PPC_MODEL_602); } diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp index c507410d759..72945b2e364 100644 --- a/src/devices/cpu/sh/sh.cpp +++ b/src/devices/cpu/sh/sh.cpp @@ -11,6 +11,10 @@ #include "emuopts.h" +#include "util/vecstream.h" + +#include <locale> + sh_common_execution::sh_common_execution(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal) : cpu_device(mconfig, type, tag, owner, clock) @@ -2029,59 +2033,6 @@ void sh_common_execution::save_fast_iregs(drcuml_block &block) /*------------------------------------------------- - log_desc_flags_to_string - generate a string - representing the instruction description - flags --------------------------------------------------*/ - -const char *sh_common_execution::log_desc_flags_to_string(const opcode_desc &desc) -{ - static char tempbuf[30]; - char *dest = tempbuf; - - /* branches */ - if (desc.is_unconditional_branch()) - *dest++ = 'U'; - else if (desc.is_conditional_branch()) - *dest++ = 'C'; - else - *dest++ = '.'; - - /* intrablock branches */ - *dest++ = desc.intrablock_branch() ? 'i' : '.'; - - /* branch targets */ - *dest++ = desc.is_branch_target() ? 'B' : '.'; - - /* delay slots */ - *dest++ = desc.in_delay_slot() ? 'D' : '.'; - - /* exceptions */ - if (desc.will_cause_exception()) - *dest++ = 'E'; - else if (desc.can_cause_exception()) - *dest++ = 'e'; - else - *dest++ = '.'; - - /* read/write */ - if (desc.reads_memory()) - *dest++ = 'R'; - else if (desc.writes_memory()) - *dest++ = 'W'; - else - *dest++ = '.'; - - /* TLB validation */ - *dest++ = desc.validate_tlb() ? 'V' : '.'; - - /* redispatch */ - *dest++ = desc.redispatch() ? 'R' : '.'; - return tempbuf; -} - - -/*------------------------------------------------- log_register_list - log a list of GPR registers -------------------------------------------------*/ @@ -2156,6 +2107,10 @@ void sh_common_execution::log_register_list(const char *string, const std::bitse void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int indent) { + sh_disassembler sh2d(false); + util::ovectorstream buffer; + buffer.imbue(std::locale::classic()); + /* open the file, creating it if necessary */ if (indent == 0) m_drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); @@ -2163,22 +2118,21 @@ void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int inden /* output each descriptor */ for ( ; desclist != nullptr; desclist = desclist->next()) { - std::ostringstream stream; + buffer.clear(); + buffer.seekp(0); + desclist->log_flags(buffer); + buffer.put('\0'); + m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: ", desclist->pc, desclist->physpc, desclist->targetpc, &buffer.vec()[0]); /* disassemle the current instruction and output it to the log */ - if (m_drcuml->logging() || m_drcuml->logging_native()) - { - if (desclist->virtual_noop()) - stream << "<virtual nop>"; - else - { - sh_disassembler sh2d(false); - sh2d.dasm_one(stream, desclist->pc, desclist->opptr); - } - } + buffer.clear(); + buffer.seekp(0); + if (desclist->virtual_noop()) + buffer << "<virtual nop>"; else - stream << "???"; - m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(*desclist), stream.str()); + sh2d.dasm_one(buffer, desclist->pc, desclist->opptr); + buffer.put('\0'); + m_drcuml->log_printf("%-36s", &buffer.vec()[0]); /* output register states */ log_register_list("use", desclist->regin, nullptr); diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h index 3d726db11bd..c06fbeddf10 100644 --- a/src/devices/cpu/sh/sh.h +++ b/src/devices/cpu/sh/sh.h @@ -443,7 +443,6 @@ public: void alloc_handle(uml::code_handle *&handleptr, const char *name); void load_fast_iregs(drcuml_block &block); void save_fast_iregs(drcuml_block &block); - const char *log_desc_flags_to_string(const opcode_desc &flags); void log_register_list(const char *string, const std::bitset<32> ®list, const std::bitset<32> *regnostarlist); void log_opcode_desc(const opcode_desc *desclist, int indent); void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op); diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp index f62ecf110fb..0716231aef7 100644 --- a/src/devices/cpu/sh/sh_fe.cpp +++ b/src/devices/cpu/sh/sh_fe.cpp @@ -14,6 +14,56 @@ #include "cpu/drcfe.ipp" + +/*------------------------------------------------- + log_flags - log the instruction description to + a stream +-------------------------------------------------*/ + +void sh_common_execution::opcode_desc::log_flags(std::ostream &stream) const +{ + // branches + if (is_unconditional_branch()) + stream << 'U'; + else if (is_conditional_branch()) + stream << 'C'; + else + stream << '.'; + + // intrablock branches + stream << (intrablock_branch() ? 'i' : '.'); + + // branch targets + stream << (is_branch_target() ? 'B' : '.'); + + // delay slots + stream << (in_delay_slot() ? 'D' : '.'); + + // exceptions + if (will_cause_exception()) + stream << 'E'; + else if (can_cause_exception()) + stream << 'e'; + else + stream << '.'; + + // read/write + if (reads_memory()) + stream << (writes_memory() ? '+' : 'R'); + else if (writes_memory()) + stream << 'W'; + else + stream << '.'; + + // TLB validation + stream << (validate_tlb() ? 'V' : '.'); + + // redispatch + stream << (redispatch() ? 'R' : '.'); +} + + + /*************************************************************************** INSTRUCTION PARSERS ***************************************************************************/ diff --git a/src/devices/cpu/sh/sh_fe.h b/src/devices/cpu/sh/sh_fe.h index 26439f8af8d..ba63138e3eb 100644 --- a/src/devices/cpu/sh/sh_fe.h +++ b/src/devices/cpu/sh/sh_fe.h @@ -16,6 +16,9 @@ #include "cpu/drcfe.h" +#include <cassert> +#include <iosfwd> + class sh_common_execution::opcode_desc : public opcode_desc_base<opcode_desc, 32> { @@ -83,6 +86,8 @@ public: m_can_expose_external_int = false; } + void log_flags(std::ostream &stream) const; + private: bool m_reads_memory; bool m_writes_memory; diff --git a/src/lib/util/client_ws.hpp b/src/lib/util/client_ws.hpp index 04af5026014..01540907843 100644 --- a/src/lib/util/client_ws.hpp +++ b/src/lib/util/client_ws.hpp @@ -99,7 +99,7 @@ namespace webpp { std::list<SendData> send_queue; void send_from_queue() { - strand.post([this]() { + asio::post(strand, [this]() { asio::async_write(*socket, send_queue.begin()->send_stream->streambuf, strand.wrap([this](const std::error_code& ec, size_t /*bytes_transferred*/) { auto send_queued=send_queue.begin(); @@ -175,7 +175,7 @@ namespace webpp { } if(io_context->stopped()) - io_context->reset(); + io_context->restart(); if(!resolver) resolver= std::make_unique<asio::ip::tcp::resolver>(*io_context); @@ -237,7 +237,7 @@ namespace webpp { send_stream->put(message_stream->get()^mask[c%4]); } - connection->strand.post([this, send_stream, callback]() { + asio::post(connection->strand, [this, send_stream, callback]() { connection->send_queue.emplace_back(send_stream, callback); if(connection->send_queue.size()==1) connection->send_from_queue(); @@ -516,15 +516,13 @@ namespace webpp { protected: void connect() override { - asio::ip::tcp::resolver::query query(host, std::to_string(port)); - - resolver->async_resolve(query, [this] - (const std::error_code &ec, asio::ip::tcp::resolver::iterator it){ + resolver->async_resolve(host, std::to_string(port), [this] + (const std::error_code &ec, asio::ip::tcp::resolver::results_type results){ if(!ec) { connection=std::shared_ptr<Connection>(new Connection(*io_context, new WS(*io_context))); - asio::async_connect(*connection->socket, it, [this] - (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/){ + asio::async_connect(*connection->socket, results, [this] + (const std::error_code &ec, const asio::ip::tcp::endpoint &/*endpoint*/){ if(!ec) { asio::ip::tcp::no_delay option(true); connection->socket->set_option(option); diff --git a/src/lib/util/server_ws_impl.hpp b/src/lib/util/server_ws_impl.hpp index c1ba9f1a392..4f7468232c3 100644 --- a/src/lib/util/server_ws_impl.hpp +++ b/src/lib/util/server_ws_impl.hpp @@ -96,7 +96,7 @@ namespace webpp { std::list<SendData> send_queue; void send_from_queue(const std::shared_ptr<Connection> &connection) { - strand.post([this, connection]() { + asio::post(strand, [this, connection]() { asio::async_write(*socket, send_queue.begin()->header_stream->streambuf, strand.wrap([this, connection](const std::error_code& ec, size_t /*bytes_transferred*/) { if(!ec) { @@ -219,11 +219,11 @@ namespace webpp { io_context=std::make_shared<asio::io_context>(); if(io_context->stopped()) - io_context->reset(); + io_context->restart(); asio::ip::tcp::endpoint endpoint; if(config.address.size()>0) - endpoint=asio::ip::tcp::endpoint(asio::ip::address::from_string(config.address), config.port); + endpoint=asio::ip::tcp::endpoint(asio::ip::make_address(config.address), config.port); else endpoint=asio::ip::tcp::endpoint(asio::ip::tcp::v4(), config.port); @@ -283,7 +283,7 @@ namespace webpp { else header_stream->put(static_cast<unsigned char>(length)); - connection->strand.post([connection, header_stream, message_stream, callback]() { + asio::post(connection->strand, [connection, header_stream, message_stream, callback]() { connection->send_queue.emplace_back(header_stream, message_stream, callback); if(connection->send_queue.size()==1) connection->send_from_queue(connection); @@ -653,12 +653,12 @@ namespace webpp { void timer_idle_init(const std::shared_ptr<Connection> &connection) { if(config.timeout_idle>0) { connection->timer_idle= std::make_unique<asio::system_timer>(connection->socket->get_executor()); - connection->timer_idle->expires_from_now(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle))); + connection->timer_idle->expires_after(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle))); timer_idle_expired_function(connection); } } void timer_idle_reset(const std::shared_ptr<Connection> &connection) const { - if(config.timeout_idle>0 && connection->timer_idle->expires_from_now(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle)))>0) + if(config.timeout_idle>0 && connection->timer_idle->expires_after(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle)))>0) timer_idle_expired_function(connection); } void timer_idle_cancel(const std::shared_ptr<Connection> &connection) const { diff --git a/src/mame/capcom/cps2comm.cpp b/src/mame/capcom/cps2comm.cpp index 95701ef264d..2dac7035b1c 100644 --- a/src/mame/capcom/cps2comm.cpp +++ b/src/mame/capcom/cps2comm.cpp @@ -173,7 +173,8 @@ public: void stop() { - m_ioctx.post( + asio::post( + m_ioctx, [this] () { m_stopping = true; @@ -191,7 +192,8 @@ public: void set_routing(u8 val) { - m_ioctx.post( + asio::post( + m_ioctx, [this, val] () { if (BIT(val, 0, 2) == 0U) @@ -216,7 +218,8 @@ public: void send_in(u8 data) { - m_ioctx.post( + asio::post( + m_ioctx, [this, data] () { if (m_in_connected) @@ -231,7 +234,8 @@ public: void send_out(u8 data) { - m_ioctx.post( + asio::post( + m_ioctx, [this, data] () { if (m_out_sock.is_open()) diff --git a/src/mame/nakajima/nakajies.cpp b/src/mame/nakajima/nakajies.cpp index 4506c368d4b..3fc10647388 100644 --- a/src/mame/nakajima/nakajies.cpp +++ b/src/mame/nakajima/nakajies.cpp @@ -302,8 +302,7 @@ public: , m_rtc(*this, "rtc") , m_view{ {*this, "view_0"}, {*this, "view_1"}, {*this, "view_2"}, {*this, "view_3"}, - {*this, "view_4"}, {*this, "view_5"}, {*this, "view_6"}, {*this, "view_7"} - } + {*this, "view_4"}, {*this, "view_5"}, {*this, "view_6"}, {*this, "view_7"} } , m_port_row(*this, "ROW%u", 0U) , m_port_debug(*this, "debug") , m_rombank(*this, "rombank%u", 0U) @@ -312,11 +311,11 @@ public: { } - void nakajies210(machine_config &config); - void nakajies220(machine_config &config); - void nakajies220_256(machine_config &config); - void nakajies250(machine_config &config); - void dator3k(machine_config &config); + void nakajies210(machine_config &config) ATTR_COLD; + void nakajies220(machine_config &config) ATTR_COLD; + void nakajies220_256(machine_config &config) ATTR_COLD; + void nakajies250(machine_config &config) ATTR_COLD; + void dator3k(machine_config &config) ATTR_COLD; DECLARE_INPUT_CHANGED_MEMBER(trigger_irq); @@ -621,16 +620,14 @@ void nakajies_state::machine_reset() m_lcd_memory_start = 0; m_matrix = 0; - for (int i = 0; i < 8; i++) - { - m_view[i].select(0); - } + for (auto &view : m_view) + view.select(0); - for (int i = 0; i < 8; i++) - { - m_rombank[i]->set_entry(0x0f); - m_rambank[i]->set_entry(0x0f); - } + for (auto &bank : m_rombank) + bank->set_entry(0x0f); + + for (auto &bank : m_rambank) + bank->set_entry(0x0f); } u32 nakajies_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -826,11 +823,11 @@ ROM_END } // anonymous namespace -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 199?, wales210, 0, 0, nakajies210, nakajies, nakajies_state, empty_init, "Walther", "ES-210", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // German, 128KB RAM -COMP( 199?, dator3k, wales210, 0, dator3k, nakajies, nakajies_state, empty_init, "Dator", "Dator 3000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Spanish, 128KB RAM -COMP( 199?, es210_es, wales210, 0, nakajies210, nakajies, nakajies_state, empty_init, "Nakajima", "ES-210 (Spain)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Spanish, 128KB RAM -COMP( 199?, drwrt100, wales210, 0, nakajies220, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter T100", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 128KB RAM +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 199?, wales210, 0, 0, nakajies210, nakajies, nakajies_state, empty_init, "Walther", "ES-210", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // German, 128KB RAM +COMP( 199?, dator3k, wales210, 0, dator3k, nakajies, nakajies_state, empty_init, "Dator", "Dator 3000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Spanish, 128KB RAM +COMP( 199?, es210_es, wales210, 0, nakajies210, nakajies, nakajies_state, empty_init, "Nakajima", "ES-210 (Spain)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Spanish, 128KB RAM +COMP( 199?, drwrt100, wales210, 0, nakajies220, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter T100", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 128KB RAM COMP( 1996, drwrt400, wales210, 0, nakajies220_256, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter T400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 256KB RAM, also found a machine with 160KB RAM -COMP( 199?, drwrt450, wales210, 0, nakajies220, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter 450", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 128KB RAM -COMP( 199?, drwrt200, wales210, 0, nakajies250, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter T200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 256KB? RAM +COMP( 199?, drwrt450, wales210, 0, nakajies220, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter 450", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 128KB RAM +COMP( 199?, drwrt200, wales210, 0, nakajies250, nakajies, nakajies_state, empty_init, "NTS", "DreamWriter T200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // English, 256KB? RAM diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index ded12f49f09..b479313119b 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -51,7 +51,7 @@ using util::BIT; #include "cpu/dsp563xx/dsp563xxd.h" #include "cpu/dspp/dsppdasm.h" #include "cpu/e0c6200/e0c6200d.h" -#include "cpu/e132xs/32xsdasm.h" +#include "cpu/e132xs/e1dasm.h" #include "cpu/es5510/es5510d.h" #include "cpu/esrip/esripdsm.h" #include "cpu/f2mc16/f2mc16d.h" @@ -348,16 +348,6 @@ struct z8000_unidasm_t : z8000_disassembler::config } z8000_unidasm; // Configuration missing -struct hyperstone_unidasm_t : hyperstone_disassembler::config -{ - bool h; - hyperstone_unidasm_t() { h = false; } - virtual ~hyperstone_unidasm_t() = default; - - virtual bool get_h() const { return h; } -} hyperstone_unidasm; - -// Configuration missing struct nec_unidasm_t : nec_disassembler::config { int mode; @@ -491,7 +481,7 @@ static const dasm_table_entry dasm_table[] = { "hp_09825_67907", be, -1, []() -> util::disasm_interface * { return new hp_09825_67907_disassembler; } }, { "hpc16083", le, 0, []() -> util::disasm_interface * { return new hpc16083_disassembler; } }, { "hpc16164", le, 0, []() -> util::disasm_interface * { return new hpc16164_disassembler; } }, - { "hyperstone", be, 0, []() -> util::disasm_interface * { return new hyperstone_disassembler(&hyperstone_unidasm); } }, + { "hyperstone", be, 0, []() -> util::disasm_interface * { return new hyperstone_disassembler(nullptr); } }, { "ht1130", le, 0, []() -> util::disasm_interface * { return new ht1130_disassembler; } }, { "i4004", le, 0, []() -> util::disasm_interface * { return new i4004_disassembler; } }, { "i4040", le, 0, []() -> util::disasm_interface * { return new i4040_disassembler; } }, |
