This file is indexed.

/usr/include/CGAL/FPU.h is in libcgal-dev 4.7-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
// Copyright (c) 1998-2008  
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel).  All rights reserved. 
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s)     : Sylvain Pion

#ifndef CGAL_FPU_H
#define CGAL_FPU_H

#include <CGAL/assertions.h>

#ifndef __INTEL_COMPILER
#include <cmath> // for HUGE_VAL
#endif

// This file specifies some platform dependant functions, regarding the FPU
// directed rounding modes.  There is only support for double precision.
//
// It also contains the definition of the Protect_FPU_rounding<> class,
// which helps to protect blocks of code needing a particular rounding mode.

#if defined __alpha__  && defined __linux__
extern "C" {
#  include <fenv.h>
}
#elif defined __SUNPRO_CC && defined __sun
#  include <ieeefp.h>
#elif defined __osf || defined __osf__
#  ifdef __GNUG__
     // GCC seems to remove (fixincludes) read_rnd/write_rnd...
#    include "/usr/include/float.h"
#  else
#    include <cfloat>
#  endif
#elif defined _MSC_VER || defined __sparc__ || \
     (defined __i386__ && !defined __PGI && !defined __SUNPRO_CC \
      && !defined __SSE2__)
   // Nothing to include.
#else
   // By default we use the ISO C99 version.
#  include <fenv.h>
#endif


// Some useful constants

#if defined CGAL_CFG_NO_LIMITS
#  if defined CGAL_CFG_DENORMALS_COMPILE_BUG
     // For compilers crashing when dealing with denormalized values.
     // So we have to generate it at run time instead.
#    define CGAL_IA_MIN_DOUBLE (CGAL::internal::minimin)
#  else
#    define CGAL_IA_MIN_DOUBLE (5e-324)
#  endif
#  define CGAL_IA_MAX_DOUBLE (1.7976931348623157081e+308)
#else
#  include <limits>
#  define CGAL_IA_MIN_DOUBLE std::numeric_limits<double>::denorm_min()
#  define CGAL_IA_MAX_DOUBLE (std::numeric_limits<double>::max)()
#endif


// Pure and safe SSE2 mode (g++ -mfpmath=sse && (-msse2 || -march=pentium4))
// can be detected by :
// TODO : see what Intel and VC++ have to say about this.
#if defined __FLT_EVAL_METHOD__ && defined __SSE2_MATH__ && \
      (__FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1)
#  define CGAL_SAFE_SSE2
#  include <xmmintrin.h>
#endif

// The CGAL_FPU_HAS_EXCESS_PRECISION macro is defined if some computations with
// double can use more than the 53bits of precision of IEEE754, and/or if the
// exponent has a wider range.  This can produce double rounding effects and
// other bad things that we need to protect against.
// The typical offender is the traditional FPU of x86 (SSE2-only mode is not affected).
// Are there others, besides itanium and m68k?
#if !defined CGAL_IA_NO_X86_OVER_UNDER_FLOW_PROTECT && \
  (((defined __i386__ || defined __x86_64__) && !defined CGAL_SAFE_SSE2) \
   || defined __ia64__ \
   || defined _M_IX86 || defined _M_X64 || defined _M_IA64 \
   || (defined FLT_EVAL_METHOD && FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1))
#  define CGAL_FPU_HAS_EXCESS_PRECISION
#endif

// Presence of SSE2 (for explicit use)
#if  defined(__SSE2__) \
  || (defined(_M_IX86_FP) && _M_IX86_FP >= 2) \
  || defined(_M_X64)
#  include <emmintrin.h>
#  define CGAL_HAS_SSE2 1
#endif

// Only define CGAL_USE_SSE2 for 64 bits where malloc has a suitable
// alignment, 32 bits is too dangerous.
#if defined(CGAL_HAS_SSE2) && (defined(__x86_64__) || defined(_M_X64))
#  define CGAL_USE_SSE2 1
#endif

