maint: update copyright
[gnulib.git] / lib / fpucw.h
index d5c2b62..9170c27 100644 (file)
@@ -1,5 +1,5 @@
 /* Manipulating the FPU control word.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007-2014 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2007.
 
    This program is free software: you can redistribute it and/or modify
@@ -30,7 +30,8 @@
 
    On some platforms, such as NetBSD, the default precision is set to
    "double precision".  This means that 'long double' instructions will operate
-   only as 'double', i.e. lead wrong results.
+   only as 'double', i.e. lead to wrong results.  Similarly on FreeBSD 6.4, at
+   least for the division of 'long double' numbers.
 
    The FPU control word is under control of the application, i.e. it is
    not required to be set either way by the ABI.  (In fact, the i386 ABI
@@ -61,7 +62,7 @@
  */
 
 /* Inline assembler like this works only with GNU C.  */
-#if defined __i386__ && defined __GNUC__
+#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
 
 typedef unsigned short fpucw_t; /* glibc calls this fpu_control_t */
 
@@ -70,19 +71,19 @@ typedef unsigned short fpucw_t; /* glibc calls this fpu_control_t */
 # define FPU_PC_EXTENDED 0x300  /* glibc calls this _FPU_EXTENDED */
 
 # define GET_FPUCW() \
-  ({ fpucw_t _cw;                                              \
-     __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_cw));                \
-     _cw;                                                      \
+  ({ fpucw_t _cw;                                               \
+     __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_cw));         \
+     _cw;                                                       \
    })
 # define SET_FPUCW(word) \
-  (void)({ fpucw_t _ncw = (word);                              \
-           __asm__ __volatile__ ("fldcw %0" : : "m" (*&_ncw)); \
+  (void)({ fpucw_t _ncw = (word);                               \
+           __asm__ __volatile__ ("fldcw %0" : : "m" (*&_ncw));  \
          })
 
 # define DECL_LONG_DOUBLE_ROUNDING \
   fpucw_t oldcw;
 # define BEGIN_LONG_DOUBLE_ROUNDING() \
-  (void)(oldcw = GET_FPUCW (),                                 \
+  (void)(oldcw = GET_FPUCW (),                                  \
          SET_FPUCW ((oldcw & ~FPU_PC_MASK) | FPU_PC_EXTENDED))
 # define END_LONG_DOUBLE_ROUNDING() \
   SET_FPUCW (oldcw)