aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2007-05-19 21:19:08 +0200
committerUros Bizjak <uros@gcc.gnu.org>2007-05-19 21:19:08 +0200
commite9d416168f5d1782664609c71972e41eb2523a21 (patch)
tree08728cd0fea3aded65bcd316bff0c701fb67097e /gcc
parent7060db96db1a93b956a065ab05fc2995d5af17f1 (diff)
downloadgcc-e9d416168f5d1782664609c71972e41eb2523a21.zip
gcc-e9d416168f5d1782664609c71972e41eb2523a21.tar.gz
gcc-e9d416168f5d1782664609c71972e41eb2523a21.tar.bz2
sfp-machine.h (FP_EX_INVALID, [...]): New constants.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/i386/sfp-machine.h76
2 files changed, 90 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0c0fdcc..dc0ed07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
@@ -13,13 +25,13 @@
(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.
diff --git a/gcc/config/i386/sfp-machine.h b/gcc/config/i386/sfp-machine.h
index d440e1d..4a4e354 100644
--- a/gcc/config/i386/sfp-machine.h
+++ b/gcc/config/i386/sfp-machine.h
@@ -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