Patchwork [C11-atomic] Miscellaneous fixes 6/n

login
register
mail settings
Submitter Joseph S. Myers
Date Oct. 30, 2013, 11:53 p.m.
Message ID <Pine.LNX.4.64.1310302351360.29408@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/287366/
State New
Headers show

Comments

Joseph S. Myers - Oct. 30, 2013, 11:53 p.m.
I've applied this patch to C11-atomic branch to add a testcase (using
pthreads) that atomic compound assignments are actually atomic when
multiple threads are modifying the same variable, to add another
testcase (again using pthreads) that floating-point exceptions from
compound assignments correctly correspond to the final result, to add
a target hook to generate the required floating-point environment code
to achieve this (we don't want compiling normal C code to introduce
libm dependencies, so expand the operations inline or through
libatomic), to add a libatomic function __atomic_feraiseexcept for the
part of this that can be reasonably generic but would be rather long
to expand inline (raising the final exceptions from the atomic
operation), and to implement the target hook for x86 in the case of
SSE.

After this patch, on x86_64-unknown-linux-gnu, c11-atomic-exec-4.c
(tests of atomicity) passes, and the tests in c11-atomic-exec-5.c
(tests of floating-point exceptions) that don't involve long double
pass; the long double tests will require the hook to be filled out for
x87 floating point.

I think the remaining pieces before I merge trunk to the branch then
prepare the _Atomic support for submission for trunk are the x87 parts
of the new hook (which will involve new built-in functions for fnstenv
/ fldenv / fnstsw / fnclex - in the SSE case, the built-in functions
for stmxcsr / ldmxcsr already existed), and effective-target support
for the c11-atomic-exec-5.c testcase so it only runs when <fenv.h> is
present, with all the IEEE exceptions defined, and floating-point
operations do in fact raise exceptions.

gcc:
2013-10-30  Joseph Myers  <joseph@codesourcery.com>

	* target.def (atomic_assign_expand_fenv): New hook.
	* doc/tm.texi.in (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New @hook.
	* doc/tm.texi: Regenerate.
	* targhooks.c (default_atomic_assign_expand_fenv): New function.
	* targhooks.h (default_atomic_assign_expand_fenv): Declare.
	* sync-builtins.def (__atomic_feraiseexcept): New built-in
	function.
	* config/i386/i386.c (ix86_atomic_assign_expand_fenv): New
	function.
	(TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New macro.

gcc/c:
2013-10-30  Joseph Myers  <joseph@codesourcery.com>

	* c-typeck.c (build_atomic_assign): Use
	targetm.atomic_assign_expand_fenv hook.

gcc/fortran:
2013-10-30  Joseph Myers  <joseph@codesourcery.com>

	* f95-lang.c (ATTR_LEAF_LIST): New macro.

gcc/testsuite:
2013-10-30  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/atomic/c11-atomic-exec-4.c,
	gcc.dg/atomic/c11-atomic-exec-5.c: New tests.

libatomic:
2013-10-30  Joseph Myers  <joseph@codesourcery.com>

	* fenv.c: New file.
	* libatomic.map (LIBATOMIC_1.1): New symbol version.  Include
	__atomic_feraiseexcept.
	* configure.ac (libtool_VERSION): Change to 2:0:1.
	(fenv.h): Test for header.
	* Makefile.am (libatomic_la_SOURCES): Add fenv.c.
	* Makefile.in, auto-config.h.in, configure: Regenerate.

Patch

Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(revision 204092)
+++ gcc/fortran/f95-lang.c	(working copy)
@@ -531,7 +531,8 @@  gfc_builtin_function (tree decl)
   return decl;
 }
 
-/* So far we need just these 4 attribute types.  */
+/* So far we need just these 5 attribute types.  */
+#define ATTR_LEAF_LIST			(ECF_LEAF)
 #define ATTR_NOTHROW_LEAF_LIST		(ECF_NOTHROW | ECF_LEAF)
 #define ATTR_NOTHROW_LEAF_MALLOC_LIST	(ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
 #define ATTR_CONST_NOTHROW_LEAF_LIST	(ECF_NOTHROW | ECF_LEAF | ECF_CONST)
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 204092)
+++ gcc/c/c-typeck.c	(working copy)
@@ -11351,8 +11351,16 @@  build_atomic_assign (location_t loc, tree lhs, enu
   add_stmt (func_call);
   params->truncate (0);
 
-  /* TODO if (!integral)  issue feholdexcept (&fenv); */
+  /* Create the expressions for floating-point environment
+     manipulation, if required.  */
+  bool need_fenv = FLOAT_TYPE_P (lhs_type) || FLOAT_TYPE_P (rhs_type);
+  tree hold_call = NULL_TREE, clear_call = NULL_TREE, update_call = NULL_TREE;
+  if (need_fenv)
+    targetm.atomic_assign_expand_fenv (&hold_call, &clear_call, &update_call);
 
+  if (hold_call)
+    add_stmt (hold_call);
+
   /* loop:  */
   add_stmt (loop_label);
 
@@ -11386,7 +11394,8 @@  build_atomic_assign (location_t loc, tree lhs, enu
   SET_EXPR_LOCATION (stmt, loc);
   add_stmt (stmt);
   
-  /* TODO if (!integral) issue feclearexcept (FE_ALL_EXCEPT);  */
+  if (clear_call)
+    add_stmt (clear_call);
 
   /* goto loop;  */
   goto_stmt  = build1 (GOTO_EXPR, void_type_node, loop_decl);
@@ -11396,7 +11405,8 @@  build_atomic_assign (location_t loc, tree lhs, enu
   /* done:  */
   add_stmt (done_label);
 
-  /* TODO If (!integral) issue feupdateenv (&fenv)  */
+  if (update_call)
+    add_stmt (update_call);
 
   /* Finish the compound statement.  */
   compound_stmt = c_end_compound_stmt (loc, compound_stmt, false);
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 204092)
+++ gcc/doc/tm.texi	(working copy)
@@ -11357,3 +11357,7 @@  The default value of this hook is based on target'
 @deftypefn {Target Hook} {unsigned int} TARGET_ATOMIC_ALIGN_FOR_MODE (enum machine_mode @var{mode})
 If defined, this function returns an appropriate alignment in bits for an atomic object of machine_mode @var{mode}.  If 0 is returned then the default alignment for the specified mode is used. 
 @end deftypefn
+
+@deftypefn {Target Hook} void TARGET_ATOMIC_ASSIGN_EXPAND_FENV (tree *@var{hold}, tree *@var{clear}, tree *@var{update})
+ISO C11 requires atomic compound assignments that may raise floating-point exceptions to raise exceptions corresponding to the arithmetic operation whose result was successfully stored in a compare-and-exchange sequence.  This requires code equivalent to calls to @code{feholdexcept}, @code{feclearexcept} and @code{feupdateenv} to be generated at appropriate points in the compare-and-exchange sequence.  This hook should set @code{*@var{hold}} to an expression equivalent to the call to @code{feholdexcept}, @code{*@var{clear}} to an expression equivalent to the call to @code{feclearexcept} and @code{*@var{update}} to an expression equivalent to the call to @code{feupdateenv}.  The three expressions are @code{NULL_TREE} on entry to the hook and may be left as @code{NULL_TREE} if no code is required in a particular place.  The default implementation leaves all three expressions as @code{NULL_TREE}.  The @code{__atomic_feraiseexcept} function from @code{libatomic} may be of use as part of the code generated in @code{*@var{update}}.
+@end deftypefn
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 204092)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -8390,3 +8390,5 @@  and the associated definitions of those functions.
 @hook TARGET_HAS_IFUNC_P
 
 @hook TARGET_ATOMIC_ALIGN_FOR_MODE
+
+@hook TARGET_ATOMIC_ASSIGN_EXPAND_FENV
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 204092)
+++ gcc/target.def	(working copy)
@@ -5135,6 +5135,25 @@  DEFHOOK
  unsigned int, (enum machine_mode mode),
  hook_uint_mode_0)
 