namespace CGAL {

namespace internal {

#ifdef CGAL_CFG_DENORMALS_COMPILE_BUG
CGAL_EXPORT extern double minimin;
#endif

#ifdef __INTEL_COMPILER
const double infinity = std::numeric_limits<double>::infinity();
#else
const double infinity = HUGE_VAL;
#endif

} // namespace internal

// Inline function to stop compiler optimizations that shouldn't happen with
// pragma fenv on.
// - constant propagation
// - migration of fesetround across floating point operations
// - (-a)-b -> -(a+b)
// - (-a)*b -> -(a*b)
// etc
inline double IA_opacify(double x)
{
#ifdef __llvm__
  // LLVM's support for inline asm is completely messed up:
  // http://llvm.org/bugs/show_bug.cgi?id=17958
  // http://llvm.org/bugs/show_bug.cgi?id=17959
  // etc.
  // This seems to produce code that is ok (not optimal but better than
  // volatile). In case of trouble, use volatile instead.
# ifdef CGAL_HAS_SSE2
  asm volatile ("" : "+x"(x) );
# elif (defined __VFP_FP__ && !defined __SOFTFP__) || defined __aarch64__
  // ARM
  asm volatile ("" : "+w"(x) );
# else
  asm volatile ("" : "+m"(x) );
# endif
  return x;
#elif defined __xlC__
  // PowerPC - XL C++ (the z/OS version supposedly does not define this macro)
  // If we give it an alternative "+fm", it gets confused and generates worse code.
  asm volatile ("" : "+f"(x) );
  return x;
#elif defined __GNUG__
  // Intel used not to emulate this perfectly, we'll see.
  // If we create a version of IA_opacify for vectors, note that gcc < 4.8
  // fails with "+g" and we need to use "+mx" instead.
  // "+X" ICEs ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59155 ) and
  // may not be safe?
  // The constraint 'g' doesn't include floating point registers ???
  // Intel has a bug where -mno-sse still defines __SSE__ and __SSE2__
  // (-mno-sse2 works though), no work-around for now.
# if defined __SSE2_MATH__ || (defined __INTEL_COMPILER && defined __SSE2__)
#  if __GNUC__ * 100 + __GNUC_MINOR__ >= 409
  // ICEs in reload/LRA with older versions.
  asm volatile ("" : "+gx"(x) );
#  else
  asm volatile ("" : "+mx"(x) );
#  endif
# elif (defined __i386__ || defined __x86_64__)
  // "+f" doesn't compile on x86(_64)
  // ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59157 )
  // Don't mix "t" with "g": http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59180
  // We can't put "t" with "x" either, prefer "x" for -mfpmath=sse,387.
  // ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59181 )
  asm volatile ("" : "+mt"(x) );
# elif (defined __VFP_FP__ && !defined __SOFTFP__) || defined __aarch64__
  // ARM
  asm volatile ("" : "+gw"(x) );
# elif defined __powerpc__ || defined __POWERPC__
  // PowerPC
  asm volatile ("" : "+gd"(x) );
# elif defined __sparc
  // Sparc
  asm volatile ("" : "+ge"(x) );
# elif defined __ia64
  // Itanium
  asm volatile ("" : "+gf"(x) );
# else
  asm volatile ("" : "+g"(x) );
# endif
  return x;
#else
  volatile double e = x;
  return e;
#endif
}

// Inline function to drop excess precision before we forget the rounding mode,
// and stop compiler optimizations at the same time.
inline double IA_force_to_double(double x)
{
#ifndef CGAL_FPU_HAS_EXCESS_PRECISION
  return IA_opacify (x);
#else
#if defined __GNUG__
#  ifdef CGAL_HAS_SSE2
  // For an explanation of volatile:
  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56027
  asm volatile ("" : "+mx"(x) );
#  else
  // Similar to writing to a volatile and reading back, except that calling
  // it k times in a row only goes through memory once.
  asm volatile ("" : "+m"(x) );
#  endif
  return x;
#else
  volatile double e = x;
  return e;
#endif
#endif
}

// Interval arithmetic needs to protect against double-rounding effects
// caused by excess FPU precision, even if it forces the 53bit mantissa
// precision, because there is no way to fix the problem for the exponent
// which has the same problem.  This affects underflow and overflow cases.
// In case one does not care about such "extreme" situations, one can
// set CGAL_IA_NO_X86_OVER_UNDER_FLOW_PROTECT to pretend there is no excess
// precision.
#if defined CGAL_FPU_HAS_EXCESS_PRECISION
#  define CGAL_IA_FORCE_TO_DOUBLE(x) CGAL::IA_force_to_double(x)
#elif 1
// LLVM doesn't have -frounding-math so needs extra protection.
// GCC also migrates fesetround calls over FP instructions, so protect
// everyone.
#  define CGAL_IA_FORCE_TO_DOUBLE(x) CGAL::IA_opacify(x)
#else
// Unused, reserved to compilers without excess precision and pragma fenv on.
// ??? Should we trust Visual Studio not to optimize too much and let it use
// this when CGAL_IA_NO_X86_OVER_UNDER_FLOW_PROTECT?
#  define CGAL_IA_FORCE_TO_DOUBLE(x) (x)
#endif

// We sometimes need to stop constant propagation,
// because operations are done with a wrong rounding mode at compile time.
#ifndef CGAL_IA_DONT_STOP_CONSTANT_PROPAGATION
#  define CGAL_IA_STOP_CPROP(x)    CGAL::IA_opacify(x)
#else
#  define CGAL_IA_STOP_CPROP(x)    (x)
#endif

// std::sqrt(double) on VC++ and CygWin is buggy when not optimizing.
#if defined ( _MSC_VER ) && ! defined ( _WIN64 )
inline double IA_bug_sqrt(double d)
{
  _asm
  {
    fld d
    fsqrt
    fstp d
  }
  return d;
}

#  define CGAL_BUG_SQRT(d) IA_bug_sqrt(d)


#elif defined __SSE2_MATH__
// For SSE2, we need to call __builtin_sqrt() instead of libc's sqrt().
#  define CGAL_BUG_SQRT(d) __builtin_sqrt(d)
#elif defined __CYGWIN__
inline double IA_bug_sqrt(double d)
{
  double r;
  asm volatile ("fsqrt" : "=t"(r) : "0"(d));
  return r;
}
#  define CGAL_BUG_SQRT(d) IA_bug_sqrt(d)
#else
#  define CGAL_BUG_SQRT(d) std::sqrt(d)
#endif

// Here are the operator macros that make use of the above.
// With GCC, we can do slightly better : test with __builtin_constant_p()
// that both arguments are constant before stopping one of them.
// Use inline functions instead ?
#define CGAL_IA_ADD(a,b) CGAL_IA_FORCE_TO_DOUBLE((a)+CGAL_IA_STOP_CPROP(b))
#define CGAL_IA_SUB(a,b) CGAL_IA_FORCE_TO_DOUBLE(CGAL_IA_STOP_CPROP(a)-(b))
#define CGAL_IA_MUL(a,b) CGAL_IA_FORCE_TO_DOUBLE((a)*CGAL_IA_STOP_CPROP(b))
#define CGAL_IA_DIV(a,b) CGAL_IA_FORCE_TO_DOUBLE((a)/CGAL_IA_STOP_CPROP(b))
#define CGAL_IA_SQUARE(a) CGAL_IA_MUL(a,a)
#define CGAL_IA_SQRT(a) \
        CGAL_IA_FORCE_TO_DOUBLE(CGAL_BUG_SQRT(CGAL_IA_STOP_CPROP(a)))


#if defined CGAL_SAFE_SSE2

#define CGAL_IA_SETFPCW(CW) _MM_SET_ROUNDING_MODE(CW)
#define CGAL_IA_GETFPCW(CW) CW = _MM_GET_ROUNDING_MODE()
typedef unsigned int FPU_CW_t;
#define CGAL_FE_TONEAREST    _MM_ROUND_NEAREST
#define CGAL_FE_TOWARDZERO   _MM_ROUND_TOWARD_ZERO
#define CGAL_FE_UPWARD       _MM_ROUND_UP
#define CGAL_FE_DOWNWARD     _MM_ROUND_DOWN

#elif defined __i386__ && !defined __PGI && !defined __SUNPRO_CC \
      && !defined CGAL_HAS_SSE2
// If we use both 387 and sse2, be safe and drop to fe[gs]etround.
// Can we test CGAL_USE_SSE2 instead?

// The GNU libc version (cf powerpc) is nicer, but doesn't work on libc 5 :(
// This one also works with CygWin.
// Note that the ISO C99 version may not be enough because of the extended
// mantissa issue on x86 (may be required by some kinds of computation, but
// as far as CGAL::Interval_nt<> is concerned, the double-rounding issues
// are taking care of there).
#define CGAL_IA_SETFPCW(CW) asm volatile ("fldcw %0" : :"m" (CW))
#define CGAL_IA_GETFPCW(CW) asm volatile ("fnstcw %0" : "=m" (CW))
typedef unsigned short FPU_CW_t;
#define CGAL_FE_TONEAREST    (0x000 | 0x127f)
#define CGAL_FE_TOWARDZERO   (0xc00 | 0x127f)
#define CGAL_FE_UPWARD       (0x800 | 0x127f)
#define CGAL_FE_DOWNWARD     (0x400 | 0x127f)

#elif defined __SUNPRO_CC && defined __sun
#define CGAL_IA_SETFPCW(CW) fpsetround(fp_rnd(CW))
#define CGAL_IA_GETFPCW(CW) CW = fpgetround()
typedef unsigned int FPU_CW_t;
#define CGAL_FE_TONEAREST    FP_RN
#define CGAL_FE_TOWARDZERO   FP_RZ
#define CGAL_FE_UPWARD       FP_RP
#define CGAL_FE_DOWNWARD     FP_RM

#elif defined __sparc__
#define CGAL_IA_SETFPCW(CW) asm volatile ("ld %0,%%fsr" : :"m" (CW))
#define CGAL_IA_GETFPCW(CW) asm volatile ("st %%fsr,%0" : "=m" (CW))
typedef unsigned int FPU_CW_t;
#define CGAL_FE_TONEAREST    (0x0        | 0x20000000 | 0x1f)
#define CGAL_FE_TOWARDZERO   (0x40000000 | 0x20000000 | 0x1f)
#define CGAL_FE_UPWARD       (0x80000000 | 0x20000000 | 0x1f)
#define CGAL_FE_DOWNWARD     (0xc0000000 | 0x20000000 | 0x1f)

#elif defined __mips__
#define CGAL_IA_SETFPCW(CW) asm volatile ("ctc1 %0,$31" : :"r" (CW))
#define CGAL_IA_GETFPCW(CW) asm volatile ("cfc1 %0,$31" : "=r" (CW))
typedef unsigned int FPU_CW_t;
#define CGAL_FE_TONEAREST    (0x0)
#define CGAL_FE_TOWARDZERO   (0x1)
#define CGAL_FE_UPWARD       (0x2)
#define CGAL_FE_DOWNWARD     (0x3)

#elif defined __osf || defined __osf__  // Not yet supported.
#define CGAL_IA_SETFPCW(CW) write_rnd(CW)
#define CGAL_IA_GETFPCW(CW) CW = read_rnd()
typedef unsigned int FPU_CW_t;
#define CGAL_FE_TONEAREST    FP_RND_RN
#define CGAL_FE_TOWARDZERO   FP_RND_RZ
#define CGAL_FE_UPWARD       FP_RND_RP
#define CGAL_FE_DOWNWARD     FP_RND_RM

#elif defined ( _MSC_VER )
#if ( _MSC_VER < 1400)
#define CGAL_IA_SETFPCW(CW) _controlfp (CW, _MCW_RC )
#define CGAL_IA_GETFPCW(CW) CW = _controlfp (0, 0 ) &  _MCW_RC
typedef unsigned short FPU_CW_t;
#else
#define CGAL_IA_SETFPCW(CW) unsigned int dummy; _controlfp_s (&dummy, CW, _MCW_RC )
#define CGAL_IA_GETFPCW(CW)_controlfp_s (&CW, 0, 0 ); CW  &=  _MCW_RC
typedef unsigned int FPU_CW_t;
#endif

#define CGAL_FE_TONEAREST    _RC_NEAR
#define CGAL_FE_TOWARDZERO   _RC_CHOP
#define CGAL_FE_UPWARD       _RC_UP
#define CGAL_FE_DOWNWARD     _RC_DOWN

#else
// This is a version following the ISO C99 standard, which aims at portability.
// The drawbacks are speed on one hand, and also, on x86, it doesn't fix the
// extended mantissa issue (this is not a problem for IA, but it is one for
// some future modular computations).
#define CGAL_IA_SETFPCW(CW)  fesetround(CW)
#define CGAL_IA_GETFPCW(CW)  CW = fegetround()
typedef int FPU_CW_t;
#define CGAL_FE_TONEAREST    FE_TONEAREST
#define CGAL_FE_TOWARDZERO   FE_TOWARDZERO
#define CGAL_FE_UPWARD       FE_UPWARD
#define CGAL_FE_DOWNWARD     FE_DOWNWARD
#endif

// User interface:

inline
FPU_CW_t
FPU_get_cw (void)
{
    FPU_CW_t cw;
    CGAL_IA_GETFPCW(cw);
    return cw;
}

inline
void
FPU_set_cw (FPU_CW_t cw)
{
    CGAL_IA_SETFPCW(cw);
}

inline
FPU_CW_t
FPU_get_and_set_cw (FPU_CW_t cw)
{
    FPU_CW_t old = FPU_get_cw();
    FPU_set_cw(cw);
    return old;
}


// A class whose constructor sets the FPU mode to +inf, saves a backup of it,
// and whose destructor resets it back to the saved state.

template <bool Protected = true> struct Protect_FPU_rounding;

template <>
struct Protect_FPU_rounding<true>
{
  Protect_FPU_rounding(FPU_CW_t r = CGAL_FE_UPWARD)
    : backup( FPU_get_and_set_cw(r) ) {}

