diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28c6a6da236959fe7f0407f13d13356724dbe4b8..be8eb9ea473400fa2211e8dbc290e8f9be1116f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-05-28 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/fp_exception.adb: New test. + 2013-05-28 Richard Biener <rguenther@suse.de> PR tree-optimization/56787 diff --git a/gcc/testsuite/gnat.dg/fp_exception.adb b/gcc/testsuite/gnat.dg/fp_exception.adb new file mode 100644 index 0000000000000000000000000000000000000000..a8bf62fa9233f8754e5ac035e56d4572d37d73eb --- /dev/null +++ b/gcc/testsuite/gnat.dg/fp_exception.adb @@ -0,0 +1,24 @@ +-- { dg-do run { target *-*-solaris2.* } } +-- { dg-options "-ftrapping-math" } + +procedure FP_Exception is + + type my_fixed is digits 15; + for my_fixed'size use 64; + fixed1 : my_fixed := 1.0; + fixed2 : my_fixed := -0.0; + mask_all : constant integer := 16#1F#; + + procedure fpsetmask(mask : in integer); + pragma IMPORT (C, fpsetmask, "fpsetmask"); + +begin + + -- Mask all floating point exceptions so they can be trapped + fpsetmask (mask_all); + + fixed1 := fixed1 / fixed2; + +exception + when others => null; +end; diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 861d5da33583cd6b780cfc4b21f430d45f71029b..66f292155798f170676d21cdd94e0e9d6361ce04 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2013-05-28 Eric Botcazou <ebotcazou@adacore.com> + + * config/sparc/sol2-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Do not set + fs->signal_frame for SIGFPE raised for IEEE-754 exceptions. + * config/i386/sol2-unwind.h (x86_fallback_frame_state): Likewise. + 2013-05-22 Eric Botcazou <ebotcazou@adacore.com> * config.host (powerpc-*-elf*): Add rs6000/t-savresfgpr to tmake_file. diff --git a/libgcc/config/i386/sol2-unwind.h b/libgcc/config/i386/sol2-unwind.h index f804aaf15a77ee424ca60be906336d0f2d2149e2..e67710907b138a6c1a31ecb878a4c826a41da102 100644 --- a/libgcc/config/i386/sol2-unwind.h +++ b/libgcc/config/i386/sol2-unwind.h @@ -249,7 +249,12 @@ x86_fallback_frame_state (struct _Unwind_Context *context, fs->regs.reg[8].how = REG_SAVED_OFFSET; fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa; fs->retaddr_column = 8; - fs->signal_frame = 1; + + /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn + rather than before it, so don't set fs->signal_frame in that case. + We test whether the ES field of the Status Register is zero. */ + if ((mctx->fpregs.fp_reg_set.fpchip_state.status & 0x80) == 0) + fs->signal_frame = 1; return _URC_NO_REASON; } diff --git a/libgcc/config/sparc/sol2-unwind.h b/libgcc/config/sparc/sol2-unwind.h index 584a9b09666d79d05511ff8c826e2edddcbc303f..4a8c42f590864b2d2ae2f8e1d29f229d82cd37a9 100644 --- a/libgcc/config/sparc/sol2-unwind.h +++ b/libgcc/config/sparc/sol2-unwind.h @@ -403,7 +403,12 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context, fs->retaddr_column = 0; fs->regs.reg[0].how = REG_SAVED_OFFSET; fs->regs.reg[0].loc.offset = (long)shifted_ra_location - new_cfa; - fs->signal_frame = 1; + + /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn + rather than before it, so don't set fs->signal_frame in that case. + We test whether the cexc field of the FSR is zero. */ + if ((mctx->fpregs.fpu_fsr & 0x1f) == 0) + fs->signal_frame = 1; return _URC_NO_REASON; }