aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2013-11-07 20:45:28 +0100
committerUros Bizjak <uros@gcc.gnu.org>2013-11-07 20:45:28 +0100
commitd59a8fcce613f4a32c6323ee76e2ac191e0830cc (patch)
tree237bfbe00dde7132e0b5b649205713d48f4d7b94 /libgcc
parentf6de942eeb7bcb3c57cecd29af212f3e3e39593b (diff)
downloadgcc-d59a8fcce613f4a32c6323ee76e2ac191e0830cc.zip
gcc-d59a8fcce613f4a32c6323ee76e2ac191e0830cc.tar.gz
gcc-d59a8fcce613f4a32c6323ee76e2ac191e0830cc.tar.bz2
sfp-exceptions.c (__sfp_handle_exceptions): Handle FP_EX_DENORM.
* config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Handle FP_EX_DENORM. Store result to volatile location after SSE division to close interrupt window. Remove unneeded fwait after x87 division since interrupt window will be closed by emitted fstp. From-SVN: r204540
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/config/i386/sfp-exceptions.c16
2 files changed, 21 insertions, 2 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 4da11a0..8a644d7 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,10 @@
+2013-11-07 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Handle
+ FP_EX_DENORM. Store result to volatile location after SSE division
+ to close interrupt window. Remove unneeded fwait after x87
+ division since interrupt window will be closed by emitted fstp.
+
2013-11-06 Joseph Myers <joseph@codesourcery.com>
* soft-fp/README: Update.
diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c
index fbaaab2..6d449ec 100644
--- a/libgcc/config/i386/sfp-exceptions.c
+++ b/libgcc/config/i386/sfp-exceptions.c
@@ -48,20 +48,32 @@ __sfp_handle_exceptions (int _fex)
{
float f = 0.0f;
#ifdef __x86_64__
+ volatile float r;
asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
+ r = f; /* Needed to trigger exception. */
#else
asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
- asm volatile ("fwait");
+ /* No need for fwait, exception is triggered by emitted fstp. */
#endif
}
+ if (_fex & FP_EX_DENORM)
+ {
+ struct fenv temp;
+ asm volatile ("fnstenv\t%0" : "=m" (temp));
+ temp.__status_word |= FP_EX_DENORM;
+ asm volatile ("fldenv\t%0" : : "m" (temp));
+ asm volatile ("fwait");
+ }
if (_fex & FP_EX_DIVZERO)
{
float f = 1.0f, g = 0.0f;
#ifdef __x86_64__
+ volatile float r;
asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
+ r = f; /* Needed to trigger exception. */
#else
asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
- asm volatile ("fwait");
+ /* No need for fwait, exception is triggered by emitted fstp. */
#endif
}
if (_fex & FP_EX_OVERFLOW)