Patchwork [i386] : Handle FP_EX_DENORM and improve __sfp_handle_exceptions

login
register
mail settings
Submitter Uros Bizjak
Date Nov. 7, 2013, 7:44 p.m.
Message ID <CAFULd4arbMXhyT7F4iq-fW-QzVyBAu0UNTb6s9AvmtxQT36ktA@mail.gmail.com>
Download mbox | patch
Permalink /patch/289470/
State New
Headers show

Comments

Uros Bizjak - Nov. 7, 2013, 7:44 p.m.
Hello!

Attached patch adds missing FP_EX_DENORM handling to x86 soft-fp
exception generator and improves support code a bit. The FP_EX_DENORM
handling will be needed by gfortran IEEE support.

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.

Tested on x86_64-pc-linux-gnu {,-m32} and committed to mainline SVN.

The patch will be backported to other release branches due to missing
FP_EX_DENORM.

Uros.

Patch

Index: config/i386/sfp-exceptions.c
===================================================================
--- config/i386/sfp-exceptions.c	(revision 204522)
+++ config/i386/sfp-exceptions.c	(working copy)
@@ -48,20 +48,32 @@ 
     {
       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)