[Patch 4/17] Implement TARGET_C_EXCESS_PRECISION for m68k
authorJames Greenhalgh <james.greenhalgh@arm.com>
Wed, 23 Nov 2016 17:17:35 +0000 (17:17 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Wed, 23 Nov 2016 17:17:35 +0000 (17:17 +0000)
gcc/

* config/m68k/m68k.c (m68k_excess_precision): New.
(TARGET_C_EXCESS_PRECISION): Define.

From-SVN: r242774

gcc/ChangeLog
gcc/config/m68k/m68k.c

index ab0154b..30fbed6 100644 (file)
@@ -1,5 +1,10 @@
 2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
 
+       * config/m68k/m68k.c (m68k_excess_precision): New.
+       (TARGET_C_EXCESS_PRECISION): Define.
+
+2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
+
        * config/s390/s390.c (s390_excess_precision): New.
        (TARGET_C_EXCESS_PRECISION): Define.
 
index 346c2dc..7bc26bf 100644 (file)
@@ -183,6 +183,8 @@ static rtx m68k_function_arg (cumulative_args_t, machine_mode,
 static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
 static bool m68k_output_addr_const_extra (FILE *, rtx);
 static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
+static enum flt_eval_method
+m68k_excess_precision (enum excess_precision_type);
 \f
 /* Initialize the GCC target structure.  */
 
@@ -323,6 +325,9 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA m68k_output_addr_const_extra
 
+#undef TARGET_C_EXCESS_PRECISION
+#define TARGET_C_EXCESS_PRECISION m68k_excess_precision
+
 /* The value stored by TAS.  */
 #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
 #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
@@ -6534,4 +6539,36 @@ m68k_epilogue_uses (int regno ATTRIBUTE_UNUSED)
              == m68k_fk_interrupt_handler));
 }
 
+
+/* Implement TARGET_C_EXCESS_PRECISION.
+
+   Set the value of FLT_EVAL_METHOD in float.h.  When using 68040 fp
+   instructions, we get proper intermediate rounding, otherwise we
+   get extended precision results.  */
+
+static enum flt_eval_method
+m68k_excess_precision (enum excess_precision_type type)
+{
+  switch (type)
+    {
+      case EXCESS_PRECISION_TYPE_FAST:
+       /* The fastest type to promote to will always be the native type,
+          whether that occurs with implicit excess precision or
+          otherwise.  */
+       return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+      case EXCESS_PRECISION_TYPE_STANDARD:
+      case EXCESS_PRECISION_TYPE_IMPLICIT:
+       /* Otherwise, the excess precision we want when we are
+          in a standards compliant mode, and the implicit precision we
+          provide can be identical.  */
+       if (TARGET_68040 || ! TARGET_68881)
+         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+
+       return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
+      default:
+       gcc_unreachable ();
+    }
+  return FLT_EVAL_METHOD_UNPREDICTABLE;
+}
+
 #include "gt-m68k.h"