diff options
author | couriersud <couriersud@arcor.de> | 2017-01-04 18:00:38 +0100 |
---|---|---|
committer | couriersud <couriersud@arcor.de> | 2017-01-04 18:01:22 +0100 |
commit | 78ef96336e916fe0adbc313cbf706c413fcc75aa (patch) | |
tree | a7e2965e5e98cd2a502dab35b975aa610c3e1171 /src | |
parent | 85d1aca315bf336ca0f4cc51ba035f1607903cf8 (diff) |
Added SIGFPE enabling code to plib/pexception.*. Moved plib exceptions
into these files as well. The code uses <cfenv> which is part of c++11
standard. Non-standard glib extensions are currently only used on linux
and (i386 or x86_64). (nw)
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/netlist/build/makefile | 1 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/palloc.cpp | 38 | ||||
-rw-r--r-- | src/lib/netlist/plib/palloc.h | 54 | ||||
-rw-r--r-- | src/lib/netlist/plib/pexception.cpp | 109 | ||||
-rw-r--r-- | src/lib/netlist/plib/pexception.h | 112 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 8 |
8 files changed, 232 insertions, 92 deletions
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 171ba4cf5bb..cddb4751146 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -49,6 +49,7 @@ POBJS := \ $(POBJ)/palloc.o \ $(POBJ)/pchrono.o \ $(POBJ)/pdynlib.o \ + $(POBJ)/pexception.o \ $(POBJ)/pfmtlog.o \ $(POBJ)/poptions.o \ $(POBJ)/pparser.o \ diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 12181586b82..cfefc32bc41 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -22,6 +22,7 @@ #include "plib/pstate.h" #include "plib/pfmtlog.h" #include "plib/pstream.h" +#include "plib/pexception.h" // ---------------------------------------------------------------------------------------- // Type definitions diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp index b90960f953e..2f1131601da 100644 --- a/src/lib/netlist/plib/palloc.cpp +++ b/src/lib/netlist/plib/palloc.cpp @@ -12,44 +12,6 @@ #include "pfmtlog.h" namespace plib { -//============================================================ -// Exceptions -//============================================================ - -pexception::pexception(const pstring text) -{ - m_text = text; -} - -file_e::file_e(const pstring fmt, const pstring &filename) - : pexception(pfmt(fmt)(filename)) -{ -} - -file_open_e::file_open_e(const pstring &filename) - : file_e("File open failed: {}", filename) -{ -} - -file_read_e::file_read_e(const pstring &filename) - : file_e("File read failed: {}", filename) -{ -} - -file_write_e::file_write_e(const pstring &filename) - : file_e("File write failed: {}", filename) -{ -} - -null_argument_e::null_argument_e(const pstring &argument) - : pexception(pfmt("Null argument passed: {}")(argument)) -{ -} - -out_of_mem_e::out_of_mem_e(const pstring &location) - : pexception(pfmt("Out of memory: {}")(location)) -{ -} //============================================================ // Memory pool diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index a12595e0027..1f4a5b083d9 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -8,7 +8,6 @@ #ifndef PALLOC_H_ #define PALLOC_H_ -#include <exception> #include <vector> #include <memory> #include <utility> @@ -17,59 +16,6 @@ #include "pstring.h" namespace plib { -//============================================================ -// exception base -//============================================================ - -class pexception : public std::exception -{ -public: - pexception(const pstring text); - pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; } - - virtual ~pexception() noexcept {} - - const pstring &text() { return m_text; } - -private: - pstring m_text; -}; - -class file_e : public plib::pexception -{ -public: - explicit file_e(const pstring fmt, const pstring &filename); -}; - -class file_open_e : public file_e -{ -public: - explicit file_open_e(const pstring &filename); -}; - -class file_read_e : public file_e -{ -public: - explicit file_read_e(const pstring &filename); -}; - -class file_write_e : public file_e -{ -public: - explicit file_write_e(const pstring &filename); -}; - -class null_argument_e : public plib::pexception -{ -public: - explicit null_argument_e(const pstring &argument); -}; - -class out_of_mem_e : public plib::pexception -{ -public: - explicit out_of_mem_e(const pstring &location); -}; //============================================================ // Memory allocation diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp new file mode 100644 index 00000000000..a49fa699ce5 --- /dev/null +++ b/src/lib/netlist/plib/pexception.cpp @@ -0,0 +1,109 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * palloc.c + * + */ + +#include <cfenv> + +#include "pexception.h" +#include "pfmtlog.h" + +#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__) +#define HAS_FEENABLE_EXCEPT (1) +#else +#define HAS_FEENABLE_EXCEPT (0) +#endif + +namespace plib { +//============================================================ +// Exceptions +//============================================================ + +pexception::pexception(const pstring text) +{ + m_text = text; +} + +file_e::file_e(const pstring fmt, const pstring &filename) + : pexception(pfmt(fmt)(filename)) +{ +} + +file_open_e::file_open_e(const pstring &filename) + : file_e("File open failed: {}", filename) +{ +} + +file_read_e::file_read_e(const pstring &filename) + : file_e("File read failed: {}", filename) +{ +} + +file_write_e::file_write_e(const pstring &filename) + : file_e("File write failed: {}", filename) +{ +} + +null_argument_e::null_argument_e(const pstring &argument) + : pexception(pfmt("Null argument passed: {}")(argument)) +{ +} + +out_of_mem_e::out_of_mem_e(const pstring &location) + : pexception(pfmt("Out of memory: {}")(location)) +{ +} + +fpexception::fpexception(const pstring &text) + : pexception(pfmt("Out of memory: {}")(text)) +{ +} + +bool fpsignalenabler::m_enable = false; + +fpsignalenabler::fpsignalenabler(unsigned fpexceptions) +{ +#if HAS_FEENABLE_EXCEPT + if (m_enable) + { + unsigned b = 0; + if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT; + if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO; + if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW; + if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW; + if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID; + m_last_enabled = feenableexcept(b); + } +#else + m_last_enabled = 0; +#endif +} + + +fpsignalenabler::~fpsignalenabler() +{ +#if HAS_FEENABLE_EXCEPT + if (m_enable) + { + fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT + feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT + } +#endif +} + +bool fpsignalenabler::supported() +{ + return true; +} + +bool fpsignalenabler::global_enable(bool enable) +{ + bool old = m_enable; + m_enable = enable; + return old; +} + + +} diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h new file mode 100644 index 00000000000..7e3c59441c2 --- /dev/null +++ b/src/lib/netlist/plib/pexception.h @@ -0,0 +1,112 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * palloc.h + * + */ + +#ifndef PEXCEPTION_H_ +#define PEXCEPTION_H_ + +#include <exception> + +#include "pconfig.h" +#include "pstring.h" + +namespace plib { +//============================================================ +// exception base +//============================================================ + +class pexception : public std::exception +{ +public: + pexception(const pstring text); + pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; } + + virtual ~pexception() noexcept {} + + const pstring &text() { return m_text; } + +private: + pstring m_text; +}; + +class file_e : public plib::pexception +{ +public: + explicit file_e(const pstring fmt, const pstring &filename); +}; + +class file_open_e : public file_e +{ +public: + explicit file_open_e(const pstring &filename); +}; + +class file_read_e : public file_e +{ +public: + explicit file_read_e(const pstring &filename); +}; + +class file_write_e : public file_e +{ +public: + explicit file_write_e(const pstring &filename); +}; + +class null_argument_e : public plib::pexception +{ +public: + explicit null_argument_e(const pstring &argument); +}; + +class out_of_mem_e : public plib::pexception +{ +public: + explicit out_of_mem_e(const pstring &location); +}; + +/* FIXME: currently only a stub for later use. More use could be added by + * using “-fnon-call-exceptions" and sigaction to enable c++ exception supported. + */ + +class fpexception : public pexception +{ +public: + fpexception(const pstring &text); +}; + +static const unsigned FP_INEXACT = 0x0001; +static const unsigned FP_DIVBYZERO = 0x0002; +static const unsigned FP_UNDERFLOW = 0x0004; +static const unsigned FP_OVERFLOW = 0x0008; +static const unsigned FP_INVALID = 0x00010; +static const unsigned FP_ALL = 0x0001f; + +/* + * Catch SIGFPE on linux for debugging purposes. + */ + +class fpsignalenabler +{ +public: + fpsignalenabler(unsigned fpexceptions); + ~fpsignalenabler(); + + /* is the functionality supported ? */ + static bool supported(); + /* returns last global enable state */ + static bool global_enable(bool enable); + +private: + unsigned m_last_enabled; + + static bool m_enable; +}; + + +} + +#endif /* PEXCEPTION_H_ */ diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index e400837c3ac..11bf0fb12cf 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -13,6 +13,7 @@ #include "pconfig.h" #include "pstring.h" #include "pfmtlog.h" +#include "pexception.h" namespace plib { // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 086fe517a2f..60189bfb0cc 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -15,12 +15,15 @@ #include "plib/pstring.h" #include "plib/plists.h" #include "plib/ptypes.h" +#include "plib/pexception.h" #include "nl_setup.h" #include "nl_factory.h" #include "nl_parser.h" #include "devices/net_lib.h" #include "tools/nl_convert.h" +#include <cfenv> + class tool_options_t : public plib::options { public: @@ -440,8 +443,13 @@ int main(int argc, char *argv[]) tool_options_t opts; int ret; + /* make SIGFPE actually deliver signals on supoorted platforms */ + plib::fpsignalenabler::global_enable(true); + plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW); + //perr("{}", "WARNING: This is Work In Progress! - It may fail anytime\n"); //perr("Update dispatching using method {}\n", pmf_verbose[NL_PMF_TYPE]); + //printf("test2 %f\n", std::exp(-14362.38064713)); if ((ret = opts.parse(argc, argv)) != argc) { perr("Error parsing {}\n", argv[ret]); |