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; }