  ~Protect_FPU_rounding()
  {
     FPU_set_cw(backup);
  }

private:
  FPU_CW_t backup;
};

template <>
struct Protect_FPU_rounding<false>
{
  Protect_FPU_rounding() {}
  Protect_FPU_rounding(FPU_CW_t /*= CGAL_FE_UPWARD*/) {}
};


// A wrapper on top of the Protect_FPU_rounding to add "expensive" checks
// of the rounding mode.  It is used internally, to benefit from the
// protector declarations to add checks in non-protected mode.

template <bool Protected = true>
struct Checked_protect_FPU_rounding
  : Protect_FPU_rounding<Protected>
{
  Checked_protect_FPU_rounding()
  {
    CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_UPWARD);
  }

  Checked_protect_FPU_rounding(FPU_CW_t r)
    : Protect_FPU_rounding<Protected>(r)
  {
    CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_UPWARD);
  }
};


// The class Set_ieee_double_precision forces the double precision (53bit mantissa),
// to protect from double rounding effects on x86 FPU.
// ( Note that it also sets the rounding mode to nearest. )
// Its destructor restores the FPU state as it was previously.
// Note that this affects "long double" as well, and other potential side effects.
// And note that it does not (cannot) "fix" the same problem for the exponent.

struct Set_ieee_double_precision
#ifdef CGAL_FPU_HAS_EXCESS_PRECISION
  : public Protect_FPU_rounding<>
{
  Set_ieee_double_precision()
    : Protect_FPU_rounding<>(CGAL_FE_TONEAREST) {}
};
#else
{
  Set_ieee_double_precision() {} // only to kill compiler warnings.
};
#endif


// The following function serves the same goal as Set_ieee_double_precision but
// does the change globally (no destructor resets the previous behavior).
inline void force_ieee_double_precision()
{
#ifdef CGAL_FPU_HAS_EXCESS_PRECISION
    FPU_set_cw(CGAL_FE_TONEAREST);
#endif
}

} //namespace CGAL

#endif // CGAL_FPU_H