sfp-machine.h (FP_EX_INVALID, [...]): New constants.
authorUros Bizjak <uros@gcc.gnu.org>
Sat, 19 May 2007 19:19:08 +0000 (21:19 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sat, 19 May 2007 19:19:08 +0000 (21:19 +0200)
        * config/i386/sfp-machine.h (FP_EX_INVALID, FP_EX_DENORM,
        FP_EXP_DIVZERO, FP_EX_OVERFLOW, FP_EX_UNDERFLOW, FP_EX_INEXACT):
        New constants.
        (struct fenv): New structure.
        (FP_HANDLE_EXCEPTIONS): New define.
        (FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF, FP_RND_MINF): New constants.
        (_FP_DECL_EXP): New define.
        (FP_INIT_ROUNDMODE): New define.
        (FP_ROUNDMODE): New define.

From-SVN: r124857

gcc/ChangeLog
gcc/config/i386/sfp-machine.h

index 0c0fdcc684dc3bd8d114c9c1fd0303a4619cdc41..dc0ed0790e7ef454722aba8e04ff4d781e891215 100644 (file)
@@ -1,3 +1,15 @@
+2007-05-19  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/sfp-machine.h (FP_EX_INVALID, FP_EX_DENORM,
+       FP_EXP_DIVZERO, FP_EX_OVERFLOW, FP_EX_UNDERFLOW, FP_EX_INEXACT):
+       New constants.
+       (struct fenv): New structure.
+       (FP_HANDLE_EXCEPTIONS): New define.
+       (FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF, FP_RND_MINF): New constants.
+       (_FP_DECL_EXP): New define.
+       (FP_INIT_ROUNDMODE): New define.
+       (FP_ROUNDMODE): New define.
+
 2007-05-19  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        * doc/invoke.texi (Warning Options): Add -Wconversion-sign.
        (convert_and_check): Don't check warnings if the conversion failed.
 
 2007-05-19 Andy Hutchinson <HutchinsonAndy@netscape.net>
-           Anatoly Sokolov <aesok@dol.ru>
+          Anatoly Sokolov <aesok@dol.ru>
 
        * config/avr/avr-protos.h (expand_prologue, expand_epilogue, 
        avr_epilogue_uses) : Add declaration.
        * config/avr/predicates.md (avr_sp_immediate_operand): New predicate.
        * config/avr/constraints.md (R): New constraint.
-       config/avr/avr.md (SREG_ADDR,  UNSPEC_SEI, UNSPEC_CLI, 
+       config/avr/avr.md (SREG_ADDR, UNSPEC_SEI, UNSPEC_CLI, 
        UNSPECV_PROLOGUE_SAVES, UNSPECV_EPILOGUE_RESTORES): New constants.
        (*pop1, *pop2, *pop3, *pop4, *pop5): Combine into ...
        (*addhi3_sp_R_pc2, *addhi3_sp_R_pc3): ... these patterns.
index d440e1d3266ae5d239b46508b189ee96347fef16..4a4e354303d1e4dbe5948383dcda8b91452a248d 100644 (file)
@@ -44,6 +44,82 @@ typedef unsigned int UTItype __attribute__((mode(TI)));
     R##_c = FP_CLS_NAN;                                                \
   } while (0)
 
+#define FP_EX_INVALID          0x01
+#define FP_EX_DENORM           0x02
+#define FP_EX_DIVZERO          0x04
+#define FP_EX_OVERFLOW         0x08
+#define FP_EX_UNDERFLOW                0x10
+#define FP_EX_INEXACT          0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS                                           \
+  do {                                                                 \
+    if (_fex & FP_EX_INVALID)                                          \
+      {                                                                        \
+       float f = 0.0;                                                  \
+       __asm__ __volatile__ ("divss %0, %0 " : : "x" (f));             \
+      }                                                                        \
+    if (_fex & FP_EX_DIVZERO)                                          \
+      {                                                                        \
+       float f = 1.0, g = 0.0;                                         \
+       __asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));     \
+      }                                                                        \
+    if (_fex & FP_EX_OVERFLOW)                                         \
+      {                                                                        \
+       struct fenv temp;                                               \
+       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
+       temp.__status_word |= FP_EX_OVERFLOW;                           \
+       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
+       __asm__ __volatile__ ("fwait");                                 \
+      }                                                                        \
+    if (_fex & FP_EX_UNDERFLOW)                                                \
+      {                                                                        \
+       struct fenv temp;                                               \
+       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
+       temp.__status_word |= FP_EX_UNDERFLOW;                          \
+       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
+       __asm__ __volatile__ ("fwait");                                 \
+      }                                                                        \
+    if (_fex & FP_EX_INEXACT)                                          \
+      {                                                                        \
+       struct fenv temp;                                               \
+       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
+       temp.__status_word |= FP_EX_INEXACT;                            \
+       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
+       __asm__ __volatile__ ("fwait");                                 \
+      }                                                                        \
+  } while (0)
+
+#define FP_RND_NEAREST         0
+#define FP_RND_ZERO            0xc00
+#define FP_RND_PINF            0x800
+#define FP_RND_MINF            0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE                      \
+  do {                                         \
+    __asm__ ("fnstcw %0" : "=m" (_fcw));       \
+  } while (0)
+
+#define FP_ROUNDMODE           (_fcw & 0xc00)
 
 #define        __LITTLE_ENDIAN 1234
 #define        __BIG_ENDIAN    4321