strtoimax: port to HP-UX 11.11
[gnulib.git] / lib / fpucw.h
index 16aa4bc..0b7f528 100644 (file)
@@ -1,11 +1,11 @@
 /* Manipulating the FPU control word.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007-2013 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2007.
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,8 +13,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef _FPUCW_H
 #define _FPUCW_H
@@ -31,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
@@ -62,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 */
 
@@ -71,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)