On Thu, Nov 7, 2013 at 9:55 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>> > I see code of the form (testing compilation rather than execution): >>> > >>> > flds 4(%esp) >>> > flds 8(%esp) >>> > fmulp %st, %st(1) >>> > fstps 12(%esp) >>> > >>> > where the fstps should result in the exception, and glibc uses volatile in >>> > several places, conditional on __FLT_EVAL_METHOD__ != 0, to force a >>> > conversion to the semantic type (whether for correct results, or to ensure >>> > exceptions). >>> >>> Yes, this is the exact sequence my example compiles to: >>> >>> 8048405: d9 44 24 14 flds 0x14(%esp) >>> 8048409: d9 44 24 18 flds 0x18(%esp) >>> 804840d: de c9 fmulp %st,%st(1) >>> 804840f: d9 5c 24 1c fstps 0x1c(%esp) >>> >>> unfortunately, it won't generate exception. >> >> Are you sure? It's documented as generating an exception. That may mean, >> as usual on x87, setting the exception bit (as can be tested by >> fetestexcept) and only calling a trap handler on the *next* x87 >> instruction. So if fstps is the last floating-point instruction executed >> by the program, a trap handler may not be called - but that's no different >> from an ordinary floating-point compound assignment having the >> exception-raising operation as the last floating-point instruction. > > Aha, here is the problem. > > The exception is not generated by fmulp, but by the fstps that follows > fmulp. The fstps will close exception window from fmulp, but fstps > needs another fwait to generate exception. I have added fwait after > fstps manually: > > 0x080483fd <+29>: fstps 0x18(%esp) > 0x08048401 <+33>: flds 0x18(%esp) > 0x08048405 <+37>: flds 0x18(%esp) > 0x08048409 <+41>: fmulp %st,%st(1) > 0x0804840b <+43>: fstps 0x1c(%esp) > => 0x0804840f <+47>: fwait > 0x08048410 <+48>: leave > > And in this case, exception was generated, as marked by "=>" in gdb. However, this insn also raised FE_INEXACT flag (also on x86_64), probably not what you wanted. Your code that generates FE_UNDERFLOW will also raise FE_INEXACT. (and FE_DENORMAL). Uros.