Hello! > Here’s my patch submission for adding IEEE intrinsic modules (following > Fortran 2003 and 2008 > standards) to gfortran. It implements the item 1, and part of item 2, of my > initial plan [1]. All the > IEEE modules, types, named constants, procedures are defined and fully > working. The patch > comes of course with plenty of testcases, and I can add some more if you can > think of things I’ve > forgotten. I’ve bootstrapped and regtested the patch on:
__asm__ __volatile__ ("fnclex\n\tfldcw\t%0" : : "m" (cw)); @@ -136,16 +165,54 @@ set_fpu (void) __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); /* The SSE exception masks are shifted by 7 bits. */ - cw_sse |= _FPU_MASK_ALL << 7; - cw_sse &= ~(excepts << 7); - - /* Clear stalled exception flags. */ - cw_sse &= ~_FPU_EX_ALL; You have to clear stalled SSE exceptions here. Their flags are in LSB bits, so their position is different than the position of exception mask bits in the control word. + /* Change the flags. This is tricky on 387 (unlike SSE), because we have + FNSTSW but no FLDSW instruction. */ + __asm__ __volatile__ ("fnstenv\t%0" : "=m" (*&temp)); + + temp.__status_word &= ~exc_clr; + temp.__status_word |= exc_set; + + __asm__ __volatile__ ("fldenv\t%0" : : "m" (*&temp)); Why do you need "*&" here? fldenv will also trigger exceptions with set flags on the next x87 FP insn ... + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); + + cw_sse &= ~exc_clr; + cw_sse |= exc_set; + + __asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse)); ... and ldmxcsr won't trigger exceptions, neither with SSE insn. Please see Intel documentation on FP exceptions. Uros.