+DEFHOOK
+(atomic_assign_expand_fenv,
+"ISO C11 requires atomic compound assignments that may raise floating-point\
+ exceptions to raise exceptions corresponding to the arithmetic operation\
+ whose result was successfully stored in a compare-and-exchange sequence. \
+ This requires code equivalent to calls to @code{feholdexcept},\
+ @code{feclearexcept} and @code{feupdateenv} to be generated at\
+ appropriate points in the compare-and-exchange sequence.  This hook should\
+ set @code{*@var{hold}} to an expression equivalent to the call to\
+ @code{feholdexcept}, @code{*@var{clear}} to an expression equivalent to\
+ the call to @code{feclearexcept} and @code{*@var{update}} to an expression\
+ equivalent to the call to @code{feupdateenv}.  The three expressions are\
+ @code{NULL_TREE} on entry to the hook and may be left as @code{NULL_TREE}\
+ if no code is required in a particular place.  The default implementation\
+ leaves all three expressions as @code{NULL_TREE}.  The\
+ @code{__atomic_feraiseexcept} function from @code{libatomic} may be of use\
+ as part of the code generated in @code{*@var{update}}.",
+ void, (tree *hold, tree *clear, tree *update),
+ default_atomic_assign_expand_fenv)
 
 /* Leave the boolean fields at the end.  */
 
Index: gcc/sync-builtins.def
===================================================================
--- gcc/sync-builtins.def	(revision 204092)
+++ gcc/sync-builtins.def	(working copy)
@@ -600,3 +600,9 @@  DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_SIGNAL_FENCE,
 		  "__atomic_signal_fence",
 		  BT_FN_VOID_INT, ATTR_NOTHROW_LEAF_LIST)
 
+/* This one is actually a function in libatomic and not expected to be
+   inlined, declared here for convenience of targets generating calls
+   to it.  */
+DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_FERAISEEXCEPT,
+		  "__atomic_feraiseexcept",
+		  BT_FN_VOID_INT, ATTR_LEAF_LIST)
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 204092)
+++ gcc/targhooks.c	(working copy)
@@ -1567,4 +1567,11 @@  default_canonicalize_comparison (int *, rtx *, rtx
 {
 }
 
+/* Default implementation of TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
+
+void
+default_atomic_assign_expand_fenv (tree *, tree *, tree *)
+{
+}
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 204092)
+++ gcc/targhooks.h	(working copy)
@@ -202,3 +202,4 @@  extern void default_asm_output_ident_directive (co
 
 extern enum machine_mode default_cstore_mode (enum insn_code);
 extern bool default_member_type_forces_blk (const_tree, enum machine_mode);
+extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *);
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 204092)
+++ gcc/config/i386/i386.c	(working copy)
@@ -42806,6 +42806,76 @@  ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   return val;
 }
 
+/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
+
+static void
+ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
+{
+  if (!TARGET_80387 && !TARGET_SSE_MATH)
+    return;
+  tree exceptions_var = create_tmp_var (integer_type_node, NULL);
+  if (TARGET_80387)
+    {
+      /* TODO */
+    }
+  if (TARGET_SSE_MATH)
+    {
+      tree mxcsr_orig_var = create_tmp_var (unsigned_type_node, NULL);
+      tree mxcsr_mod_var = create_tmp_var (unsigned_type_node, NULL);
+      tree stmxcsr = ix86_builtins[IX86_BUILTIN_STMXCSR];
+      tree ldmxcsr = ix86_builtins[IX86_BUILTIN_LDMXCSR];
+      tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
+      tree hold_assign_orig = build2 (MODIFY_EXPR, unsigned_type_node,
+				      mxcsr_orig_var, stmxcsr_hold_call);
+      tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
+				  mxcsr_orig_var,
+				  build_int_cst (unsigned_type_node, 0x1f80));
+      hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
+			     build_int_cst (unsigned_type_node, 0xffffffc0));
+      tree hold_assign_mod = build2 (MODIFY_EXPR, unsigned_type_node,
+				     mxcsr_mod_var, hold_mod_val);
+      tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
+      tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
+			      hold_assign_orig, hold_assign_mod);
+      hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
+			 ldmxcsr_hold_call);
+      if (*hold)
+	*hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
+      else
+	*hold = hold_all;
+      tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
+      if (*clear)
+	*clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
+			 ldmxcsr_clear_call);
+      else
+	*clear = ldmxcsr_clear_call;
+      tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
+      tree exceptions_sse = fold_convert (integer_type_node,
+					  stxmcsr_update_call);
+      if (*update)
+	{
+	  tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
+					exceptions_var, exceptions_sse);
+	  tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
+					   exceptions_var, exceptions_mod);
+	  *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
+			    exceptions_assign);
+	}
+      else
+	*update = build2 (MODIFY_EXPR, integer_type_node,
+			  exceptions_var, exceptions_sse);
+      tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
+      *update = build2 (COMPOUND_EXPR, void_type_node, *update,
+			ldmxcsr_update_call);
+    }
+  tree atomic_feraiseexcept
+    = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
+  tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
+						    1, exceptions_var);
+  *update = build2 (COMPOUND_EXPR, void_type_node, *update,
+		    atomic_feraiseexcept_call);
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
@@ -42913,6 +42983,9 @@  ix86_memmodel_check (unsigned HOST_WIDE_INT val)
 #undef TARGET_MEMMODEL_CHECK
 #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
 
+#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
+#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
+
 #ifdef HAVE_AS_TLS
 #undef TARGET_HAVE_TLS
 #define TARGET_HAVE_TLS true
