00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ppl-config.h>
00025
00026 #include "Init.defs.hh"
00027 #include "Variable.defs.hh"
00028 #include "fpu.defs.hh"
00029 #include "Rounding_Dir.defs.hh"
00030 #include "checked.defs.hh"
00031 #include "Coefficient.defs.hh"
00032 #include "Linear_Expression.defs.hh"
00033 #include "Constraint.defs.hh"
00034 #include "Generator.defs.hh"
00035 #include "Congruence.defs.hh"
00036 #include "Grid_Generator.defs.hh"
00037 #include "Constraint_System.defs.hh"
00038 #include "Generator_System.defs.hh"
00039 #include "Congruence_System.defs.hh"
00040 #include "Grid_Generator_System.defs.hh"
00041 #include "Polyhedron.defs.hh"
00042 #include <stdexcept>
00043
00044 namespace PPL = Parma_Polyhedra_Library;
00045
00046 unsigned int PPL::Init::count = 0;
00047
00048 PPL::fpu_rounding_direction_type PPL::Init::old_rounding_direction;
00049
00050 extern "C" void
00051 ppl_set_GMP_memory_allocation_functions(void)
00052 #if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK
00053 __attribute__((weak));
00054
00055 void
00056 ppl_set_GMP_memory_allocation_functions(void) {
00057 }
00058 #else
00059 ;
00060 #endif
00061
00062 #if PPL_CAN_CONTROL_FPU \
00063 && defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
00064
00065 namespace {
00066
00067 float nf1 = -3, pf1 = 3, f2 = 5;
00068 double nd1 = -7, pd1 = 7, d2 = 11;
00069 long double nl1 = -13, pl1 = 13, l2 = 17;
00070
00071 float nf[2], pf[2];
00072 double nd[2], pd[2];
00073 long double nl[2], pl[2];
00074
00075 int
00076 ppl_check_function() {
00077 int r = 0;
00078 if (nf[0] == nf[1] || pf[0] == pf[1] || -nf[0] != pf[1] || -nf[1] != pf[0])
00079 r |= 1;
00080 if (nd[0] == nd[1] || pd[0] == pd[1] || -nd[0] != pd[1] || -nd[1] != pd[0])
00081 r |= 2;
00082 if (nl[0] == nl[1] || pl[0] == pl[1] || -nl[0] != pl[1] || -nl[1] != pl[0])
00083 r |= 4;
00084 return r;
00085 }
00086
00087 int
00088 ppl_setround_function(int rounding_mode) {
00089 return fesetround(rounding_mode);
00090 }
00091
00092 }
00093
00094 namespace Parma_Polyhedra_Library {
00095
00096 namespace Implementation {
00097
00098 int (* volatile ppl_check_function_p)() = ppl_check_function;
00099 int (* volatile ppl_setround_function_p)(int) = ppl_setround_function;
00100
00101 }
00102
00103 }
00104
00105 namespace {
00106
00107 int
00108 ppl_test_rounding() {
00109 if ((*ppl_setround_function_p)(FE_DOWNWARD) != 0)
00110 return 255;
00111
00112 nf[0] = nf1 / f2;
00113 nd[0] = nd1 / d2;
00114 nl[0] = nl1 / l2;
00115 pf[0] = pf1 / f2;
00116 pd[0] = pd1 / d2;
00117 pl[0] = pl1 / l2;
00118
00119 if ((*ppl_setround_function_p)(FE_UPWARD) != 0)
00120 return 255;
00121
00122 nf[1] = nf1 / f2;
00123 nd[1] = nd1 / d2;
00124 nl[1] = nl1 / l2;
00125 pf[1] = pf1 / f2;
00126 pd[1] = pd1 / d2;
00127 pl[1] = pl1 / l2;
00128
00129 return (*ppl_check_function_p)();
00130 }
00131
00132 }
00133
00134 #endif // PPL_CAN_CONTROL_FPU
00135
00136
00137 PPL::Init::Init() {
00138
00139 if (count++ == 0) {
00140
00141 ppl_set_GMP_memory_allocation_functions();
00142
00143 Variable::set_output_function(Variable::default_output_function);
00144
00145 Coefficient_constants_initialize();
00146
00147 Linear_Expression::initialize();
00148
00149
00150
00151 Constraint::initialize();
00152 Generator::initialize();
00153 Congruence::initialize();
00154 Grid_Generator::initialize();
00155 Constraint_System::initialize();
00156 Generator_System::initialize();
00157 Congruence_System::initialize();
00158 Grid_Generator_System::initialize();
00159 Polyhedron::initialize();
00160
00161 #if PPL_CAN_CONTROL_FPU
00162
00163
00164 fpu_initialize_control_functions();
00165 old_rounding_direction = fpu_get_rounding_direction();
00166 fpu_set_rounding_direction(round_fpu_dir(ROUND_DIRECT));
00167
00168 #if defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
00169 if (ppl_test_rounding() != 0)
00170 throw std::logic_error("PPL configuration error:"
00171 " PPL_ARM_CAN_CONTROL_FPU evaluates to true,"
00172 " but rounding does not work.");
00173 #endif // defined(PPL_ARM_CAN_CONTROL_FPU) && PPL_ARM_CAN_CONTROL_FPU
00174
00175 #endif // PPL_CAN_CONTROL_FPU
00176
00177
00178
00179 set_irrational_precision(128);
00180 }
00181 }
00182
00183 PPL::Init::~Init() {
00184
00185 if (--count == 0) {
00186 #if PPL_CAN_CONTROL_FPU
00187
00188 fpu_set_rounding_direction(old_rounding_direction);
00189 #endif
00190
00191
00192
00193
00194 Polyhedron::finalize();
00195 Grid_Generator_System::finalize();
00196 Congruence_System::finalize();
00197 Generator_System::finalize();
00198 Constraint_System::finalize();
00199 Grid_Generator::finalize();
00200 Congruence::finalize();
00201 Generator::finalize();
00202 Constraint::finalize();
00203
00204 Linear_Expression::finalize();
00205
00206 Coefficient_constants_finalize();
00207 }
00208 }