From 3a455f75a53597594dcddb87b65346aada870527 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 31 May 2015 00:25:13 +0200 Subject: [PATCH] Netlist now uses the same approach as delegate.h to derive member function pointers. If the platform doesn't support this approach, virtual function calls will be used. In addition, this commit contains modifications for standalone compile. (nw) --- src/emu/machine/netlist.c | 2 +- src/emu/netlist/analog/nld_ms_direct.h | 8 +- src/emu/netlist/analog/nld_ms_direct1.h | 2 +- src/emu/netlist/analog/nld_ms_direct2.h | 2 +- src/emu/netlist/analog/nld_ms_sor.h | 2 +- src/emu/netlist/analog/nld_ms_sor_mat.h | 4 +- src/emu/netlist/analog/nld_solver.c | 14 +-- src/emu/netlist/analog/nld_solver.h | 2 +- src/emu/netlist/analog/nld_twoterm.c | 2 + src/emu/netlist/devices/nld_system.h | 18 ++-- src/emu/netlist/nl_base.c | 21 +++-- src/emu/netlist/nl_base.h | 26 ++---- src/emu/netlist/nl_config.h | 62 +++++++++---- src/emu/netlist/nl_setup.c | 14 +-- src/emu/netlist/nl_setup.h | 8 +- src/emu/netlist/nl_time.h | 48 +++++----- src/emu/netlist/nl_util.h | 1 + src/emu/netlist/plib/palloc.h | 14 ++- src/emu/netlist/plib/pconfig.h | 116 +++++++++++++++++++++--- src/emu/netlist/plib/pparser.c | 1 + src/emu/netlist/plib/pstate.h | 1 + src/emu/netlist/plib/pstring.c | 2 +- src/emu/netlist/plib/pstring.h | 2 + src/emu/netlist/tools/nl_convert.h | 3 +- src/tools/nltool.c | 17 +++- 25 files changed, 266 insertions(+), 126 deletions(-) diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 125f34c9f33..794eaa28454 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -294,7 +294,7 @@ void netlist_mame_device_t::device_start() //printf("clock is %d\n", clock()); m_netlist = global_alloc_clear(netlist_mame_t(*this)); - m_setup = global_alloc_clear(netlist_setup_t(*m_netlist)); + m_setup = global_alloc_clear(netlist_setup_t(m_netlist)); netlist().init_object(*m_netlist, "netlist"); m_setup->init(); diff --git a/src/emu/netlist/analog/nld_ms_direct.h b/src/emu/netlist/analog/nld_ms_direct.h index b5021e1c9f6..92d6d7b5fe4 100644 --- a/src/emu/netlist/analog/nld_ms_direct.h +++ b/src/emu/netlist/analog/nld_ms_direct.h @@ -15,8 +15,8 @@ class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t { public: - netlist_matrix_solver_direct_t(const netlist_solver_parameters_t ¶ms, const int size); - netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t ¶ms, const int size); + netlist_matrix_solver_direct_t(const netlist_solver_parameters_t *params, const int size); + netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t *params, const int size); virtual ~netlist_matrix_solver_direct_t(); @@ -417,7 +417,7 @@ ATTR_HOT inline int netlist_matrix_solver_direct_t::vsolve_non_ } template -netlist_matrix_solver_direct_t::netlist_matrix_solver_direct_t(const netlist_solver_parameters_t ¶ms, const int size) +netlist_matrix_solver_direct_t::netlist_matrix_solver_direct_t(const netlist_solver_parameters_t *params, const int size) : netlist_matrix_solver_t(GAUSSIAN_ELIMINATION, params) , m_dim(size) , m_lp_fact(0) @@ -434,7 +434,7 @@ netlist_matrix_solver_direct_t::netlist_matrix_solver_direct_t( } template -netlist_matrix_solver_direct_t::netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t ¶ms, const int size) +netlist_matrix_solver_direct_t::netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t *params, const int size) : netlist_matrix_solver_t(type, params) , m_dim(size) , m_lp_fact(0) diff --git a/src/emu/netlist/analog/nld_ms_direct1.h b/src/emu/netlist/analog/nld_ms_direct1.h index 6b901417a0a..991da037591 100644 --- a/src/emu/netlist/analog/nld_ms_direct1.h +++ b/src/emu/netlist/analog/nld_ms_direct1.h @@ -15,7 +15,7 @@ class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1 { public: - netlist_matrix_solver_direct1_t(const netlist_solver_parameters_t ¶ms) + netlist_matrix_solver_direct1_t(const netlist_solver_parameters_t *params) : netlist_matrix_solver_direct_t<1, 1>(params, 1) {} ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson); diff --git a/src/emu/netlist/analog/nld_ms_direct2.h b/src/emu/netlist/analog/nld_ms_direct2.h index 2aa8d749aaa..69df8085c57 100644 --- a/src/emu/netlist/analog/nld_ms_direct2.h +++ b/src/emu/netlist/analog/nld_ms_direct2.h @@ -17,7 +17,7 @@ class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2 { public: - netlist_matrix_solver_direct2_t(const netlist_solver_parameters_t ¶ms) + netlist_matrix_solver_direct2_t(const netlist_solver_parameters_t *params) : netlist_matrix_solver_direct_t<2, 2>(params, 2) {} ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson); diff --git a/src/emu/netlist/analog/nld_ms_sor.h b/src/emu/netlist/analog/nld_ms_sor.h index 25799dbb1e6..810e88799ac 100644 --- a/src/emu/netlist/analog/nld_ms_sor.h +++ b/src/emu/netlist/analog/nld_ms_sor.h @@ -20,7 +20,7 @@ class netlist_matrix_solver_SOR_t: public netlist_matrix_solver_direct_t(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size) , m_lp_fact(0) , m_gs_fail(0) diff --git a/src/emu/netlist/analog/nld_ms_sor_mat.h b/src/emu/netlist/analog/nld_ms_sor_mat.h index 9c5a29382f1..adc65170a87 100644 --- a/src/emu/netlist/analog/nld_ms_sor_mat.h +++ b/src/emu/netlist/analog/nld_ms_sor_mat.h @@ -20,9 +20,9 @@ class netlist_matrix_solver_SOR_mat_t: public netlist_matrix_solver_direct_t(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size) - , m_omega(params.m_sor) + , m_omega(params->m_sor) , m_lp_fact(0) , m_gs_fail(0) , m_gs_total(0) diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index 4f4ea19c79c..41a13792490 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -64,11 +64,11 @@ ATTR_COLD void terms_t::set_pointers() // netlist_matrix_solver // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t ¶ms) +ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t *params) : m_stat_calculations(0), m_stat_newton_raphson(0), m_stat_vsolver_calls(0), - m_params(params), + m_params(*params), m_cur_ts(0), m_type(type) { @@ -399,9 +399,9 @@ template netlist_matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int gs_threshold, const bool use_specific) { if (use_specific && m_N == 1) - return palloc(netlist_matrix_solver_direct1_t, m_params); + return palloc(netlist_matrix_solver_direct1_t, &m_params); else if (use_specific && m_N == 2) - return palloc(netlist_matrix_solver_direct2_t, m_params); + return palloc(netlist_matrix_solver_direct2_t, &m_params); else { if (size >= gs_threshold) @@ -409,18 +409,18 @@ netlist_matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int if (USE_MATRIX_GS) { typedef netlist_matrix_solver_SOR_mat_t solver_mat; - return palloc(solver_mat, m_params, size); + return palloc(solver_mat, &m_params, size); } else { typedef netlist_matrix_solver_SOR_t solver_GS; - return palloc(solver_GS, m_params, size); + return palloc(solver_GS, &m_params, size); } } else { typedef netlist_matrix_solver_direct_t solver_D; - return palloc(solver_D, m_params, size); + return palloc(solver_D, &m_params, size); } } } diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index 7ab2f4a7733..23c050c11a4 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -99,7 +99,7 @@ public: GAUSS_SEIDEL }; - ATTR_COLD netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t ¶ms); + ATTR_COLD netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t *params); /* ATTR_COLD */ virtual ~netlist_matrix_solver_t(); /* ATTR_COLD */ virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0; diff --git a/src/emu/netlist/analog/nld_twoterm.c b/src/emu/netlist/analog/nld_twoterm.c index 02ec7fa9c29..5c43a500d88 100644 --- a/src/emu/netlist/analog/nld_twoterm.c +++ b/src/emu/netlist/analog/nld_twoterm.c @@ -5,6 +5,8 @@ * */ +#include + #include "nld_twoterm.h" #include "nld_solver.h" diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index f764f0027e6..cefd11c5549 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -261,12 +261,12 @@ private: class nld_base_proxy : public netlist_device_t { public: - ATTR_COLD nld_base_proxy(netlist_logic_t &inout_proxied, netlist_core_terminal_t &proxy_inout) + ATTR_COLD nld_base_proxy(netlist_logic_t *inout_proxied, netlist_core_terminal_t *proxy_inout) : netlist_device_t() { - m_logic_family = inout_proxied.logic_family(); - m_term_proxied = &inout_proxied; - m_proxy_term = &proxy_inout; + m_logic_family = inout_proxied->logic_family(); + m_term_proxied = inout_proxied; + m_proxy_term = proxy_inout; } /* ATTR_COLD */ virtual ~nld_base_proxy() {} @@ -294,8 +294,8 @@ private: class nld_a_to_d_proxy : public nld_base_proxy { public: - ATTR_COLD nld_a_to_d_proxy(netlist_logic_input_t &in_proxied) - : nld_base_proxy(in_proxied, m_I) + ATTR_COLD nld_a_to_d_proxy(netlist_logic_input_t *in_proxied) + : nld_base_proxy(in_proxied, &m_I) { } @@ -336,7 +336,7 @@ private: class nld_base_d_to_a_proxy : public nld_base_proxy { public: - ATTR_COLD nld_base_d_to_a_proxy(netlist_logic_output_t &out_proxied, netlist_core_terminal_t &proxy_out) + ATTR_COLD nld_base_d_to_a_proxy(netlist_logic_output_t *out_proxied, netlist_core_terminal_t *proxy_out) : nld_base_proxy(out_proxied, proxy_out) { } @@ -359,8 +359,8 @@ private: class nld_d_to_a_proxy : public nld_base_d_to_a_proxy { public: - ATTR_COLD nld_d_to_a_proxy(netlist_logic_output_t &out_proxied) - : nld_base_d_to_a_proxy(out_proxied, m_RV.m_P) + ATTR_COLD nld_d_to_a_proxy(netlist_logic_output_t *out_proxied) + : nld_base_d_to_a_proxy(out_proxied, &m_RV.m_P) , m_RV(TWOTERM) , m_last_state(-1) , m_is_timestep(false) diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index b07e462f4f4..e3f2361d337 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -6,6 +6,7 @@ */ #include +#include #include "plib/palloc.h" @@ -51,7 +52,7 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t &proxied) const + virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t *proxied) const { return palloc(nld_d_to_a_proxy , proxied); } @@ -71,7 +72,7 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t &proxied) const + virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t *proxied) const { return palloc(nld_d_to_a_proxy , proxied); } @@ -419,15 +420,15 @@ ATTR_COLD void netlist_core_device_t::init(netlist_base_t &anetlist, const pstri set_logic_family(this->default_logic_family()); init_object(anetlist, name); -#if USE_PMFDELEGATES +#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update; -#if NO_USE_PMFCONVERSION static_update = pFunc; -#else +#elif (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) + void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update; static_update = reinterpret_cast((this->*pFunc)); +#elif (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL) + static_update = pmfp::get_mfp(&netlist_core_device_t::update, this); #endif -#endif - } ATTR_COLD netlist_core_device_t::~netlist_core_device_t() @@ -665,7 +666,7 @@ ATTR_COLD void netlist_net_t::save_register() netlist_object_t::save_register(); } -ATTR_HOT inline void netlist_core_terminal_t::update_dev(const UINT32 mask) +ATTR_HOT /* inline */ void netlist_core_terminal_t::update_dev(const UINT32 mask) { inc_stat(netdev().stat_call_count); if ((state() & mask) != 0) @@ -674,7 +675,7 @@ ATTR_HOT inline void netlist_core_terminal_t::update_dev(const UINT32 mask) } } -ATTR_HOT inline void netlist_net_t::update_devs() +ATTR_HOT /* inline */ void netlist_net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); @@ -1056,7 +1057,7 @@ ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, co // mainclock // ---------------------------------------------------------------------------------------- -ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_logic_net_t &net) +ATTR_HOT /* inline */ void NETLIB_NAME(mainclock)::mc_update(netlist_logic_net_t &net) { net.toggle_new_Q(); net.update_devs(); diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 042843b4dc5..fe70e4677ac 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -170,13 +170,11 @@ class netlist_core_device_t; -#if USE_PMFDELEGATES -#if NO_USE_PMFCONVERSION +#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) typedef void (netlist_core_device_t::*net_update_delegate)(); -#else +#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL)) typedef void (*net_update_delegate)(netlist_core_device_t *); #endif -#endif //============================================================ // MACROS / netlist devices @@ -312,7 +310,7 @@ class netlist_logic_family_desc_t { public: virtual ~netlist_logic_family_desc_t() {} - virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t &proxied) const = 0; + virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t *proxied) const = 0; nl_double m_low_thresh_V; nl_double m_high_thresh_V; @@ -482,7 +480,7 @@ public: } - ATTR_HOT inline void update_dev(const UINT32 mask); + ATTR_HOT /* inline */ void update_dev(const UINT32 mask); protected: /* ATTR_COLD */ virtual void save_register() @@ -1016,12 +1014,11 @@ public: { begin_timing(stat_total_time); inc_stat(stat_update_count); -#if USE_PMFDELEGATES -#if NO_USE_PMFCONVERSION + +#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) (this->*static_update)(); -#else +#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL)) static_update(this); -#endif #else update(); #endif @@ -1059,8 +1056,6 @@ public: ATTR_HOT virtual void step_time(ATTR_UNUSED const nl_double st) { } ATTR_HOT virtual void update_terminals() { } - - #if (NL_KEEP_STATISTICS) /* stats */ osd_ticks_t stat_total_time; @@ -1068,10 +1063,6 @@ public: INT32 stat_call_count; #endif -#if USE_PMFDELEGATES - net_update_delegate static_update; -#endif - protected: ATTR_HOT virtual void update() { } @@ -1083,6 +1074,9 @@ protected: } private: +#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL) + net_update_delegate static_update; +#endif }; diff --git a/src/emu/netlist/nl_config.h b/src/emu/netlist/nl_config.h index c6b5373fb26..b3f0e219d4e 100644 --- a/src/emu/netlist/nl_config.h +++ b/src/emu/netlist/nl_config.h @@ -15,30 +15,55 @@ //============================================================ /* - * The next options needs -Wno-pmf-conversions to compile and gcc - * There is quite some significant speed-up of up to 20% involved. - * NO_USE_PMFCONVERSION is for illustrative purposes only. Using PMFs - * has some overhead in comparison to calling a virtual function. + * The following options determine how object::update is called. + * NL_PMF_TYPE_VIRTUAL + * Use stock virtual call * - * To get a performance increase we need the GCC extension. + * NL_PMF_TYPE_GNUC_PMF + * Use standard pointer to member function syntax * - * Todo: This doesn't work with current (4.8+) mingw 32bit builds. - * Therefore disabled for now for i386 builds. + * NL_PMF_TYPE_GNUC_PMF_CONV + * Use gnu extension and convert the pmf to a function pointer. + * This is not standard compliant and needs + * -Wno-pmf-conversions to compile. * + * NL_PMF_TYPE_INTERNAL + * Use the same approach as MAME for deriving the function pointer. + * This is compiler-dependant as well + * + * Benchmarks for ./nltool -c run -f src/mame/drivers/nl_pong.c -t 10 -n pong_fast + * + * NL_PMF_TYPE_INTERNAL: 215% + * NL_PMF_TYPE_GNUC_PMF: 163% + * NL_PMF_TYPE_GNUC_PMF_CONV: 215% + * NL_PMF_TYPE_VIRTUAL: 213% + * + * The whole exercise was done to avoid virtual calls. In prior versions of + * netlist, the INTERNAL and GNUC_PMF_CONV approach provided significant improvement. + * Since than, ATTR_COLD was removed from functions declared as virtual. + * This may explain that the recent benchmarks show no difference at all. + * + * Disappointing is the GNUC_PMF performance. */ -#ifndef USE_PMFDELEGATES -#if defined(__clang__) || defined(__APPLE__) || (defined(__GNUC__) && defined(__i386__)) - #define USE_PMFDELEGATES (0) - #define NO_USE_PMFCONVERSION (1) -#elif defined(__GNUC__) - #define USE_PMFDELEGATES (0) - #define NO_USE_PMFCONVERSION (0) - #pragma GCC diagnostic ignored "-Wpmf-conversions" -#else - #define USE_PMFDELEGATES (0) - #define NO_USE_PMFCONVERSION (1) +// This will be autodetected +// #define NL_PMF_TYPE 3 + +#define NL_PMF_TYPE_VIRTUAL 0 +#define NL_PMF_TYPE_GNUC_PMF 1 +#define NL_PMF_TYPE_GNUC_PMF_CONV 2 +#define NL_PMF_TYPE_INTERNAL 3 + +#ifndef NL_PMF_TYPE + #if PHAS_PMF_INTERNAL + #define NL_PMF_TYPE NL_PMF_TYPE_INTERNAL + #else + #define NL_PMF_TYPE NL_PMF_TYPE_VIRTUAL + #endif #endif + +#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) +#pragma GCC diagnostic ignored "-Wpmf-conversions" #endif /* @@ -69,7 +94,6 @@ #define NETLIST_GMIN_DEFAULT (1e-9) - //#define nl_double float //#define NL_FCONST(x) (x ## f) diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index 5799a8dddcd..04145bc5ead 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -34,11 +34,11 @@ NETLIST_END() // netlist_setup_t // ---------------------------------------------------------------------------------------- -netlist_setup_t::netlist_setup_t(netlist_base_t &netlist) +netlist_setup_t::netlist_setup_t(netlist_base_t *netlist) : m_netlist(netlist) , m_proxy_cnt(0) { - netlist.set_setup(this); + netlist->set_setup(this); m_factory = palloc(netlist_factory_list_t); } @@ -394,7 +394,7 @@ nld_base_proxy *netlist_setup_t::get_d_a_proxy(netlist_core_terminal_t &out) if (proxy == NULL) { // create a new one ... - nld_base_d_to_a_proxy *new_proxy = out_cast.logic_family()->create_d_a_proxy(out_cast); + nld_base_d_to_a_proxy *new_proxy = out_cast.logic_family()->create_d_a_proxy(&out_cast); pstring x = pstring::sprintf("proxy_da_%s_%d", out.name().cstr(), m_proxy_cnt); m_proxy_cnt++; @@ -425,7 +425,7 @@ void netlist_setup_t::connect_input_output(netlist_core_terminal_t &in, netlist_ if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC)) { netlist_logic_input_t &incast = dynamic_cast(in); - nld_a_to_d_proxy *proxy = palloc(nld_a_to_d_proxy, incast); + nld_a_to_d_proxy *proxy = palloc(nld_a_to_d_proxy, &incast); incast.set_proxy(proxy); pstring x = pstring::sprintf("proxy_ad_%s_%d", in.name().cstr(), m_proxy_cnt); m_proxy_cnt++; @@ -464,7 +464,7 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_c { netlist_logic_input_t &incast = dynamic_cast(inp); NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n")); - nld_a_to_d_proxy *proxy = palloc(nld_a_to_d_proxy, incast); + nld_a_to_d_proxy *proxy = palloc(nld_a_to_d_proxy, &incast); incast.set_proxy(proxy); pstring x = pstring::sprintf("proxy_ad_%s_%d", inp.name().cstr(), m_proxy_cnt); m_proxy_cnt++; @@ -745,13 +745,13 @@ void netlist_setup_t::resolve_inputs() netlist().log("initialize solver ...\n"); - if (m_netlist.solver() == NULL) + if (netlist().solver() == NULL) { if (has_twoterms) netlist().error("No solver found for this net although analog elements are present\n"); } else - m_netlist.solver()->post_start(); + netlist().solver()->post_start(); } diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index df9cebac2ce..f1f117e8fc6 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -107,13 +107,13 @@ public: typedef pnamedlist_t tagmap_terminal_t; typedef plist_t tagmap_link_t; - netlist_setup_t(netlist_base_t &netlist); + netlist_setup_t(netlist_base_t *netlist); ~netlist_setup_t(); void init(); - netlist_base_t &netlist() { return m_netlist; } - const netlist_base_t &netlist() const { return m_netlist; } + netlist_base_t &netlist() { return *m_netlist; } + const netlist_base_t &netlist() const { return *m_netlist; } pstring build_fqn(const pstring &obj_name) const; @@ -159,7 +159,7 @@ protected: private: - netlist_base_t &m_netlist; + netlist_base_t *m_netlist; tagmap_nstring_t m_alias; tagmap_param_t m_params; diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h index 365fd271c19..a6ca27191e2 100644 --- a/src/emu/netlist/nl_time.h +++ b/src/emu/netlist/nl_time.h @@ -31,44 +31,44 @@ public: static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; - ATTR_HOT inline netlist_time() : m_time(0) {} + ATTR_HOT /* inline */ netlist_time() : m_time(0) {} - ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor); - ATTR_HOT friend inline UINT32 operator/(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator!=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ const netlist_time operator-(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ const netlist_time operator+(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ const netlist_time operator*(const netlist_time &left, const UINT32 factor); + ATTR_HOT friend /* inline */ UINT32 operator/(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ bool operator>(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ bool operator<(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ bool operator>=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ bool operator<=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend /* inline */ bool operator!=(const netlist_time &left, const netlist_time &right); - ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } - ATTR_HOT inline const netlist_time &operator=(const double &right) { m_time = (INTERNALTYPE) ( right * (double) RESOLUTION); return *this; } + ATTR_HOT /* inline */ const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } + ATTR_HOT /* inline */ const netlist_time &operator=(const double &right) { m_time = (INTERNALTYPE) ( right * (double) RESOLUTION); return *this; } // issues with ISO C++ standard - //ATTR_HOT inline operator double() const { return as_double(); } + //ATTR_HOT /* inline */ operator double() const { return as_double(); } - ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } + ATTR_HOT /* inline */ const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } - ATTR_HOT inline INTERNALTYPE as_raw() const { return m_time; } - ATTR_HOT inline double as_double() const { return (double) m_time / (double) RESOLUTION; } + ATTR_HOT /* inline */ INTERNALTYPE as_raw() const { return m_time; } + ATTR_HOT /* inline */ double as_double() const { return (double) m_time / (double) RESOLUTION; } // for save states .... - ATTR_HOT inline INTERNALTYPE *get_internaltype_ptr() { return &m_time; } + ATTR_HOT /* inline */ INTERNALTYPE *get_internaltype_ptr() { return &m_time; } - ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } - ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } - ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } - ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } - ATTR_HOT static inline const netlist_time from_double(const double t) { return netlist_time((INTERNALTYPE) ( t * (double) RESOLUTION)); } - ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } + ATTR_HOT static /* inline */ const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } + ATTR_HOT static /* inline */ const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } + ATTR_HOT static /* inline */ const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } + ATTR_HOT static /* inline */ const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } + ATTR_HOT static /* inline */ const netlist_time from_double(const double t) { return netlist_time((INTERNALTYPE) ( t * (double) RESOLUTION)); } + ATTR_HOT static /* inline */ const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } static const netlist_time zero; protected: - ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {} + ATTR_HOT /* inline */ netlist_time(const INTERNALTYPE val) : m_time(val) {} private: INTERNALTYPE m_time; diff --git a/src/emu/netlist/nl_util.h b/src/emu/netlist/nl_util.h index 09a06ce976a..020f8622208 100644 --- a/src/emu/netlist/nl_util.h +++ b/src/emu/netlist/nl_util.h @@ -10,6 +10,7 @@ #include #include +#include #include "plib/pstring.h" #include "plib/plists.h" diff --git a/src/emu/netlist/plib/palloc.h b/src/emu/netlist/plib/palloc.h index e78bbc6e3ab..c5d060196f1 100644 --- a/src/emu/netlist/plib/palloc.h +++ b/src/emu/netlist/plib/palloc.h @@ -40,28 +40,28 @@ inline T *palloc_t() } template -inline T *palloc_t(P1 &p1) +inline T *palloc_t(P1 p1) { void *p = palloc_raw(sizeof(T)); return new (p) T(p1); } template -inline T *palloc_t(P1 &p1, P2 &p2) +inline T *palloc_t(P1 p1, P2 p2) { void *p = palloc_raw(sizeof(T)); return new (p) T(p1, p2); } template -inline T *palloc_t(P1 &p1, P2 &p2, P3 &p3) +inline T *palloc_t(P1 p1, P2 p2, P3 p3) { void *p = palloc_raw(sizeof(T)); return new (p) T(p1, p2, p3); } template -inline T *palloc_t(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) +inline T *palloc_t(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) { void *p = palloc_raw(sizeof(T)); return new (p) T(p1, p2, p3, p4, p5, p6, p7); @@ -87,9 +87,13 @@ inline void pfree_array_t(T *p) delete[] p; } +#if 1 #define palloc(T, ...) palloc_t(__VA_ARGS__) #define pfree(_ptr) pfree_t(_ptr) - +#else +#define palloc(T, ...) new T(__VA_ARGS__) +#define pfree(_ptr) delete(_ptr) +#endif #define palloc_array(T, N) palloc_array_t(N) #define pfree_array(_ptr) pfree_array_t(_ptr) diff --git a/src/emu/netlist/plib/pconfig.h b/src/emu/netlist/plib/pconfig.h index fbbb0d0a4c9..5598906d730 100644 --- a/src/emu/netlist/plib/pconfig.h +++ b/src/emu/netlist/plib/pconfig.h @@ -12,24 +12,56 @@ #define PSTANDALONE (0) #endif -//============================================================ -// Compiling standalone -//============================================================ - -// Compiling without mame ? - -#include -#include - #if !(PSTANDALONE) #include "osdcore.h" #include "eminline.h" -#undef ATTR_COLD -#define ATTR_COLD +#ifndef assert +#define assert(x) do {} while (0) +#endif + +#include "delegate.h" #else #include +#include +#endif + +//============================================================ +// Compiling standalone +//============================================================ + +#if !(PSTANDALONE) + +#undef ATTR_COLD +#define ATTR_COLD + +/* use MAME */ +#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) +#define PHAS_PMF_INTERNAL 1 +#else +#define PHAS_PMF_INTERNAL 0 +#endif + +#else + +/* determine PMF approach */ + +#if defined(__GNUC__) + /* does not work in versions over 4.7.x of 32bit MINGW */ + #if defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) + #define PHAS_PMF_INTERNAL 0 + #elif defined(EMSCRIPTEN) + #define PHAS_PMF_INTERNAL 0 + #elif defined(__arm__) || defined(__ARMEL__) + #define PHAS_PMF_INTERNAL 0 + #else + #define PHAS_PMF_INTERNAL 1 + #endif +#else +#define USE_DELEGATE_TYPE PHAS_PMF_INTERNAL 0 +#endif + /* not supported in GCC prior to 4.4.x */ /* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */ @@ -97,4 +129,66 @@ typedef int64_t INT64; #endif +/* + * The following class was derived from the MAME delegate.h code. + * It derives a pointer to a member function. + */ + +#if (PHAS_PMF_INTERNAL) +class pmfp +{ +public: + // construct from any member function pointer + class generic_class; + typedef void (*generic_function)(); + + #if (PSTANDALONE) + typedef std::size_t FPTR; + #endif + + template + pmfp(_MemberFunctionType mfp) + : m_function(0), m_this_delta(0) + { + *reinterpret_cast<_MemberFunctionType *>(this) = mfp; + } + + // binding helper + template + _FunctionType update_after_bind(_ObjectType *object) + { + return reinterpret_cast<_FunctionType>( + convert_to_generic(reinterpret_cast(object))); + } + template + static _FunctionType get_mfp(_MemberFunctionType mfp, _ObjectType *object) + { + pmfp mfpo(mfp); + return mfpo.update_after_bind<_FunctionType>(object); + } + +private: + // extract the generic function and adjust the object pointer + generic_function convert_to_generic(generic_class * object) const + { + // apply the "this" delta to the object first + generic_class * o_p_delta = reinterpret_cast(reinterpret_cast(object) + m_this_delta); + + // if the low bit of the vtable index is clear, then it is just a raw function pointer + if (!(m_function & 1)) + return reinterpret_cast(m_function); + + // otherwise, it is the byte index into the vtable where the actual function lives + UINT8 *vtable_base = *reinterpret_cast(o_p_delta); + return *reinterpret_cast(vtable_base + m_function - 1); + } + + // actual state + FPTR m_function; // first item can be one of two things: + // if even, it's a pointer to the function + // if odd, it's the byte offset into the vtable + int m_this_delta; // delta to apply to the 'this' pointer +}; +#endif + #endif /* PCONFIG_H_ */ diff --git a/src/emu/netlist/plib/pparser.c b/src/emu/netlist/plib/pparser.c index 95b9260c7cd..6022eef1426 100644 --- a/src/emu/netlist/plib/pparser.c +++ b/src/emu/netlist/plib/pparser.c @@ -6,6 +6,7 @@ */ #include +#include #include "pparser.h" diff --git a/src/emu/netlist/plib/pstate.h b/src/emu/netlist/plib/pstate.h index 73b83e65a00..27e0ea08ebb 100644 --- a/src/emu/netlist/plib/pstate.h +++ b/src/emu/netlist/plib/pstate.h @@ -71,6 +71,7 @@ NETLIST_SAVE_TYPE(INT32, DT_INT); NETLIST_SAVE_TYPE(UINT16, DT_INT16); NETLIST_SAVE_TYPE(INT16, DT_INT16); //NETLIST_SAVE_TYPE(netlist_time::INTERNALTYPE, DT_INT64); +//NETLIST_SAVE_TYPE(std::size_t, DT_INT64); class pstate_manager_t; diff --git a/src/emu/netlist/plib/pstring.c b/src/emu/netlist/plib/pstring.c index 37af773b254..e5f73ffa17b 100644 --- a/src/emu/netlist/plib/pstring.c +++ b/src/emu/netlist/plib/pstring.c @@ -5,12 +5,12 @@ * */ -#include #include #include //FIXME:: pstring should be locale free #include #include +#include #include "pstring.h" #include "palloc.h" diff --git a/src/emu/netlist/plib/pstring.h b/src/emu/netlist/plib/pstring.h index e3054263ed7..44a990c34a3 100644 --- a/src/emu/netlist/plib/pstring.h +++ b/src/emu/netlist/plib/pstring.h @@ -7,6 +7,8 @@ #ifndef _PSTRING_H_ #define _PSTRING_H_ +#include + #include "pconfig.h" // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/tools/nl_convert.h b/src/emu/netlist/tools/nl_convert.h index 9ecbb186f1f..db5fcbf4f68 100644 --- a/src/emu/netlist/tools/nl_convert.h +++ b/src/emu/netlist/tools/nl_convert.h @@ -11,6 +11,7 @@ #define NL_CONVERT_H_ #include +#include #include "plib/pstring.h" #include "plib/plists.h" @@ -462,7 +463,7 @@ public: void verror(pstring msg, int line_num, pstring line) { - m_convert.out("abc"); + m_convert.out("%s (line %d): %s\n", msg.cstr(), line_num, line.cstr()); } diff --git a/src/tools/nltool.c b/src/tools/nltool.c index cd0cc5e62ad..f2cc7e0734c 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -183,7 +183,7 @@ public: void init() { - m_setup = palloc(netlist_setup_t, *this); + m_setup = palloc(netlist_setup_t, this); this->init_object(*this, "netlist"); m_setup->init(); } @@ -349,16 +349,29 @@ static void listdevices() main - primary entry point -------------------------------------------------*/ +#if (!PSTANDALONE) #include "corealloc.h" +#endif + +static const char *pmf_verbose[] = +{ + "NL_PMF_TYPE_VIRTUAL", + "NL_PMF_TYPE_GNUC_PMF", + "NL_PMF_TYPE_GNUC_PMF_CONV", + "NL_PMF_TYPE_INTERNAL" +}; int main(int argc, char *argv[]) { +#if (!PSTANDALONE) track_memory(true); { +#endif tool_options_t opts; int ret; fprintf(stderr, "%s", "WARNING: This is Work In Progress! - It may fail anytime\n"); + fprintf(stderr, "Update dispatching using method %s\n", pmf_verbose[NL_PMF_TYPE]); if ((ret = opts.parse(argc, argv)) != argc) { fprintf(stderr, "Error parsing %s\n", argv[ret]); @@ -396,7 +409,9 @@ int main(int argc, char *argv[]) usage(opts); return 1; } +#if (!PSTANDALONE) } dump_unfreed_mem(); +#endif return 0; }