Index: gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c	(revision 0)
@@ -0,0 +1,208 @@ 
+/* Test for _Atomic in C11.  Test that compare-and-exchange is
+   operating properly when operations on the same variable are carried
+   out in two threads.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors -pthread -D_POSIX_C_SOURCE=200809L" } */
+/* { dg-require-effective-target pthread } */
+
+#include <stdint.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ITER_COUNT 10000
+
+static volatile _Atomic bool thread_ready;
+
+/* Generate test code (with NAME used to name functions and variables)
+   for atomic compound assignments to a variable of type LHSTYPE.  The
+   variable is initialized to INIT, then PRE var POST is executed
+   ITER_COUNT times in each of two threads, and the final result
+   should be FINAL.  A function test_main_##NAME is generated that
+   returns nonzero on failure, zero on success.  */
+
+#define TEST_FUNCS(NAME, LHSTYPE, PRE, POST, INIT, FINAL)		\
+									\
+static volatile _Atomic LHSTYPE var_##NAME = (INIT);			\
+									\
+static void *								\
+test_thread_##NAME (void *arg)						\
+{									\
+  thread_ready = true;							\
+  for (int i = 0; i < ITER_COUNT; i++)					\
+    PRE var_##NAME POST;						\
+  return NULL;								\
+}									\
+									\
+static int								\
+test_main_##NAME (void)							\
+{									\
+  thread_ready = false;							\
+  pthread_t thread_id;							\
+  int pret = pthread_create (&thread_id, NULL, test_thread_##NAME,	\
+			     NULL);					\
+  if (pret != 0)							\
+    {									\
+      printf ("pthread_create failed: %d\n", pret);			\
+      return 1;								\
+    }									\
+  while (!thread_ready)							\
+    ;									\
+  for (int i = 0; i < ITER_COUNT; i++)					\
+    PRE var_##NAME POST;						\
+  pthread_join (thread_id, NULL);					\
+  if (var_##NAME != (FINAL))						\
+    {									\
+      printf (#NAME " failed\n");					\
+      return 1;								\
+    }									\
+  else									\
+    {									\
+      printf (#NAME " passed\n");					\
+      return 0;								\
+    }									\
+}
+
+TEST_FUNCS (uint8_add, uint8_t, , += 1, 0, (uint8_t) 20000)
+TEST_FUNCS (uint8_add_3, uint8_t, , += 3, 0, (uint8_t) 60000)
+TEST_FUNCS (uint16_add, uint16_t, , += 1, 0, (uint16_t) 20000)
+TEST_FUNCS (uint16_add_3, uint16_t, , += 3, 0, (uint16_t) 60000)
+TEST_FUNCS (uint32_add, uint32_t, , += 1, 0, (uint32_t) 20000)
+TEST_FUNCS (uint32_add_3, uint32_t, , += 3, 0, (uint32_t) 60000)
+TEST_FUNCS (uint64_add, uint64_t, , += 1, 0, (uint64_t) 20000)
+TEST_FUNCS (uint64_add_3, uint64_t, , += 3, 0, (uint64_t) 60000)
+TEST_FUNCS (uint64_add_neg, uint64_t, , += 1, -10000, (uint64_t) 10000)
+TEST_FUNCS (float_add, float, , += 1, 0, 20000)
+TEST_FUNCS (double_add, double, , += 1, 0, 20000)
+TEST_FUNCS (long_double_add, long double, , += 1, 0, 20000)
+TEST_FUNCS (complex_float_add, _Complex float, , += 1, 0, 20000)
+TEST_FUNCS (complex_double_add, _Complex double, , += 1, 0, 20000)
+TEST_FUNCS (complex_long_double_add, _Complex long double, , += 1, 0, 20000)
+TEST_FUNCS (uint8_postinc, uint8_t, , ++, 0, (uint8_t) 20000)
+TEST_FUNCS (uint16_postinc, uint16_t, , ++, 0, (uint16_t) 20000)
+TEST_FUNCS (uint32_postinc, uint32_t, , ++, 0, (uint32_t) 20000)
+TEST_FUNCS (uint64_postinc, uint64_t, , ++, 0, (uint64_t) 20000)
+TEST_FUNCS (uint64_postinc_neg, uint64_t, , ++, -10000, (uint64_t) 10000)
+TEST_FUNCS (float_postinc, float, , ++, 0, 20000)
+TEST_FUNCS (double_postinc, double, , ++, 0, 20000)
+TEST_FUNCS (long_double_postinc, long double, , ++, 0, 20000)
+TEST_FUNCS (uint8_preinc, uint8_t, ++, , 0, (uint8_t) 20000)
+TEST_FUNCS (uint16_preinc, uint16_t, ++, , 0, (uint16_t) 20000)
+TEST_FUNCS (uint32_preinc, uint32_t, ++, , 0, (uint32_t) 20000)
+TEST_FUNCS (uint64_preinc, uint64_t, ++, , 0, (uint64_t) 20000)
+TEST_FUNCS (uint64_preinc_neg, uint64_t, ++, , -10000, (uint64_t) 10000)
+TEST_FUNCS (float_preinc, float, ++, , 0, 20000)
+TEST_FUNCS (double_preinc, double, ++, , 0, 20000)
+TEST_FUNCS (long_double_preinc, long double, ++, , 0, 20000)
+TEST_FUNCS (uint8_sub, uint8_t, , -= 1, 0, (uint8_t) -20000)
+TEST_FUNCS (uint8_sub_3, uint8_t, , -= 3, 0, (uint8_t) -60000)
+TEST_FUNCS (uint16_sub, uint16_t, , -= 1, 0, (uint16_t) -20000)
+TEST_FUNCS (uint16_sub_3, uint16_t, , -= 3, 0, (uint16_t) -60000)
+TEST_FUNCS (uint32_sub, uint32_t, , -= 1, 0, (uint32_t) -20000)
+TEST_FUNCS (uint32_sub_3, uint32_t, , -= 3, 0, (uint32_t) -60000)
+TEST_FUNCS (uint64_sub, uint64_t, , -= 1, 0, (uint64_t) -20000)
+TEST_FUNCS (uint64_sub_3, uint64_t, , -= 3, 0, (uint64_t) -60000)
+TEST_FUNCS (uint64_sub_neg, uint64_t, , -= 1, 10000, (uint64_t) -10000)
+TEST_FUNCS (float_sub, float, , -= 1, 0, -20000)
+TEST_FUNCS (double_sub, double, , -= 1, 0, -20000)
+TEST_FUNCS (long_double_sub, long double, , -= 1, 0, -20000)
+TEST_FUNCS (complex_float_sub, _Complex float, , -= 1, 0, -20000)
+TEST_FUNCS (complex_double_sub, _Complex double, , -= 1, 0, -20000)
+TEST_FUNCS (complex_long_double_sub, _Complex long double, , -= 1, 0, -20000)
+TEST_FUNCS (uint8_postdec, uint8_t, , --, 0, (uint8_t) -20000)
+TEST_FUNCS (uint16_postdec, uint16_t, , --, 0, (uint16_t) -20000)
+TEST_FUNCS (uint32_postdec, uint32_t, , --, 0, (uint32_t) -20000)
+TEST_FUNCS (uint64_postdec, uint64_t, , --, 0, (uint64_t) -20000)
+TEST_FUNCS (uint64_postdec_neg, uint64_t, , --, 10000, (uint64_t) -10000)
+TEST_FUNCS (float_postdec, float, , --, 0, -20000)
+TEST_FUNCS (double_postdec, double, , --, 0, -20000)
+TEST_FUNCS (long_double_postdec, long double, , --, 0, -20000)
+TEST_FUNCS (uint8_predec, uint8_t, --, , 0, (uint8_t) -20000)
+TEST_FUNCS (uint16_predec, uint16_t, --, , 0, (uint16_t) -20000)
+TEST_FUNCS (uint32_predec, uint32_t, --, , 0, (uint32_t) -20000)
+TEST_FUNCS (uint64_predec, uint64_t, --, , 0, (uint64_t) -20000)
+TEST_FUNCS (uint64_predec_neg, uint64_t, --, , 10000, (uint64_t) -10000)
+TEST_FUNCS (float_predec, float, --, , 0, -20000)
+TEST_FUNCS (double_predec, double, --, , 0, -20000)
+TEST_FUNCS (long_double_predec, long double, --, , 0, -20000)
+TEST_FUNCS (uint8_mul, uint8_t, , *= 3, 1, (uint8_t) 0x81)
+TEST_FUNCS (uint16_mul, uint16_t, , *= 3, 1, (uint16_t) 0x9681)
+TEST_FUNCS (uint32_mul, uint32_t, , *= 3, 1, (uint32_t) 0x62b49681U)
+TEST_FUNCS (uint64_mul, uint64_t, , *= 3, 1, (uint64_t) 0xcd926beb62b49681ULL)
+
+int
+main (void)
+{
+  int ret = 0;
+  ret |= test_main_uint8_add ();
+  ret |= test_main_uint8_add_3 ();
+  ret |= test_main_uint16_add ();
+  ret |= test_main_uint16_add_3 ();
+  ret |= test_main_uint32_add ();
+  ret |= test_main_uint32_add_3 ();
+  ret |= test_main_uint64_add ();
+  ret |= test_main_uint64_add_3 ();
+  ret |= test_main_uint64_add_neg ();
+  ret |= test_main_float_add ();
+  ret |= test_main_double_add ();
+  ret |= test_main_long_double_add ();
+  ret |= test_main_complex_float_add ();
+  ret |= test_main_complex_double_add ();
+  ret |= test_main_complex_long_double_add ();
+  ret |= test_main_uint8_postinc ();
+  ret |= test_main_uint16_postinc ();
+  ret |= test_main_uint32_postinc ();
+  ret |= test_main_uint64_postinc ();
+  ret |= test_main_uint64_postinc_neg ();
+  ret |= test_main_float_postinc ();
+  ret |= test_main_double_postinc ();
+  ret |= test_main_long_double_postinc ();
+  ret |= test_main_uint8_preinc ();
+  ret |= test_main_uint16_preinc ();
+  ret |= test_main_uint32_preinc ();
+  ret |= test_main_uint64_preinc ();
+  ret |= test_main_uint64_preinc_neg ();
+  ret |= test_main_float_preinc ();
+  ret |= test_main_double_preinc ();
+  ret |= test_main_long_double_preinc ();
+  ret |= test_main_uint8_sub ();
+  ret |= test_main_uint8_sub_3 ();
+  ret |= test_main_uint16_sub ();
+  ret |= test_main_uint16_sub_3 ();
+  ret |= test_main_uint32_sub ();
+  ret |= test_main_uint32_sub_3 ();
+  ret |= test_main_uint64_sub ();
+  ret |= test_main_uint64_sub_3 ();
+  ret |= test_main_uint64_sub_neg ();
+  ret |= test_main_float_sub ();
+  ret |= test_main_double_sub ();
+  ret |= test_main_long_double_sub ();
+  ret |= test_main_complex_float_sub ();
+  ret |= test_main_complex_double_sub ();
+  ret |= test_main_complex_long_double_sub ();
+  ret |= test_main_uint8_postdec ();
+  ret |= test_main_uint16_postdec ();
+  ret |= test_main_uint32_postdec ();
+  ret |= test_main_uint64_postdec ();
+  ret |= test_main_uint64_postdec_neg ();
+  ret |= test_main_float_postdec ();
+  ret |= test_main_double_postdec ();
+  ret |= test_main_long_double_postdec ();
+  ret |= test_main_uint8_predec ();
+  ret |= test_main_uint16_predec ();
+  ret |= test_main_uint32_predec ();
+  ret |= test_main_uint64_predec ();
+  ret |= test_main_uint64_predec_neg ();
+  ret |= test_main_float_predec ();
+  ret |= test_main_double_predec ();
+  ret |= test_main_long_double_predec ();
+  ret |= test_main_uint8_mul ();
+  ret |= test_main_uint16_mul ();
+  ret |= test_main_uint32_mul ();
+  ret |= test_main_uint64_mul ();
+  if (ret)
+    abort ();
+  else
+    exit (0);
+}
Index: gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c	(revision 0)
@@ -0,0 +1,540 @@ 
+/* Test for _Atomic in C11.  Test floating-point exceptions for
+   compound assignment are consistent with result (so that if multiple
+   iterations of the compare-and-exchange loop are needed, exceptions
+   get properly cleared).  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors -pthread -D_POSIX_C_SOURCE=200809L" } */
+/* { dg-require-effective-target pthread } */
+
+#include <fenv.h>
+#include <float.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TEST_ALL_EXCEPT (FE_DIVBYZERO		\
+			 | FE_INEXACT		\
+			 | FE_INVALID		\
+			 | FE_OVERFLOW		\
+			 | FE_UNDERFLOW)
+
+#define ITER_COUNT 10000
+
+static volatile _Atomic bool thread_ready, thread_stop;
+
+/* Generate test code (with NAME used to name functions and variables)
+   for atomic compound assignments to a variable of type LHSTYPE.  One
+   thread repeatedly stores the values INIT1 and INIT2 in a variable,
+   while the other repeatedly executes PRE var POST having set
+   floating-point exceptions to BEXC.  If the value of the assignment
+   operation satisfies VALTEST1 (var), the floating-point exceptions
+   should be BEXC | EXC1; otherwise, they should be BEXC | EXC2.  A
+   function test_main_##NAME is generated that returns nonzero on
+   failure, zero on success.  */
+
+#define TEST_FUNCS(NAME, LHSTYPE, PRE, POST, BEXC,			\
+		   INIT1, VALTEST1, EXC1, INIT2, EXC2)			\
+									\
+static volatile _Atomic LHSTYPE var_##NAME;				\
+									\
+static void *								\
+test_thread_##NAME (void *arg)						\
+{									\
+  thread_ready = true;							\
+  while (!thread_stop)							\
+    {									\
+      var_##NAME = (INIT1);						\
+      var_##NAME = (INIT2);						\
+    }									\
+  return NULL;								\
+}									\
+									\
+static int								\
+test_main_##NAME (void)							\
+{									\
+  thread_stop = false;							\
+  thread_ready = false;							\
+  var_##NAME = (INIT1);							\
+  pthread_t thread_id;							\
+  int pret = pthread_create (&thread_id, NULL, test_thread_##NAME,	\
+			     NULL);					\
+  if (pret != 0)							\
+    {									\
+      printf ("pthread_create failed: %d\n", pret);			\
+      return 1;								\
+    }									\
+  int num_1_pass = 0, num_1_fail = 0, num_2_pass = 0, num_2_fail = 0;	\
+  while (!thread_ready)							\
+    ;									\
+  for (int i = 0; i < ITER_COUNT; i++)					\
+    {									\
+      feclearexcept (FE_ALL_EXCEPT);					\
+      feraiseexcept (BEXC);						\
+      LHSTYPE r = (PRE var_##NAME POST);				\
+      int rexc = fetestexcept (TEST_ALL_EXCEPT);			\
+      if (VALTEST1 (r))							\
+	{								\
+	  if (rexc == ((BEXC) | (EXC1)))				\
+	    num_1_pass++;						\
+	  else								\
+	    num_1_fail++;						\
+	  var_##NAME = (INIT2);						\
+	}								\
+      else								\
+	{								\
+	  if (rexc == ((BEXC) | (EXC2)))				\
+	    num_2_pass++;						\
+	  else								\
+	    num_2_fail++;						\
+	  var_##NAME = (INIT1);						\
+	}								\
+    }									\
+  thread_stop = true;							\
+  pthread_join (thread_id, NULL);					\
+  printf (#NAME " (a) %d pass, %d fail; (b) %d pass, %d fail\n",	\
+	  num_1_pass, num_1_fail, num_2_pass, num_2_fail);		\
+  return num_1_fail || num_2_fail;					\
+}
+
+TEST_FUNCS (float_add_invalid, float, , += __builtin_inff (), 0,
+	    0, __builtin_isinf, 0,
+	    -__builtin_inff (), FE_INVALID)
+TEST_FUNCS (float_add_invalid_prev, float, , += __builtin_inff (),
+	    FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW,
+	    0, __builtin_isinf, 0,
+	    -__builtin_inff (), FE_INVALID)
+TEST_FUNCS (float_add_overflow, float, , += FLT_MAX, 0,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_add_overflow_prev, float, , += FLT_MAX, FE_INVALID,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_add_overflow_double, float, , += (double) FLT_MAX, 0,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_add_overflow_long_double, float, , += (long double) FLT_MAX, 0,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_FLT_EPSILON_2(X) ((X) != FLT_EPSILON / 2)
+TEST_FUNCS (float_add_inexact, float, , += FLT_EPSILON / 2, 0,
+	    1.0f, NOT_FLT_EPSILON_2, FE_INEXACT,
+	    0, 0)
+#define NOT_0(X) ((X) != 0)
+TEST_FUNCS (float_add_inexact_int, float, , += 1, 0,
+	    FLT_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+TEST_FUNCS (float_preinc_inexact, float, ++, , 0,
+	    FLT_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+#define NOT_MINUS_1(X) ((X) != -1)
+TEST_FUNCS (float_postinc_inexact, float, , ++, 0,
+	    FLT_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
+	    -1, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS (long_add_float_inexact, long, , += 2 / FLT_EPSILON, 0,
+	    1, NOT_0, FE_INEXACT,
+	    -2 / FLT_EPSILON, 0)
+#endif
+#define REAL_ISINF(X) (__builtin_isinf (__real__ (X)))
+TEST_FUNCS (complex_float_add_overflow, _Complex float, , += FLT_MAX, 0,
+	    FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_sub_invalid, float, , -= __builtin_inff (), 0,
+	    0, __builtin_isinf, 0,
+	    __builtin_inff (), FE_INVALID)
+TEST_FUNCS (float_sub_overflow, float, , -= FLT_MAX, 0,
+	    -FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_MINUS_FLT_EPSILON_2(X) ((X) != -FLT_EPSILON / 2)
+TEST_FUNCS (float_sub_inexact, float, , -= FLT_EPSILON / 2, 0,
+	    -1.0f, NOT_MINUS_FLT_EPSILON_2, FE_INEXACT,
+	    0, 0)
+#define NOT_0(X) ((X) != 0)
+TEST_FUNCS (float_sub_inexact_int, float, , -= 1, 0,
+	    -FLT_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (float_predec_inexact, float, --, , 0,
+	    -FLT_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+#define NOT_1(X) ((X) != 1)
+TEST_FUNCS (float_postdec_inexact, float, , --, 0,
+	    -FLT_EPSILON / 2, NOT_1, FE_INEXACT,
+	    1, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS (long_sub_float_inexact, long, , -= 2 / FLT_EPSILON, 0,
+	    -1, NOT_0, FE_INEXACT,
+	    2 / FLT_EPSILON, 0)
+#endif
+TEST_FUNCS (complex_float_sub_overflow, _Complex float, , -= FLT_MAX, 0,
+	    -FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_mul_invalid, float, , *= __builtin_inff (), 0,
+	    __builtin_inff (), __builtin_isinf, 0,
+	    0, FE_INVALID)
+TEST_FUNCS (float_mul_overflow, float, , *= FLT_MAX, 0,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define IS_0(X) ((X) == 0)
+TEST_FUNCS (float_mul_underflow, float, , *= FLT_MIN, 0,
+	    FLT_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (float_mul_inexact, float, , *= 1 + FLT_EPSILON, 0,
+	    1 + FLT_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_mul_inexact_int, float, , *= 3, 0,
+	    1 + FLT_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS(long_mul_float_inexact, long, , *= 3.0f, 0,
+	   1 + 1 / FLT_EPSILON, NOT_0, FE_INEXACT,
+	   0, 0)
+#endif
+TEST_FUNCS (complex_float_mul_overflow, _Complex float, , *= FLT_MAX, 0,
+	    FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_div_invalid_divbyzero, float, , /= 0.0f, 0,
+	    1, __builtin_isinf, FE_DIVBYZERO,
+	    0, FE_INVALID)
+TEST_FUNCS (float_div_overflow, float, , /= FLT_MIN, 0,
+	    FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_div_underflow, float, , /= FLT_MAX, 0,
+	    FLT_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    FLT_MAX, 0)
+TEST_FUNCS (float_div_inexact, float, , /= 3.0f, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (float_div_inexact_int, float, , /= 3, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (int_div_float_inexact, int, , /= 3.0f, 0,
+	    4, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (complex_float_div_overflow, _Complex float, , /= FLT_MIN, 0,
+	    FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+
+TEST_FUNCS (double_add_invalid, double, , += __builtin_inf (), 0,
+	    0, __builtin_isinf, 0,
+	    -__builtin_inf (), FE_INVALID)
+TEST_FUNCS (double_add_overflow, double, , += DBL_MAX, 0,
+	    DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_add_overflow_long_double, double, , += (long double) DBL_MAX, 0,
+	    DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_DBL_EPSILON_2(X) ((X) != DBL_EPSILON / 2)
+TEST_FUNCS (double_add_inexact, double, , += DBL_EPSILON / 2, 0,
+	    1.0, NOT_DBL_EPSILON_2, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_add_inexact_int, double, , += 1, 0,
+	    DBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+TEST_FUNCS (double_preinc_inexact, double, ++, , 0,
+	    DBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+TEST_FUNCS (double_postinc_inexact, double, , ++, 0,
+	    DBL_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
+	    -1, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS (long_long_add_double_inexact, long long, , += 2 / DBL_EPSILON, 0,
+	    1, NOT_0, FE_INEXACT,
+	    -2 / DBL_EPSILON, 0)
+#endif
+TEST_FUNCS (complex_double_add_overflow, _Complex double, , += DBL_MAX, 0,
+	    DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_sub_invalid, double, , -= __builtin_inf (), 0,
+	    0, __builtin_isinf, 0,
+	    __builtin_inf (), FE_INVALID)
+TEST_FUNCS (double_sub_overflow, double, , -= DBL_MAX, 0,
+	    -DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_MINUS_DBL_EPSILON_2(X) ((X) != -DBL_EPSILON / 2)
+TEST_FUNCS (double_sub_inexact, double, , -= DBL_EPSILON / 2, 0,
+	    -1.0, NOT_MINUS_DBL_EPSILON_2, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_sub_inexact_int, double, , -= 1, 0,
+	    -DBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (double_predec_inexact, double, --, , 0,
+	    -DBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (double_postdec_inexact, double, , --, 0,
+	    -DBL_EPSILON / 2, NOT_1, FE_INEXACT,
+	    1, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS (long_long_sub_double_inexact, long long, , -= 2 / DBL_EPSILON, 0,
+	    -1, NOT_0, FE_INEXACT,
+	    2 / DBL_EPSILON, 0)
+#endif
+TEST_FUNCS (complex_double_sub_overflow, _Complex double, , -= DBL_MAX, 0,
+	    -DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_mul_invalid, double, , *= __builtin_inf (), 0,
+	    __builtin_inf (), __builtin_isinf, 0,
+	    0, FE_INVALID)
+TEST_FUNCS (double_mul_overflow, double, , *= DBL_MAX, 0,
+	    DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_mul_overflow_float, double, , *= FLT_MAX, 0,
+	    DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_mul_underflow, double, , *= DBL_MIN, 0,
+	    DBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (double_mul_inexact, double, , *= 1 + DBL_EPSILON, 0,
+	    1 + DBL_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_mul_inexact_int, double, , *= 3, 0,
+	    1 + DBL_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+#if FLT_EVAL_METHOD == 0
+TEST_FUNCS(long_long_mul_double_inexact, long long, , *= 3.0, 0,
+	   1 + 1 / DBL_EPSILON, NOT_0, FE_INEXACT,
+	   0, 0)
+#endif
+TEST_FUNCS (complex_double_mul_overflow, _Complex double, , *= DBL_MAX, 0,
+	    DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_div_invalid_divbyzero, double, , /= 0.0, 0,
+	    1, __builtin_isinf, FE_DIVBYZERO,
+	    0, FE_INVALID)
+TEST_FUNCS (double_div_overflow, double, , /= DBL_MIN, 0,
+	    DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_div_underflow, double, , /= DBL_MAX, 0,
+	    DBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    DBL_MAX, 0)
+TEST_FUNCS (double_div_inexact, double, , /= 3.0, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (double_div_inexact_int, double, , /= 3, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (int_div_double_inexact, int, , /= 3.0, 0,
+	    4, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (complex_double_div_overflow, _Complex double, , /= DBL_MIN, 0,
+	    DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+
+TEST_FUNCS (long_double_add_invalid, long double, , += __builtin_infl (), 0,
+	    0, __builtin_isinf, 0,
+	    -__builtin_infl (), FE_INVALID)
+TEST_FUNCS (long_double_add_overflow, long double, , += LDBL_MAX, 0,
+	    LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_LDBL_EPSILON_2(X) ((X) != LDBL_EPSILON / 2)
+#if LDBL_MANT_DIG != 106
+TEST_FUNCS (long_double_add_inexact, long double, , += LDBL_EPSILON / 2, 0,
+	    1.0L, NOT_LDBL_EPSILON_2, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_add_inexact_int, long double, , += 1, 0,
+	    LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+TEST_FUNCS (long_double_preinc_inexact, long double, ++, , 0,
+	    LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    -1, 0)
+TEST_FUNCS (long_double_postinc_inexact, long double, , ++, 0,
+	    LDBL_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
+	    -1, 0)
+#endif
+TEST_FUNCS (complex_long_double_add_overflow, _Complex long double, , += LDBL_MAX, 0,
+	    LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_sub_invalid, long double, , -= __builtin_infl (), 0,
+	    0, __builtin_isinf, 0,
+	    __builtin_infl (), FE_INVALID)
+TEST_FUNCS (long_double_sub_overflow, long double, , -= LDBL_MAX, 0,
+	    -LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+#define NOT_MINUS_LDBL_EPSILON_2(X) ((X) != -LDBL_EPSILON / 2)
+#if LDBL_MANT_DIG != 106
+TEST_FUNCS (long_double_sub_inexact, long double, , -= LDBL_EPSILON / 2, 0,
+	    -1.0L, NOT_MINUS_LDBL_EPSILON_2, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_sub_inexact_int, long double, , -= 1, 0,
+	    -LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (long_double_predec_inexact, long double, --, , 0,
+	    -LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
+	    1, 0)
+TEST_FUNCS (long_double_postdec_inexact, long double, , --, 0,
+	    -LDBL_EPSILON / 2, NOT_1, FE_INEXACT,
+	    1, 0)
+#endif
+TEST_FUNCS (complex_long_double_sub_overflow, _Complex long double, , -= LDBL_MAX, 0,
+	    -LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_mul_invalid, long double, , *= __builtin_infl (), 0,
+	    __builtin_infl (), __builtin_isinf, 0,
+	    0, FE_INVALID)
+TEST_FUNCS (long_double_mul_overflow, long double, , *= LDBL_MAX, 0,
+	    LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_mul_overflow_float, long double, , *= FLT_MAX, 0,
+	    LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_mul_overflow_double, long double, , *= DBL_MAX, 0,
+	    LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_mul_underflow, long double, , *= LDBL_MIN, 0,
+	    LDBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    1, 0)
+#if LDBL_MANT_DIG != 106
+TEST_FUNCS (long_double_mul_inexact, long double, , *= 1 + LDBL_EPSILON, 0,
+	    1 + LDBL_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_mul_inexact_int, long double, , *= 3, 0,
+	    1 + LDBL_EPSILON, NOT_0, FE_INEXACT,
+	    0, 0)
+#endif
+TEST_FUNCS (complex_long_double_mul_overflow, _Complex long double, , *= LDBL_MAX, 0,
+	    LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_div_invalid_divbyzero, long double, , /= 0.0L, 0,
+	    1, __builtin_isinf, FE_DIVBYZERO,
+	    0, FE_INVALID)
+TEST_FUNCS (long_double_div_overflow, long double, , /= LDBL_MIN, 0,
+	    LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_div_underflow, long double, , /= LDBL_MAX, 0,
+	    LDBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
+	    LDBL_MAX, 0)
+TEST_FUNCS (long_double_div_inexact, long double, , /= 3.0L, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (long_double_div_inexact_int, long double, , /= 3, 0,
+	    1, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (int_div_long_double_inexact, int, , /= 3.0L, 0,
+	    4, NOT_0, FE_INEXACT,
+	    0, 0)
+TEST_FUNCS (complex_long_double_div_overflow, _Complex long double, , /= LDBL_MIN, 0,
+	    LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
+	    0, 0)
+
+int
+main (void)
+{
+  int ret = 0;
+  ret |= test_main_float_add_invalid ();
+  ret |= test_main_float_add_invalid_prev ();
+  ret |= test_main_float_add_overflow ();
+  ret |= test_main_float_add_overflow_prev ();
+  ret |= test_main_float_add_overflow_double ();
+  ret |= test_main_float_add_overflow_long_double ();
+  ret |= test_main_float_add_inexact ();
+  ret |= test_main_float_add_inexact_int ();
+  ret |= test_main_float_preinc_inexact ();
+  ret |= test_main_float_postinc_inexact ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_add_float_inexact ();
+#endif
+  ret |= test_main_complex_float_add_overflow ();
+  ret |= test_main_float_sub_invalid ();
+  ret |= test_main_float_sub_overflow ();
+  ret |= test_main_float_sub_inexact ();
+  ret |= test_main_float_sub_inexact_int ();
+  ret |= test_main_float_predec_inexact ();
+  ret |= test_main_float_postdec_inexact ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_sub_float_inexact ();
+#endif
+  ret |= test_main_complex_float_sub_overflow ();
+  ret |= test_main_float_mul_invalid ();
+  ret |= test_main_float_mul_overflow ();
+  ret |= test_main_float_mul_underflow ();
+  ret |= test_main_float_mul_inexact ();
+  ret |= test_main_float_mul_inexact_int ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_mul_float_inexact ();
+#endif
+  ret |= test_main_complex_float_mul_overflow ();
+  ret |= test_main_float_div_invalid_divbyzero ();
+  ret |= test_main_float_div_overflow ();
+  ret |= test_main_float_div_underflow ();
+  ret |= test_main_float_div_inexact ();
+  ret |= test_main_float_div_inexact_int ();
+  ret |= test_main_int_div_float_inexact ();
+  ret |= test_main_complex_float_div_overflow ();
+  ret |= test_main_double_add_invalid ();
+  ret |= test_main_double_add_overflow ();
+  ret |= test_main_double_add_overflow_long_double ();
+  ret |= test_main_double_add_inexact ();
+  ret |= test_main_double_add_inexact_int ();
+  ret |= test_main_double_preinc_inexact ();
+  ret |= test_main_double_postinc_inexact ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_long_add_double_inexact ();
+#endif
+  ret |= test_main_complex_double_add_overflow ();
+  ret |= test_main_double_sub_invalid ();
+  ret |= test_main_double_sub_overflow ();
+  ret |= test_main_double_sub_inexact ();
+  ret |= test_main_double_sub_inexact_int ();
+  ret |= test_main_double_predec_inexact ();
+  ret |= test_main_double_postdec_inexact ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_long_sub_double_inexact ();
+#endif
+  ret |= test_main_complex_double_sub_overflow ();
+  ret |= test_main_double_mul_invalid ();
+  ret |= test_main_double_mul_overflow ();
+  ret |= test_main_double_mul_overflow_float ();
+  ret |= test_main_double_mul_underflow ();
+  ret |= test_main_double_mul_inexact ();
+  ret |= test_main_double_mul_inexact_int ();
+#if FLT_EVAL_METHOD == 0
+  ret |= test_main_long_long_mul_double_inexact ();
+#endif
+  ret |= test_main_complex_double_mul_overflow ();
+  ret |= test_main_double_div_invalid_divbyzero ();
+  ret |= test_main_double_div_overflow ();
+  ret |= test_main_double_div_underflow ();
+  ret |= test_main_double_div_inexact ();
+  ret |= test_main_double_div_inexact_int ();
+  ret |= test_main_int_div_double_inexact ();
+  ret |= test_main_complex_double_div_overflow ();
+  ret |= test_main_long_double_add_invalid ();
+  ret |= test_main_long_double_add_overflow ();
+#if LDBL_MANT_DIG != 106
+  ret |= test_main_long_double_add_inexact ();
+  ret |= test_main_long_double_add_inexact_int ();
+  ret |= test_main_long_double_preinc_inexact ();
+  ret |= test_main_long_double_postinc_inexact ();
+#endif
+  ret |= test_main_complex_long_double_add_overflow ();
+  ret |= test_main_long_double_sub_invalid ();
+  ret |= test_main_long_double_sub_overflow ();
+#if LDBL_MANT_DIG != 106
+  ret |= test_main_long_double_sub_inexact ();
+  ret |= test_main_long_double_sub_inexact_int ();
+  ret |= test_main_long_double_predec_inexact ();
+  ret |= test_main_long_double_postdec_inexact ();
+#endif
+  ret |= test_main_complex_long_double_sub_overflow ();
+  ret |= test_main_long_double_mul_invalid ();
+  ret |= test_main_long_double_mul_overflow ();
+  ret |= test_main_long_double_mul_overflow_float ();
+  ret |= test_main_long_double_mul_overflow_double ();
+  ret |= test_main_long_double_mul_underflow ();
+#if LDBL_MANT_DIG != 106
+  ret |= test_main_long_double_mul_inexact ();
+  ret |= test_main_long_double_mul_inexact_int ();
+#endif
+  ret |= test_main_complex_long_double_mul_overflow ();
+  ret |= test_main_long_double_div_invalid_divbyzero ();
+  ret |= test_main_long_double_div_overflow ();
+  ret |= test_main_long_double_div_underflow ();
+  ret |= test_main_long_double_div_inexact ();
+  ret |= test_main_long_double_div_inexact_int ();
+  ret |= test_main_int_div_long_double_inexact ();
+  ret |= test_main_complex_long_double_div_overflow ();
+  if (ret != 0)
+    abort ();
+  else
+    exit (0);
+}
Index: libatomic/configure.ac
===================================================================
--- libatomic/configure.ac	(revision 204092)
+++ libatomic/configure.ac	(working copy)
@@ -148,7 +148,7 @@  AC_SUBST(enable_static)
 AM_MAINTAINER_MODE
 
 # For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=1:0:0
+libtool_VERSION=2:0:1
 AC_SUBST(libtool_VERSION)
 
 # Get target configury.
@@ -165,6 +165,7 @@  CFLAGS="$save_CFLAGS -fno-sync-libcalls $XCFLAGS"
 AC_STDC_HEADERS
 ACX_HEADER_STRING
 GCC_HEADER_STDINT(gstdint.h)
+AC_CHECK_HEADERS([fenv.h])
 
 # Check for common type sizes
 LIBAT_FORALL_MODES([LIBAT_HAVE_INT_MODE])
Index: libatomic/auto-config.h.in
===================================================================
--- libatomic/auto-config.h.in	(revision 204092)
+++ libatomic/auto-config.h.in	(working copy)
@@ -105,6 +105,9 @@ 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
+/* Define to 1 if you have the <fenv.h> header file. */
+#undef HAVE_FENV_H
+
 /* Define to 1 if the target supports __attribute__((ifunc(...))). */
 #undef HAVE_IFUNC
 
Index: libatomic/Makefile.am
===================================================================
--- libatomic/Makefile.am	(revision 204092)
+++ libatomic/Makefile.am	(working copy)
@@ -67,7 +67,8 @@  endif
 libatomic_version_info = -version-info $(libtool_VERSION)
 
 libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script)
-libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c
+libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \
+	fenv.c
 
 SIZEOBJS = load store cas exch fadd fsub fand fior fxor fnand tas
 SIZES = @SIZES@
Index: libatomic/libatomic.map
===================================================================
--- libatomic/libatomic.map	(revision 204092)
+++ libatomic/libatomic.map	(working copy)
@@ -95,3 +95,7 @@  LIBATOMIC_1.0 {
   local:
 	*;
 };
+LIBATOMIC_1.1 {
+  global:
+	__atomic_feraiseexcept;
+} LIBATOMIC_1.0;
Index: libatomic/fenv.c
===================================================================
--- libatomic/fenv.c	(revision 0)
+++ libatomic/fenv.c	(revision 0)
@@ -0,0 +1,72 @@ 
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+   This file is part of the GNU Atomic Library (libatomic).
+
+   Libatomic is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   Libatomic is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+   more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "libatomic_i.h"
+
+#ifdef HAVE_FENV_H
+# include <fenv.h>
+#endif
+
+/* Raise the supported floating-point exceptions from EXCEPTS.  Other
+   bits in EXCEPTS are ignored.  */
+
+void
+__atomic_feraiseexcept (int excepts __attribute__ ((unused)))
+{
+  volatile float r __attribute__ ((unused));
+#ifdef FE_INVALID
+  if (excepts & FE_INVALID)
+  {
+    volatile float zero = 0.0f;
+    r = zero / zero;
+  }
+#endif
+#ifdef FE_DIVBYZERO
+  if (excepts & FE_DIVBYZERO)
+    {
+      volatile float zero = 0.0f;
+      r = 1.0f / zero;
+    }
+#endif
+#ifdef FE_OVERFLOW
+  if (excepts & FE_OVERFLOW)
+    {
+      volatile float max = __FLT_MAX__;
+      r = max * max;
+    }
+#endif
+#ifdef FE_UNDERFLOW
+  if (excepts & FE_UNDERFLOW)
+    {
+      volatile float min = __FLT_MIN__;
+      r = min * min;
+    }
+#endif
+#ifdef FE_INEXACT
+  if (excepts & FE_INEXACT)
+    {
+      volatile float three = 3.0f;
+      r = 1.0f / three;
+    }
+#endif
+}
Index: libatomic/configure
===================================================================
--- libatomic/configure	(revision 204092)
+++ libatomic/configure	(working copy)
@@ -2000,6 +2000,93 @@  rm -f conftest.val
   return $ac_retval
 
 } # ac_fn_c_compute_int
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -11019,7 +11106,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11022 "configure"
+#line 11109 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11125,7 +11212,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11128 "configure"
+#line 11215 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11389,7 +11476,7 @@  fi
 
 
 # For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=1:0:0
+libtool_VERSION=2:0:1
 
 
 # Get target configury.
@@ -11953,7 +12040,19 @@  ac_config_commands="$ac_config_commands gstdint.h"
 
 
 
+for ac_header in fenv.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fenv.h" "ac_cv_header_fenv_h" "$ac_includes_default"
+if test "x$ac_cv_header_fenv_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FENV_H 1
+_ACEOF
 
+fi
+
+done
+
+
 # Check for common type sizes
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 1 byte integer" >&5
Index: libatomic/Makefile.in
===================================================================
--- libatomic/Makefile.in	(revision 204092)
+++ libatomic/Makefile.in	(working copy)
@@ -90,14 +90,14 @@  am__base_list = \
 am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
 LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
 am_libatomic_la_OBJECTS = gload.lo gstore.lo gcas.lo gexch.lo \
-	glfree.lo lock.lo init.lo
+	glfree.lo lock.lo init.lo fenv.lo
 libatomic_la_OBJECTS = $(am_libatomic_la_OBJECTS)
 libatomic_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libatomic_la_LDFLAGS) $(LDFLAGS) -o $@
 libatomic_convenience_la_DEPENDENCIES = $(libatomic_la_LIBADD)
 am__objects_1 = gload.lo gstore.lo gcas.lo gexch.lo glfree.lo lock.lo \
-	init.lo
+	init.lo fenv.lo
 am_libatomic_convenience_la_OBJECTS = $(am__objects_1)
 libatomic_convenience_la_OBJECTS =  \
 	$(am_libatomic_convenience_la_OBJECTS)
@@ -286,7 +286,9 @@  noinst_LTLIBRARIES = libatomic_convenience.la
 @LIBAT_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBAT_BUILD_VERSIONED_SHLIB_TRUE@libatomic_version_dep = libatomic.map-sun
 libatomic_version_info = -version-info $(libtool_VERSION)
 libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script)
-libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c
+libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \
+	fenv.c
+
 SIZEOBJS = load store cas exch fadd fsub fand fior fxor fnand tas
 EXTRA_libatomic_la_SOURCES = $(addsuffix _n.c,$(SIZEOBJS))
 libatomic_la_DEPENDENCIES = $(libatomic_la_LIBADD) $(libatomic_version_dep)
@@ -425,6 +427,7 @@  mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fenv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcas.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gexch.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glfree.Plo@am__quote@