summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2017-01-04 18:00:38 +0100
committer couriersud <couriersud@arcor.de>2017-01-04 18:01:22 +0100
commit78ef96336e916fe0adbc313cbf706c413fcc75aa (patch)
treea7e2965e5e98cd2a502dab35b975aa610c3e1171 /src
parent85d1aca315bf336ca0f4cc51ba035f1607903cf8 (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/makefile1
-rw-r--r--src/lib/netlist/nl_base.h1
-rw-r--r--src/lib/netlist/plib/palloc.cpp38
-rw-r--r--src/lib/netlist/plib/palloc.h54
-rw-r--r--src/lib/netlist/plib/pexception.cpp109
-rw-r--r--src/lib/netlist/plib/pexception.h112
-rw-r--r--src/lib/netlist/plib/pstream.h1
-rw-r--r--src/lib/netlist/prg/nltool.cpp8
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]);