From ea0f297c85c5543057d373dfac100d602eba4760 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 6 Jun 2020 20:42:10 +0200 Subject: netlist: remove more macro usage, fix win float exceptions. (nw) --- src/devices/machine/netlist.cpp | 8 ++----- src/lib/netlist/nl_config.h | 9 ++++++++ src/lib/netlist/nltypes.h | 8 ++----- src/lib/netlist/plib/pconfig.h | 13 ------------ src/lib/netlist/plib/pexception.cpp | 26 +++++++++++++++++++++++ src/lib/netlist/plib/ptypes.h | 42 ++++++++++++++++++++++++++----------- 6 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index e26ac9b2764..9fd71f0bc3c 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -802,14 +802,12 @@ struct save_helper m_device->save_item(item, (m_prefix + "_" + name).c_str()); } -#if PHAS_INT128 - void save_item(INT128 &item, pstring name) + void save_item(std::enable_if_t &item, pstring name) { auto *p = reinterpret_cast(&item); m_device->save_item(p[0], (m_prefix + "_" + name + "_1").c_str()); m_device->save_item(p[1], (m_prefix + "_" + name + "_2").c_str()); } -#endif private: device_t *m_device; @@ -1133,10 +1131,8 @@ void netlist_mame_device::save_state() save_pointer((int16_t *) s->ptr(), s->name().c_str(), s->count()); else if (s->dt().size() == sizeof(int8_t)) save_pointer((int8_t *) s->ptr(), s->name().c_str(), s->count()); -#if (PHAS_INT128) - else if (s->dt().size() == sizeof(INT128)) + else if (plib::compile_info::has_int128::value && s->dt().size() == sizeof(INT128)) save_pointer((int64_t *) s->ptr(), s->name().c_str(), s->count() * 2); -#endif else netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->dt().size(), s->name().c_str()); } diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 9f122502efa..8740b5ddbd9 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -115,6 +115,15 @@ #define NL_USE_FLOAT128 PUSE_FLOAT128 #endif +/// \brief Prefer 128bit int type for ptime if supported +/// +/// Set this to one if you want to use 128 bit int for ptime. +/// This is about 10% slower on a skylake processor for pongf. +/// +#ifndef NL_PREFER_INT128 +#define NL_PREFER_INT128 (0) +#endif + /// \brief Support float type for matrix calculations. /// /// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h index fe0ec07067d..f7ccb9b53ec 100644 --- a/src/lib/netlist/nltypes.h +++ b/src/lib/netlist/nltypes.h @@ -142,13 +142,9 @@ namespace netlist } // namespace detail -#if (PHAS_INT128) using netlist_time = plib::ptime; - using netlist_time_ext = plib::ptime; -#else - using netlist_time = plib::ptime; - using netlist_time_ext = netlist_time; -#endif + using netlist_time_ext = plib::ptime::type, config::INTERNAL_RES::value>; + static_assert(noexcept(netlist_time::from_nsec(1)), "Not evaluated as constexpr"); //============================================================ diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 4e116b90344..b719139d73f 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -22,15 +22,6 @@ #define PUSE_ACCURATE_STATS (0) #endif -/// \brief System supports INT128 -/// -/// Set this to one if you want to use 128 bit int for ptime. -/// This is about 10% slower on a skylake processor for pongf. -/// -#ifndef PHAS_INT128 -#define PHAS_INT128 (0) -#endif - /// \brief Add support for the __float128 floating point type. /// #ifndef PUSE_FLOAT128 @@ -137,10 +128,6 @@ #endif #endif -#if (PHAS_INT128) -typedef __uint128_t UINT128; -typedef __int128_t INT128; -#endif #if (PUSE_FLOAT128) typedef __float128 FLOAT128; diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp index 674601f2ed8..d332f989321 100644 --- a/src/lib/netlist/plib/pexception.cpp +++ b/src/lib/netlist/plib/pexception.cpp @@ -6,6 +6,7 @@ #include #include +#include #if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__) #define HAS_FEENABLE_EXCEPT (1) @@ -103,6 +104,8 @@ namespace plib { bool fpsignalenabler::m_enable = false; + //FIXME: mingw needs to be compiled with "-fnon-call-exceptions" + fpsignalenabler::fpsignalenabler(unsigned fpexceptions) { #if HAS_FEENABLE_EXCEPT @@ -116,6 +119,18 @@ namespace plib { if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID; m_last_enabled = feenableexcept(b); } + #elif defined(_WIN32) && defined(_EM_INEXACT) + if (m_enable) + { + int b = _EM_DENORMAL | _EM_INEXACT | _EM_ZERODIVIDE | _EM_UNDERFLOW | _EM_OVERFLOW | _EM_INVALID; + if (fpexceptions & plib::FP_INEXACT) b &= ~_EM_INEXACT; + if (fpexceptions & plib::FP_DIVBYZERO) b &= ~_EM_ZERODIVIDE; + if (fpexceptions & plib::FP_UNDERFLOW) b &= ~_EM_UNDERFLOW; + if (fpexceptions & plib::FP_OVERFLOW) b &= ~_EM_OVERFLOW; + if (fpexceptions & plib::FP_INVALID) b &= ~_EM_INVALID; + m_last_enabled = _controlfp(0, 0); + _controlfp(b, _MCW_EM ); + } #else m_last_enabled = 0; #endif @@ -130,12 +145,23 @@ namespace plib { fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT } + #elif defined(_WIN32) && defined(_EM_INEXACT) + if (m_enable) + { + _controlfp(m_last_enabled, _MCW_EM); + } #endif } bool fpsignalenabler::supported() { + #if HAS_FEENABLE_EXCEPT + return true; + #elif defined(_WIN32) && defined(_EM_INEXACT) return true; + #else + return false; + #endif } bool fpsignalenabler::global_enable(bool enable) diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index fa2172c7507..c40735a0f48 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -39,6 +39,10 @@ namespace plib // compile time information //============================================================ + /// \brief Dummy 128 bit types for platforms which don't support 128 bit + struct UINT128_DUMMY {}; + struct INT128_DUMMY {}; + struct compile_info { #ifdef _WIN32 @@ -52,7 +56,27 @@ namespace plib using win32 = std::integral_constant; using unicode = std::integral_constant; #endif + #ifdef __SIZEOF_INT128__ + using has_int128 = std::integral_constant; + using int128_type = __int128_t; + using uint128_type = __uint128_t; + static constexpr int128_type int128_max() { return (~static_cast(0)) >> 1; } + static constexpr uint128_type uint128_max() { return ~(static_cast(0)); } + #else + using has_int128 = std::integral_constant; + using int128_type = INT128_DUMMY; + using uint128_type = UINT128_DUMMY; + static constexpr int128_type int128_max() { return int128_type(); } + static constexpr uint128_type uint128_max() { return uint128_type(); } + #endif }; +} // namespace plib + +using INT128 = plib::compile_info::int128_type; +using UINT128 = plib::compile_info::uint128_type; + +namespace plib +{ template struct is_integral : public std::is_integral { }; template struct is_signed : public std::is_signed { }; @@ -60,7 +84,7 @@ namespace plib template struct numeric_limits : public std::numeric_limits { }; // 128 bit support at least on GCC is not fully supported -#if PHAS_INT128 + template<> struct is_integral { static constexpr bool value = true; }; template<> struct is_integral { static constexpr bool value = true; }; @@ -74,17 +98,16 @@ namespace plib { static constexpr UINT128 max() noexcept { - return ~(static_cast(0)); + return compile_info::uint128_max(); } }; template<> struct numeric_limits { static constexpr INT128 max() noexcept { - return (~static_cast(0)) >> 1; + return compile_info::int128_max(); } }; -#endif template struct is_floating_point : public std::is_floating_point { }; @@ -110,16 +133,13 @@ namespace plib template struct size_for_bits { + static_assert(bits <= 64 || (bits <= 128 && compile_info::has_int128::value), "not supported"); enum { value = bits <= 8 ? 1 : bits <= 16 ? 2 : bits <= 32 ? 4 : -#if (PHAS_INT128) bits <= 64 ? 8 : 16 -#else - 8 -#endif }; }; @@ -128,9 +148,7 @@ namespace plib template<> struct least_type_for_size<2> { using type = uint_least16_t; }; template<> struct least_type_for_size<4> { using type = uint_least32_t; }; template<> struct least_type_for_size<8> { using type = uint_least64_t; }; -#if (PHAS_INT128) template<> struct least_type_for_size<16> { using type = UINT128; }; -#endif // This is different to the standard library. Mappings provided in stdint // are not always fastest. @@ -139,19 +157,19 @@ namespace plib template<> struct fast_type_for_size<2> { using type = uint32_t; }; template<> struct fast_type_for_size<4> { using type = uint32_t; }; template<> struct fast_type_for_size<8> { using type = uint_fast64_t; }; -#if (PHAS_INT128) template<> struct fast_type_for_size<16> { using type = UINT128; }; -#endif template struct least_type_for_bits { + static_assert(bits <= 64 || (bits <= 128 && compile_info::has_int128::value), "not supported"); using type = typename least_type_for_size::value>::type; }; template struct fast_type_for_bits { + static_assert(bits <= 64 || (bits <= 128 && compile_info::has_int128::value), "not supported"); using type = typename fast_type_for_size::value>::type; }; -- cgit v1.2.3