[PPL-devel] [GIT] ppl/ppl(master): Use of PPL_ARM_CAN_CONTROL_FPU made safer.
Roberto Bagnara
bagnara at cs.unipr.it
Tue Apr 21 21:54:25 CEST 2009
Module: ppl/ppl
Branch: master
Commit: 7f4c56724b1b865aa8d8fc6ef563467d105ba609
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=7f4c56724b1b865aa8d8fc6ef563467d105ba609
Author: Roberto Bagnara <bagnara at cs.unipr.it>
Date: Tue Apr 21 21:53:44 2009 +0200
Use of PPL_ARM_CAN_CONTROL_FPU made safer.
When the PPL has been configured with CPPFLAGS="-DPPL_ARM_CAN_CONTROL_FPU=1",
the library initialization procedure checks that the FPU can indeed be
controlled and fails if that is not the case.
---
NEWS | 6 ++-
TODO | 4 --
src/Init.cc | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 92 insertions(+), 7 deletions(-)
diff --git a/NEWS b/NEWS
index 9b35ac5..cc6ecb8 100644
--- a/NEWS
+++ b/NEWS
@@ -12,9 +12,11 @@ New and Changed Features
o Implementation of general (NNC) polyhedra speeded up.
+o When the PPL has been configured with
+ CPPFLAGS="-DPPL_ARM_CAN_CONTROL_FPU=1", the library initialization
+ procedure checks that the FPU can indeed be controlled and fails if
+ that is not the case.
-New and Changed Features
-========================
Deprecated and removed methods
------------------------------
diff --git a/TODO b/TODO
index cfbd3be..6c4877d 100644
--- a/TODO
+++ b/TODO
@@ -10,10 +10,6 @@ Enhancements for PPL 0.11
current interface based on `abandon_expensive_computations'.
- Get rid of ugly assign functions defined in anonymous namespace of
MIP_Problem.cc replacing it with a more general-purpose approach.
-- When the PPL has been configured with
- CPPFLAGS="-DPPL_ARM_CAN_CONTROL_FPU=1" make sure the library initialization
- procedure checks that the FPU can indeed be controlled, failing if
- that is not the case.
- Reconsider the datatype for the units parameter in the Watchdog
constructors: should we prefer an unsigned?
- Rename set_rational_sqrt_precision_parameter to
diff --git a/src/Init.cc b/src/Init.cc
index 35fb4f4..45e994d 100644
--- a/src/Init.cc
+++ b/src/Init.cc
@@ -38,6 +38,7 @@ site: http://www.cs.unipr.it/ppl/ . */
#include "Congruence_System.defs.hh"
#include "Grid_Generator_System.defs.hh"
#include "Polyhedron.defs.hh"
+#include <stdexcept>
namespace PPL = Parma_Polyhedra_Library;
@@ -57,6 +58,81 @@ ppl_set_GMP_memory_allocation_functions(void) {
;
#endif
+#if PPL_CAN_CONTROL_FPU \
+ && defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
+
+namespace {
+
+ float nf1 = -3, pf1 = 3, f2 = 5;
+ double nd1 = -7, pd1 = 7, d2 = 11;
+long double nl1 = -13, pl1 = 13, l2 = 17;
+
+ float nf[2], pf[2];
+ double nd[2], pd[2];
+long double nl[2], pl[2];
+
+int
+ppl_check_function() {
+ int r = 0;
+ if (nf[0] == nf[1] || pf[0] == pf[1] || -nf[0] != pf[1] || -nf[1] != pf[0])
+ r |= 1;
+ if (nd[0] == nd[1] || pd[0] == pd[1] || -nd[0] != pd[1] || -nd[1] != pd[0])
+ r |= 2;
+ if (nl[0] == nl[1] || pl[0] == pl[1] || -nl[0] != pl[1] || -nl[1] != pl[0])
+ r |= 4;
+ return r;
+}
+
+int
+ppl_setround_function(int rounding_mode) {
+ return fesetround(rounding_mode);
+}
+
+} // namespace
+
+namespace Parma_Polyhedra_Library {
+
+namespace Implementation {
+
+int (* volatile ppl_check_function_p)() = ppl_check_function;
+int (* volatile ppl_setround_function_p)(int) = ppl_setround_function;
+
+} // Implementation
+
+} // Parma_Polyhedra_Library
+
+namespace {
+
+int
+ppl_test_rounding() {
+ if ((*ppl_setround_function_p)(FE_DOWNWARD) != 0)
+ return 255;
+
+ nf[0] = nf1 / f2;
+ nd[0] = nd1 / d2;
+ nl[0] = nl1 / l2;
+ pf[0] = pf1 / f2;
+ pd[0] = pd1 / d2;
+ pl[0] = pl1 / l2;
+
+ if ((*ppl_setround_function_p)(FE_UPWARD) != 0)
+ return 255;
+
+ nf[1] = nf1 / f2;
+ nd[1] = nd1 / d2;
+ nl[1] = nl1 / l2;
+ pf[1] = pf1 / f2;
+ pd[1] = pd1 / d2;
+ pl[1] = pl1 / l2;
+
+ return (*ppl_check_function_p)();
+}
+
+} // namespace
+
+#endif // PPL_CAN_CONTROL_FPU
+ // && defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
+
PPL::Init::Init() {
// Only when the first Init object is constructed...
if (count++ == 0) {
@@ -80,12 +156,23 @@ PPL::Init::Init() {
Congruence_System::initialize();
Grid_Generator_System::initialize();
Polyhedron::initialize();
+
#if PPL_CAN_CONTROL_FPU
+
// ... and the FPU rounding direction is set.
fpu_initialize_control_functions();
old_rounding_direction = fpu_get_rounding_direction();
fpu_set_rounding_direction(round_fpu_dir(ROUND_DIRECT));
-#endif
+
+#if defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
+ if (ppl_test_rounding() != 0)
+ throw std::logic_error("PPL configuration error:"
+ " PPL_ARM_CAN_CONTROL_FPU evaluates to true,"
+ " but rounding does not work.");
+#endif // defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
+
+#endif // PPL_CAN_CONTROL_FPU
+
// The default is choosen to have a precision greater than most
// precise IEC559 floating point (112 bits of mantissa).
set_rational_sqrt_precision_parameter(128);
More information about the PPL-devel
mailing list