mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +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());
|
||||
|
||||
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();
|
||||
|
||||
|
@ -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<m_N, _storage_N>::vsolve_non_
|
||||
}
|
||||
|
||||
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)
|
||||
, m_dim(size)
|
||||
, 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>
|
||||
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)
|
||||
, m_dim(size)
|
||||
, m_lp_fact(0)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -20,7 +20,7 @@ class netlist_matrix_solver_SOR_t: public netlist_matrix_solver_direct_t<m_N, _s
|
||||
{
|
||||
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)
|
||||
, m_lp_fact(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:
|
||||
|
||||
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)
|
||||
, m_omega(params.m_sor)
|
||||
, m_omega(params->m_sor)
|
||||
, m_lp_fact(0)
|
||||
, m_gs_fail(0)
|
||||
, m_gs_total(0)
|
||||
|
@ -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 <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)
|
||||
{
|
||||
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<m_N,_storage_N> solver_mat;
|
||||
return palloc(solver_mat, m_params, size);
|
||||
return palloc(solver_mat, &m_params, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -5,6 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "nld_twoterm.h"
|
||||
#include "nld_solver.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)
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
#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<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
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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<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);
|
||||
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<netlist_logic_input_t &>(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();
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,13 +107,13 @@ public:
|
||||
typedef pnamedlist_t<netlist_core_terminal_t *> tagmap_terminal_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();
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "plib/pstring.h"
|
||||
#include "plib/plists.h"
|
||||
|
@ -40,28 +40,28 @@ inline T *palloc_t()
|
||||
}
|
||||
|
||||
template<typename T, typename P1>
|
||||
inline T *palloc_t(P1 &p1)
|
||||
inline T *palloc_t(P1 p1)
|
||||
{
|
||||
void *p = palloc_raw(sizeof(T));
|
||||
return new (p) T(p1);
|
||||
}
|
||||
|
||||
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));
|
||||
return new (p) T(p1, p2);
|
||||
}
|
||||
|
||||
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));
|
||||
return new (p) T(p1, p2, p3);
|
||||
}
|
||||
|
||||
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));
|
||||
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<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<T>(N)
|
||||
#define pfree_array(_ptr) pfree_array_t(_ptr)
|
||||
|
||||
|
@ -12,24 +12,56 @@
|
||||
#define PSTANDALONE (0)
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// Compiling standalone
|
||||
//============================================================
|
||||
|
||||
// Compiling without mame ?
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
|
||||
#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 <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 */
|
||||
/* 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<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_ */
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
#include "pparser.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;
|
||||
|
||||
|
@ -5,12 +5,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
//FIXME:: pstring should be locale free
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
#include "pstring.h"
|
||||
#include "palloc.h"
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef _PSTRING_H_
|
||||
#define _PSTRING_H_
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#include "pconfig.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define NL_CONVERT_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
|
||||
#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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user