mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
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)
This commit is contained in:
parent
2f13be3ec5
commit
3a455f75a5
@ -294,7 +294,7 @@ void netlist_mame_device_t::device_start()
|
|||||||
//printf("clock is %d\n", clock());
|
//printf("clock is %d\n", clock());
|
||||||
|
|
||||||
m_netlist = global_alloc_clear(netlist_mame_t(*this));
|
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");
|
netlist().init_object(*m_netlist, "netlist");
|
||||||
m_setup->init();
|
m_setup->init();
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
netlist_matrix_solver_direct_t(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 ¶ms, 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();
|
virtual ~netlist_matrix_solver_direct_t();
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned m_N, unsigned _storage_N>
|
template <unsigned m_N, unsigned _storage_N>
|
||||||
netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const netlist_solver_parameters_t ¶ms, const int size)
|
netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const netlist_solver_parameters_t *params, const int size)
|
||||||
: netlist_matrix_solver_t(GAUSSIAN_ELIMINATION, params)
|
: netlist_matrix_solver_t(GAUSSIAN_ELIMINATION, params)
|
||||||
, m_dim(size)
|
, m_dim(size)
|
||||||
, m_lp_fact(0)
|
, m_lp_fact(0)
|
||||||
@ -434,7 +434,7 @@ netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned m_N, unsigned _storage_N>
|
template <unsigned m_N, unsigned _storage_N>
|
||||||
netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t ¶ms, const int size)
|
netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t *params, const int size)
|
||||||
: netlist_matrix_solver_t(type, params)
|
: netlist_matrix_solver_t(type, params)
|
||||||
, m_dim(size)
|
, m_dim(size)
|
||||||
, m_lp_fact(0)
|
, m_lp_fact(0)
|
||||||
|
@ -15,7 +15,7 @@ class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1
|
|||||||
{
|
{
|
||||||
public:
|
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)
|
: netlist_matrix_solver_direct_t<1, 1>(params, 1)
|
||||||
{}
|
{}
|
||||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||||
|
@ -17,7 +17,7 @@ class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2
|
|||||||
{
|
{
|
||||||
public:
|
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)
|
: netlist_matrix_solver_direct_t<2, 2>(params, 2)
|
||||||
{}
|
{}
|
||||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||||
|
@ -20,7 +20,7 @@ class netlist_matrix_solver_SOR_t: public netlist_matrix_solver_direct_t<m_N, _s
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
netlist_matrix_solver_SOR_t(const netlist_solver_parameters_t ¶ms, int size)
|
netlist_matrix_solver_SOR_t(const netlist_solver_parameters_t *params, int size)
|
||||||
: netlist_matrix_solver_direct_t<m_N, _storage_N>(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size)
|
: netlist_matrix_solver_direct_t<m_N, _storage_N>(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size)
|
||||||
, m_lp_fact(0)
|
, m_lp_fact(0)
|
||||||
, m_gs_fail(0)
|
, m_gs_fail(0)
|
||||||
|
@ -20,9 +20,9 @@ class netlist_matrix_solver_SOR_mat_t: public netlist_matrix_solver_direct_t<m_N
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
netlist_matrix_solver_SOR_mat_t(const netlist_solver_parameters_t ¶ms, int size)
|
netlist_matrix_solver_SOR_mat_t(const netlist_solver_parameters_t *params, int size)
|
||||||
: netlist_matrix_solver_direct_t<m_N, _storage_N>(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size)
|
: netlist_matrix_solver_direct_t<m_N, _storage_N>(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size)
|
||||||
, m_omega(params.m_sor)
|
, m_omega(params->m_sor)
|
||||||
, m_lp_fact(0)
|
, m_lp_fact(0)
|
||||||
, m_gs_fail(0)
|
, m_gs_fail(0)
|
||||||
, m_gs_total(0)
|
, m_gs_total(0)
|
||||||
|
@ -64,11 +64,11 @@ ATTR_COLD void terms_t::set_pointers()
|
|||||||
// netlist_matrix_solver
|
// 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_calculations(0),
|
||||||
m_stat_newton_raphson(0),
|
m_stat_newton_raphson(0),
|
||||||
m_stat_vsolver_calls(0),
|
m_stat_vsolver_calls(0),
|
||||||
m_params(params),
|
m_params(*params),
|
||||||
m_cur_ts(0),
|
m_cur_ts(0),
|
||||||
m_type(type)
|
m_type(type)
|
||||||
{
|
{
|
||||||
@ -399,9 +399,9 @@ template <int m_N, int _storage_N>
|
|||||||
netlist_matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int gs_threshold, const bool use_specific)
|
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)
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (size >= gs_threshold)
|
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)
|
if (USE_MATRIX_GS)
|
||||||
{
|
{
|
||||||
typedef netlist_matrix_solver_SOR_mat_t<m_N,_storage_N> solver_mat;
|
typedef netlist_matrix_solver_SOR_mat_t<m_N,_storage_N> solver_mat;
|
||||||
return palloc(solver_mat, m_params, size);
|
return palloc(solver_mat, &m_params, size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typedef netlist_matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
|
typedef netlist_matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
|
||||||
return palloc(solver_GS, m_params, size);
|
return palloc(solver_GS, &m_params, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typedef netlist_matrix_solver_direct_t<m_N,_storage_N> solver_D;
|
typedef netlist_matrix_solver_direct_t<m_N,_storage_N> solver_D;
|
||||||
return palloc(solver_D, m_params, size);
|
return palloc(solver_D, &m_params, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ public:
|
|||||||
GAUSS_SEIDEL
|
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 ~netlist_matrix_solver_t();
|
||||||
|
|
||||||
/* ATTR_COLD */ virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
|
/* ATTR_COLD */ virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "nld_twoterm.h"
|
#include "nld_twoterm.h"
|
||||||
#include "nld_solver.h"
|
#include "nld_solver.h"
|
||||||
|
|
||||||
|
@ -261,12 +261,12 @@ private:
|
|||||||
class nld_base_proxy : public netlist_device_t
|
class nld_base_proxy : public netlist_device_t
|
||||||
{
|
{
|
||||||
public:
|
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()
|
: netlist_device_t()
|
||||||
{
|
{
|
||||||
m_logic_family = inout_proxied.logic_family();
|
m_logic_family = inout_proxied->logic_family();
|
||||||
m_term_proxied = &inout_proxied;
|
m_term_proxied = inout_proxied;
|
||||||
m_proxy_term = &proxy_inout;
|
m_proxy_term = proxy_inout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ATTR_COLD */ virtual ~nld_base_proxy() {}
|
/* ATTR_COLD */ virtual ~nld_base_proxy() {}
|
||||||
@ -294,8 +294,8 @@ private:
|
|||||||
class nld_a_to_d_proxy : public nld_base_proxy
|
class nld_a_to_d_proxy : public nld_base_proxy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ATTR_COLD nld_a_to_d_proxy(netlist_logic_input_t &in_proxied)
|
ATTR_COLD nld_a_to_d_proxy(netlist_logic_input_t *in_proxied)
|
||||||
: nld_base_proxy(in_proxied, m_I)
|
: nld_base_proxy(in_proxied, &m_I)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +336,7 @@ private:
|
|||||||
class nld_base_d_to_a_proxy : public nld_base_proxy
|
class nld_base_d_to_a_proxy : public nld_base_proxy
|
||||||
{
|
{
|
||||||
public:
|
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)
|
: 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
|
class nld_d_to_a_proxy : public nld_base_d_to_a_proxy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ATTR_COLD nld_d_to_a_proxy(netlist_logic_output_t &out_proxied)
|
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)
|
: nld_base_d_to_a_proxy(out_proxied, &m_RV.m_P)
|
||||||
, m_RV(TWOTERM)
|
, m_RV(TWOTERM)
|
||||||
, m_last_state(-1)
|
, m_last_state(-1)
|
||||||
, m_is_timestep(false)
|
, m_is_timestep(false)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "plib/palloc.h"
|
#include "plib/palloc.h"
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ public:
|
|||||||
m_R_low = 1.0;
|
m_R_low = 1.0;
|
||||||
m_R_high = 130.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);
|
return palloc(nld_d_to_a_proxy , proxied);
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ public:
|
|||||||
m_R_low = 1.0;
|
m_R_low = 1.0;
|
||||||
m_R_high = 130.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);
|
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());
|
set_logic_family(this->default_logic_family());
|
||||||
init_object(anetlist, name);
|
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;
|
void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update;
|
||||||
#if NO_USE_PMFCONVERSION
|
|
||||||
static_update = pFunc;
|
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<net_update_delegate>((this->*pFunc));
|
static_update = reinterpret_cast<net_update_delegate>((this->*pFunc));
|
||||||
|
#elif (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL)
|
||||||
|
static_update = pmfp::get_mfp<net_update_delegate>(&netlist_core_device_t::update, this);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_COLD netlist_core_device_t::~netlist_core_device_t()
|
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();
|
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);
|
inc_stat(netdev().stat_call_count);
|
||||||
if ((state() & mask) != 0)
|
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);
|
//assert(m_num_cons != 0);
|
||||||
nl_assert(this->isRailNet());
|
nl_assert(this->isRailNet());
|
||||||
@ -1056,7 +1057,7 @@ ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, co
|
|||||||
// mainclock
|
// 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.toggle_new_Q();
|
||||||
net.update_devs();
|
net.update_devs();
|
||||||
|
@ -170,13 +170,11 @@
|
|||||||
|
|
||||||
class netlist_core_device_t;
|
class netlist_core_device_t;
|
||||||
|
|
||||||
#if USE_PMFDELEGATES
|
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||||
#if NO_USE_PMFCONVERSION
|
|
||||||
typedef void (netlist_core_device_t::*net_update_delegate)();
|
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 *);
|
typedef void (*net_update_delegate)(netlist_core_device_t *);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// MACROS / netlist devices
|
// MACROS / netlist devices
|
||||||
@ -312,7 +310,7 @@ class netlist_logic_family_desc_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~netlist_logic_family_desc_t() {}
|
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_low_thresh_V;
|
||||||
nl_double m_high_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:
|
protected:
|
||||||
/* ATTR_COLD */ virtual void save_register()
|
/* ATTR_COLD */ virtual void save_register()
|
||||||
@ -1016,12 +1014,11 @@ public:
|
|||||||
{
|
{
|
||||||
begin_timing(stat_total_time);
|
begin_timing(stat_total_time);
|
||||||
inc_stat(stat_update_count);
|
inc_stat(stat_update_count);
|
||||||
#if USE_PMFDELEGATES
|
|
||||||
#if NO_USE_PMFCONVERSION
|
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||||
(this->*static_update)();
|
(this->*static_update)();
|
||||||
#else
|
#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
|
||||||
static_update(this);
|
static_update(this);
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
update();
|
update();
|
||||||
#endif
|
#endif
|
||||||
@ -1059,8 +1056,6 @@ public:
|
|||||||
ATTR_HOT virtual void step_time(ATTR_UNUSED const nl_double st) { }
|
ATTR_HOT virtual void step_time(ATTR_UNUSED const nl_double st) { }
|
||||||
ATTR_HOT virtual void update_terminals() { }
|
ATTR_HOT virtual void update_terminals() { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (NL_KEEP_STATISTICS)
|
#if (NL_KEEP_STATISTICS)
|
||||||
/* stats */
|
/* stats */
|
||||||
osd_ticks_t stat_total_time;
|
osd_ticks_t stat_total_time;
|
||||||
@ -1068,10 +1063,6 @@ public:
|
|||||||
INT32 stat_call_count;
|
INT32 stat_call_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_PMFDELEGATES
|
|
||||||
net_update_delegate static_update;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
ATTR_HOT virtual void update() { }
|
ATTR_HOT virtual void update() { }
|
||||||
@ -1083,6 +1074,9 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
|
||||||
|
net_update_delegate static_update;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,30 +15,55 @@
|
|||||||
//============================================================
|
//============================================================
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The next options needs -Wno-pmf-conversions to compile and gcc
|
* The following options determine how object::update is called.
|
||||||
* There is quite some significant speed-up of up to 20% involved.
|
* NL_PMF_TYPE_VIRTUAL
|
||||||
* NO_USE_PMFCONVERSION is for illustrative purposes only. Using PMFs
|
* Use stock virtual call
|
||||||
* has some overhead in comparison to calling a virtual function.
|
|
||||||
*
|
*
|
||||||
* 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.
|
* NL_PMF_TYPE_GNUC_PMF_CONV
|
||||||
* Therefore disabled for now for i386 builds.
|
* 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
|
// This will be autodetected
|
||||||
#if defined(__clang__) || defined(__APPLE__) || (defined(__GNUC__) && defined(__i386__))
|
// #define NL_PMF_TYPE 3
|
||||||
#define USE_PMFDELEGATES (0)
|
|
||||||
#define NO_USE_PMFCONVERSION (1)
|
#define NL_PMF_TYPE_VIRTUAL 0
|
||||||
#elif defined(__GNUC__)
|
#define NL_PMF_TYPE_GNUC_PMF 1
|
||||||
#define USE_PMFDELEGATES (0)
|
#define NL_PMF_TYPE_GNUC_PMF_CONV 2
|
||||||
#define NO_USE_PMFCONVERSION (0)
|
#define NL_PMF_TYPE_INTERNAL 3
|
||||||
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
|
||||||
#else
|
#ifndef NL_PMF_TYPE
|
||||||
#define USE_PMFDELEGATES (0)
|
#if PHAS_PMF_INTERNAL
|
||||||
#define NO_USE_PMFCONVERSION (1)
|
#define NL_PMF_TYPE NL_PMF_TYPE_INTERNAL
|
||||||
|
#else
|
||||||
|
#define NL_PMF_TYPE NL_PMF_TYPE_VIRTUAL
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV)
|
||||||
|
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -69,7 +94,6 @@
|
|||||||
|
|
||||||
#define NETLIST_GMIN_DEFAULT (1e-9)
|
#define NETLIST_GMIN_DEFAULT (1e-9)
|
||||||
|
|
||||||
|
|
||||||
//#define nl_double float
|
//#define nl_double float
|
||||||
//#define NL_FCONST(x) (x ## f)
|
//#define NL_FCONST(x) (x ## f)
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ NETLIST_END()
|
|||||||
// netlist_setup_t
|
// 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_netlist(netlist)
|
||||||
, m_proxy_cnt(0)
|
, m_proxy_cnt(0)
|
||||||
{
|
{
|
||||||
netlist.set_setup(this);
|
netlist->set_setup(this);
|
||||||
m_factory = palloc(netlist_factory_list_t);
|
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)
|
if (proxy == NULL)
|
||||||
{
|
{
|
||||||
// create a new one ...
|
// 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);
|
pstring x = pstring::sprintf("proxy_da_%s_%d", out.name().cstr(), m_proxy_cnt);
|
||||||
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))
|
if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC))
|
||||||
{
|
{
|
||||||
netlist_logic_input_t &incast = dynamic_cast<netlist_logic_input_t &>(in);
|
netlist_logic_input_t &incast = dynamic_cast<netlist_logic_input_t &>(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);
|
incast.set_proxy(proxy);
|
||||||
pstring x = pstring::sprintf("proxy_ad_%s_%d", in.name().cstr(), m_proxy_cnt);
|
pstring x = pstring::sprintf("proxy_ad_%s_%d", in.name().cstr(), m_proxy_cnt);
|
||||||
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<netlist_logic_input_t &>(inp);
|
netlist_logic_input_t &incast = dynamic_cast<netlist_logic_input_t &>(inp);
|
||||||
NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n"));
|
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);
|
incast.set_proxy(proxy);
|
||||||
pstring x = pstring::sprintf("proxy_ad_%s_%d", inp.name().cstr(), m_proxy_cnt);
|
pstring x = pstring::sprintf("proxy_ad_%s_%d", inp.name().cstr(), m_proxy_cnt);
|
||||||
m_proxy_cnt++;
|
m_proxy_cnt++;
|
||||||
@ -745,13 +745,13 @@ void netlist_setup_t::resolve_inputs()
|
|||||||
|
|
||||||
netlist().log("initialize solver ...\n");
|
netlist().log("initialize solver ...\n");
|
||||||
|
|
||||||
if (m_netlist.solver() == NULL)
|
if (netlist().solver() == NULL)
|
||||||
{
|
{
|
||||||
if (has_twoterms)
|
if (has_twoterms)
|
||||||
netlist().error("No solver found for this net although analog elements are present\n");
|
netlist().error("No solver found for this net although analog elements are present\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_netlist.solver()->post_start();
|
netlist().solver()->post_start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +107,13 @@ public:
|
|||||||
typedef pnamedlist_t<netlist_core_terminal_t *> tagmap_terminal_t;
|
typedef pnamedlist_t<netlist_core_terminal_t *> tagmap_terminal_t;
|
||||||
typedef plist_t<link_t> tagmap_link_t;
|
typedef plist_t<link_t> tagmap_link_t;
|
||||||
|
|
||||||
netlist_setup_t(netlist_base_t &netlist);
|
netlist_setup_t(netlist_base_t *netlist);
|
||||||
~netlist_setup_t();
|
~netlist_setup_t();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
netlist_base_t &netlist() { return m_netlist; }
|
netlist_base_t &netlist() { return *m_netlist; }
|
||||||
const netlist_base_t &netlist() const { return m_netlist; }
|
const netlist_base_t &netlist() const { return *m_netlist; }
|
||||||
|
|
||||||
pstring build_fqn(const pstring &obj_name) const;
|
pstring build_fqn(const pstring &obj_name) const;
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
netlist_base_t &m_netlist;
|
netlist_base_t *m_netlist;
|
||||||
|
|
||||||
tagmap_nstring_t m_alias;
|
tagmap_nstring_t m_alias;
|
||||||
tagmap_param_t m_params;
|
tagmap_param_t m_params;
|
||||||
|
@ -31,44 +31,44 @@ public:
|
|||||||
|
|
||||||
static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
|
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 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 */ 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 */ 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 */ 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 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 double &right) { m_time = (INTERNALTYPE) ( right * (double) RESOLUTION); return *this; }
|
||||||
|
|
||||||
// issues with ISO C++ standard
|
// 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 */ INTERNALTYPE as_raw() const { return m_time; }
|
||||||
ATTR_HOT inline double as_double() const { return (double) m_time / (double) RESOLUTION; }
|
ATTR_HOT /* inline */ double as_double() const { return (double) m_time / (double) RESOLUTION; }
|
||||||
|
|
||||||
// for save states ....
|
// 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_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_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_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_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_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_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
|
||||||
|
|
||||||
static const netlist_time zero;
|
static const netlist_time zero;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {}
|
ATTR_HOT /* inline */ netlist_time(const INTERNALTYPE val) : m_time(val) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INTERNALTYPE m_time;
|
INTERNALTYPE m_time;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "plib/pstring.h"
|
#include "plib/pstring.h"
|
||||||
#include "plib/plists.h"
|
#include "plib/plists.h"
|
||||||
|
@ -40,28 +40,28 @@ inline T *palloc_t()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename P1>
|
template<typename T, typename P1>
|
||||||
inline T *palloc_t(P1 &p1)
|
inline T *palloc_t(P1 p1)
|
||||||
{
|
{
|
||||||
void *p = palloc_raw(sizeof(T));
|
void *p = palloc_raw(sizeof(T));
|
||||||
return new (p) T(p1);
|
return new (p) T(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename P1, typename P2>
|
template<typename T, typename P1, typename P2>
|
||||||
inline T *palloc_t(P1 &p1, P2 &p2)
|
inline T *palloc_t(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
void *p = palloc_raw(sizeof(T));
|
void *p = palloc_raw(sizeof(T));
|
||||||
return new (p) T(p1, p2);
|
return new (p) T(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename P1, typename P2, typename P3>
|
template<typename T, typename P1, typename P2, typename P3>
|
||||||
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));
|
void *p = palloc_raw(sizeof(T));
|
||||||
return new (p) T(p1, p2, p3);
|
return new (p) T(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
template<typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||||
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));
|
void *p = palloc_raw(sizeof(T));
|
||||||
return new (p) T(p1, p2, p3, p4, p5, p6, p7);
|
return new (p) T(p1, p2, p3, p4, p5, p6, p7);
|
||||||
@ -87,9 +87,13 @@ inline void pfree_array_t(T *p)
|
|||||||
delete[] p;
|
delete[] p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
#define palloc(T, ...) palloc_t<T>(__VA_ARGS__)
|
#define palloc(T, ...) palloc_t<T>(__VA_ARGS__)
|
||||||
#define pfree(_ptr) pfree_t(_ptr)
|
#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<T>(N)
|
#define palloc_array(T, N) palloc_array_t<T>(N)
|
||||||
#define pfree_array(_ptr) pfree_array_t(_ptr)
|
#define pfree_array(_ptr) pfree_array_t(_ptr)
|
||||||
|
|
||||||
|
@ -12,24 +12,56 @@
|
|||||||
#define PSTANDALONE (0)
|
#define PSTANDALONE (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//============================================================
|
|
||||||
// Compiling standalone
|
|
||||||
//============================================================
|
|
||||||
|
|
||||||
// Compiling without mame ?
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdarg>
|
|
||||||
|
|
||||||
#if !(PSTANDALONE)
|
#if !(PSTANDALONE)
|
||||||
#include "osdcore.h"
|
#include "osdcore.h"
|
||||||
#include "eminline.h"
|
#include "eminline.h"
|
||||||
|
|
||||||
#undef ATTR_COLD
|
#ifndef assert
|
||||||
#define ATTR_COLD
|
#define assert(x) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "delegate.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cstddef>
|
||||||
|
#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 */
|
/* not supported in GCC prior to 4.4.x */
|
||||||
/* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */
|
/* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */
|
||||||
@ -97,4 +129,66 @@ typedef int64_t INT64;
|
|||||||
|
|
||||||
#endif
|
#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<typename _MemberFunctionType>
|
||||||
|
pmfp(_MemberFunctionType mfp)
|
||||||
|
: m_function(0), m_this_delta(0)
|
||||||
|
{
|
||||||
|
*reinterpret_cast<_MemberFunctionType *>(this) = mfp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// binding helper
|
||||||
|
template<typename _FunctionType, typename _ObjectType>
|
||||||
|
_FunctionType update_after_bind(_ObjectType *object)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<_FunctionType>(
|
||||||
|
convert_to_generic(reinterpret_cast<generic_class *>(object)));
|
||||||
|
}
|
||||||
|
template<typename _FunctionType, typename _MemberFunctionType, typename _ObjectType>
|
||||||
|
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<generic_class *>(reinterpret_cast<UINT8 *>(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<generic_function>(m_function);
|
||||||
|
|
||||||
|
// otherwise, it is the byte index into the vtable where the actual function lives
|
||||||
|
UINT8 *vtable_base = *reinterpret_cast<UINT8 **>(o_p_delta);
|
||||||
|
return *reinterpret_cast<generic_function *>(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_ */
|
#endif /* PCONFIG_H_ */
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "pparser.h"
|
#include "pparser.h"
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ NETLIST_SAVE_TYPE(INT32, DT_INT);
|
|||||||
NETLIST_SAVE_TYPE(UINT16, DT_INT16);
|
NETLIST_SAVE_TYPE(UINT16, DT_INT16);
|
||||||
NETLIST_SAVE_TYPE(INT16, DT_INT16);
|
NETLIST_SAVE_TYPE(INT16, DT_INT16);
|
||||||
//NETLIST_SAVE_TYPE(netlist_time::INTERNALTYPE, DT_INT64);
|
//NETLIST_SAVE_TYPE(netlist_time::INTERNALTYPE, DT_INT64);
|
||||||
|
//NETLIST_SAVE_TYPE(std::size_t, DT_INT64);
|
||||||
|
|
||||||
class pstate_manager_t;
|
class pstate_manager_t;
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
//FIXME:: pstring should be locale free
|
//FIXME:: pstring should be locale free
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "pstring.h"
|
#include "pstring.h"
|
||||||
#include "palloc.h"
|
#include "palloc.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef _PSTRING_H_
|
#ifndef _PSTRING_H_
|
||||||
#define _PSTRING_H_
|
#define _PSTRING_H_
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "pconfig.h"
|
#include "pconfig.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define NL_CONVERT_H_
|
#define NL_CONVERT_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "plib/pstring.h"
|
#include "plib/pstring.h"
|
||||||
#include "plib/plists.h"
|
#include "plib/plists.h"
|
||||||
@ -462,7 +463,7 @@ public:
|
|||||||
|
|
||||||
void verror(pstring msg, int line_num, pstring line)
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ public:
|
|||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
m_setup = palloc(netlist_setup_t, *this);
|
m_setup = palloc(netlist_setup_t, this);
|
||||||
this->init_object(*this, "netlist");
|
this->init_object(*this, "netlist");
|
||||||
m_setup->init();
|
m_setup->init();
|
||||||
}
|
}
|
||||||
@ -349,16 +349,29 @@ static void listdevices()
|
|||||||
main - primary entry point
|
main - primary entry point
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (!PSTANDALONE)
|
||||||
#include "corealloc.h"
|
#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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if (!PSTANDALONE)
|
||||||
track_memory(true);
|
track_memory(true);
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
tool_options_t opts;
|
tool_options_t opts;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
fprintf(stderr, "%s", "WARNING: This is Work In Progress! - It may fail anytime\n");
|
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)
|
if ((ret = opts.parse(argc, argv)) != argc)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error parsing %s\n", argv[ret]);
|
fprintf(stderr, "Error parsing %s\n", argv[ret]);
|
||||||
@ -396,7 +409,9 @@ int main(int argc, char *argv[])
|
|||||||
usage(opts);
|
usage(opts);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#if (!PSTANDALONE)
|
||||||
}
|
}
|
||||||
dump_unfreed_mem();
|
dump_unfreed_mem();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user