diff mbox

[RFC,2/2] MIPS/GCC: IEEE Std 754 NaN interlinking support

Message ID alpine.DEB.2.00.1511261414550.16168@tp.orcam.me.uk
State New
Headers show

Commit Message

Maciej W. Rozycki Nov. 26, 2015, 2:29 p.m. UTC
Implement the GCC interface for IEEE Std 754 NaN interlinking, following 
"MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking" 
<https://dmz-portal.mips.com/wiki/MIPS_ABI_-_NaN_Interlinking> and
the recommendations set out there as follows:

* implement driver and compiler command-line options to control the 
  compliance mode:

  -mieee=strict        -- to select the strict compliance mode enforcing 
                          compliance checks down to the static link and
                          therefore suitable for use cases where IEEE 
                          Std 754 compliance is critical,

  -mieee=relaxed-exec  -- to select the relaxed compliance mode for 
                          executable links only, and the strict 
                          compliance mode for other execution modes,
                          effectively producing objects and shared 
                          libraries still usable with software which is 
                          strictly compliant with IEEE Std 754,

  -mieee=relaxed       -- to select the relaxed compliance mode,

  -mieee=force-relaxed -- to select the relaxed compliance mode, 
                          additionally suppressing warnings from 
                          suspicious static links.

* implement corresponding configuration options to control the default 
  compliance mode:

  --with-ieee=strict       -- to select the strict compliance mode as 
                              the default,

  --with-ieee=relaxed-exec -- to select the relaxed compliance mode for 
                              executable links only as the default.

* implement compiler command-line options to control the NaN compliance 
  mode:

  -mrelaxed-nan=none  -- to output code suitable for use cases where 
                         IEEE Std 754 compliance is critical and 
                         therefore including `.ieee strict; .ieee warn' 
                         in assembly produced,

  -mrelaxed-nan=exec  -- to output code suitable for use cases where 
                         IEEE Std 754 compliance is not required, 
                         however still usable with software which is 
                         strictly compliant with IEEE Std 754, and 
                         therefore including `.ieee strict; .ieee 
                         nowarn' in assembly produced,

  -mrelaxed-nan=all   -- to output code suitable for use cases where 
                         IEEE Std 754 compliance is never required and 
                         therefore including `.ieee relaxed; .ieee 
                         nowarn' in assembly produced,

  -mrelaxed-nan=force -- same as `-mrelaxed-nan=all' to simplify 
                         handling in specs.

There is one issue with this change in that a `-mrelaxed-nan=' option 
supplied on a GCC command line does not override the default set with a 
`--with-ieee=' option.  This is because the driver stuffs the initial 
`-mieee=' option produced with OPTION_DEFAULT_SPECS *after* any 
`-mrelaxed-nan=' option provided by the user.  I take it as a driver bug
as user-supplied options are supposed to be placed last on the command 
line so as to allow any earlier or implied options to be overridden.
Therefore I am not going to address this problem with this change, the
user is advised to use `-mieee=' options wherever possible anyway.

	gcc/
	* flags.h (set_fast_math_flags): New prototype.
	* opts.c (set_fast_math_flags): Export.
	* common/config/mips/mips-common.c (mips_handle_option): Handle 
	`-mieee=' options.
	* config/mips/mips-opts.h (mips_relaxed_nan_setting): New enum.
	(mips_ieee_setting): Likewise.
	* config/mips/mips.h (OPTION_DEFAULT_SPECS): Add `ieee'.
	(ASM_SPEC): Handle `-mieee=' and `-mrelaxed-nan=' options.
	(LINK_SPEC): Likewise.
	[!HAVE_AS_IEEE] (HAVE_AS_IEEE): New macro.
	* config/mips/mips.c (mips_file_start): Handle `-mrelaxed-nan=' 
	options.
	* config/mips/mips.opt (mrelaxed-nan=, mieee=): New options.
	* doc/install.texi (Configuration): Add `--with-ieee=' options.
	* doc/invoke.texi (Option Summary) <MIPS Options>: Add 
	`-mrelaxed-nan=' and `-mieee=' options.
	(MIPS Options): Likewise.
	* config.gcc <mips*-*-*>: Handle `--with-ieee=' options.
	(all_defaults): Add `ieee'.
	* configure.ac <mips*-*-*>: Check for GAS `-mieee=' support.
	* config.in: Regenerate.
	* configure: Regenerate.

	gcc/testsuite/
	* gcc.target/mips/ieee-force-relaxed.c: New test.
	* gcc.target/mips/ieee-relaxed-exec.c: New test.
	* gcc.target/mips/ieee-relaxed.c: New test.
	* gcc.target/mips/ieee-strict.c: New test.
	* gcc.target/mips/relaxed-nan-all.c: New test.
	* gcc.target/mips/relaxed-nan-exec.c: New test.
	* gcc.target/mips/relaxed-nan-force.c: New test.
	* gcc.target/mips/relaxed-nan-none.c: New test.
---
gcc-mips-nan-interlink.diff
diff mbox

Patch

Index: gcc/gcc/common/config/mips/mips-common.c
===================================================================
--- gcc.orig/gcc/common/config/mips/mips-common.c	2015-11-24 00:05:16.049937677 +0000
+++ gcc/gcc/common/config/mips/mips-common.c	2015-11-24 00:06:10.355508364 +0000
@@ -51,6 +51,25 @@  mips_handle_option (struct gcc_options *
       opts->x_target_flags &= ~MASK_FLOAT64;
       return true;
 
+    case OPT_mieee_:
+      switch (opts->x_mips_ieee)
+	{
+	case MIPS_IEEE_STRICT:
+	  opts->x_mips_relaxed_nan = MIPS_RELAXED_NAN_NONE;
+	  set_fast_math_flags (opts, 0);
+	  break;
+
+	case MIPS_IEEE_RELAXED_EXEC:
+	  opts->x_mips_relaxed_nan = MIPS_RELAXED_NAN_EXEC;
+	  break;
+
+	case MIPS_IEEE_RELAXED:
+	case MIPS_IEEE_FORCE_RELAXED:
+	  opts->x_mips_relaxed_nan = MIPS_RELAXED_NAN_ALL;
+	  break;
+	}
+      return true;
+
     default:
       return true;
     }
Index: gcc/gcc/config.gcc
===================================================================
--- gcc.orig/gcc/config.gcc	2015-11-24 00:05:16.222718728 +0000
+++ gcc/gcc/config.gcc	2015-11-24 00:06:10.425289924 +0000
@@ -3937,7 +3937,7 @@  case "${target}" in
 		;;
 
 	mips*-*-*)
-		supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci"
+		supported_defaults="abi arch arch_32 arch_64 float fpu ieee nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci"
 
 		case ${with_float} in
 		"" | soft | hard)
@@ -3959,6 +3959,16 @@  case "${target}" in
 			;;
 		esac
 
+		case ${with_ieee} in
+		"" | relaxed-exec | strict)
+			# OK
+			;;
+		*)
+			echo "Unknown IEEE Std 754 conformance mode used in --with-ieee=$with_ieee" 1>&2
+			exit 1
+			;;
+		esac
+
 		case ${with_nan} in
 		"" | 2008 | legacy)
 			# OK
@@ -4500,7 +4510,7 @@  case ${target} in
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu ieee nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
Index: gcc/gcc/config.in
===================================================================
--- gcc.orig/gcc/config.in	2015-11-24 00:05:16.865396949 +0000
+++ gcc/gcc/config.in	2015-11-24 00:06:10.477192219 +0000
@@ -369,6 +369,12 @@ 
 #endif
 
 
+/* Define if the assembler understands -mieee=. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_IEEE
+#endif
+
+
 /* Define if your assembler supports the Sun syntax for cmov. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_IX86_CMOV_SUN_SYNTAX
Index: gcc/gcc/config/mips/mips-opts.h
===================================================================
--- gcc.orig/gcc/config/mips/mips-opts.h	2015-11-24 00:05:17.155042702 +0000
+++ gcc/gcc/config/mips/mips-opts.h	2015-11-24 00:06:10.621715475 +0000
@@ -34,6 +34,21 @@  enum mips_ieee_754_setting {
   MIPS_IEEE_754_2008
 };
 
+/* Enumerates the setting of the -mrelaxed-nan option.  */
+enum mips_relaxed_nan_setting {
+  MIPS_RELAXED_NAN_NONE,
+  MIPS_RELAXED_NAN_EXEC,
+  MIPS_RELAXED_NAN_ALL
+};
+
+/* Enumerates the setting of the -mieee option.  */
+enum mips_ieee_setting {
+  MIPS_IEEE_STRICT,
+  MIPS_IEEE_RELAXED_EXEC,
+  MIPS_IEEE_RELAXED,
+  MIPS_IEEE_FORCE_RELAXED
+};
+
 /* Enumerates the setting of the -mr10k-cache-barrier option.  */
 enum mips_r10k_cache_barrier_setting {
   R10K_CACHE_BARRIER_NONE,
Index: gcc/gcc/config/mips/mips.c
===================================================================
--- gcc.orig/gcc/config/mips/mips.c	2015-11-24 00:05:17.424994956 +0000
+++ gcc/gcc/config/mips/mips.c	2015-11-24 00:06:10.842710769 +0000
@@ -9251,6 +9251,12 @@  mips_file_start (void)
     fprintf (asm_out_file, "\t.nan\t%s\n",
 	     mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
 
+  /* Record the NaN encoding conformance mode.  */
+  if (HAVE_AS_IEEE)
+    fprintf (asm_out_file, "\t.ieee\t%s\n\t.ieee\t%s\n",
+	     mips_relaxed_nan == MIPS_RELAXED_NAN_ALL ? "relaxed" : "strict",
+	     mips_relaxed_nan == MIPS_RELAXED_NAN_NONE ? "warn" : "nowarn");
+
 #ifdef HAVE_AS_DOT_MODULE
   /* Record the FP ABI.  See below for comments.  */
   if (TARGET_NO_FLOAT)
Index: gcc/gcc/config/mips/mips.h
===================================================================
--- gcc.orig/gcc/config/mips/mips.h	2015-11-24 00:05:17.873930007 +0000
+++ gcc/gcc/config/mips/mips.h	2015-11-24 00:06:11.196887035 +0000
@@ -824,6 +824,7 @@  struct mips_cpu_info {
    --with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are
      specified.
    --with-nan is ignored if -mnan is specified.
+   --with-ieee is ignored if -mieee is specified.
    --with-fp-32 is ignored if -msoft-float, -msingle-float or -mfp are specified.
    --with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg
      or -mno-odd-spreg are specified.
@@ -840,6 +841,7 @@  struct mips_cpu_info {
   {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
   {"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \
   {"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
+  {"ieee", "%{!mieee=*:-mieee=%(VALUE)}" }, \
   {"fp_32", "%{" OPT_ARCH32 \
 	    ":%{!msoft-float:%{!msingle-float:%{!mfp*:-mfp%(VALUE)}}}}" }, \
   {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \
@@ -1325,6 +1327,10 @@  struct mips_cpu_info {
 %{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \
 %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
 %{mfp32} %{mfpxx} %{mfp64} %{mnan=*} \
+%{mieee=strict|mrelaxed-nan=none:-mieee=strict -mieee=warn} \
+%{mieee=relaxed-exec|mrelaxed-nan=exec:-mieee=strict -mieee=nowarn} \
+%{mieee=relaxed|mieee=force-relaxed|mrelaxed-nan=all|mrelaxed-nan=force: \
+  -mieee=relaxed -mieee=nowarn} \
 %{modd-spreg} %{mno-odd-spreg} \
 %{mshared} %{mno-shared} \
 %{msym32} %{mno-sym32} \
@@ -1352,7 +1358,12 @@  FP_ASM_SPEC "\
 #ifndef LINK_SPEC
 #define LINK_SPEC "\
 %(endian_spec) \
-%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32*} %{mips64*}" \
+%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32*} %{mips64*} \
+%{mieee=strict|mrelaxed-nan=none:--ieee=strict} \
+%{mieee=relaxed-exec|mrelaxed-nan=exec: \
+  %{r|shared:--ieee=strict;:--ieee=relaxed}} \
+%{mieee=relaxed|mrelaxed-nan=all:--ieee=relaxed} \
+%{mieee=force-relaxed|mrelaxed-nan=force:--ieee=relaxed --ieee=nowarn} " \
 LINK_SHARED_SPEC " \
 %(subtarget_link_spec)"
 #endif  /* LINK_SPEC defined */
@@ -3103,6 +3114,10 @@  while (0)
 #define HAVE_AS_NAN 0
 #endif
 
+#ifndef HAVE_AS_IEEE
+#define HAVE_AS_IEEE 0
+#endif
+
 #ifndef USED_FOR_TARGET
 /* Information about ".set noFOO; ...; .set FOO" blocks.  */
 struct mips_asm_switch {
Index: gcc/gcc/config/mips/mips.opt
===================================================================
--- gcc.orig/gcc/config/mips/mips.opt	2015-11-24 00:05:18.121655495 +0000
+++ gcc/gcc/config/mips/mips.opt	2015-11-24 00:06:12.155385760 +0000
@@ -227,6 +227,46 @@  Enum(mips_ieee_754_value) String(2008) V
 EnumValue
 Enum(mips_ieee_754_value) String(legacy) Value(MIPS_IEEE_754_LEGACY)
 
+mrelaxed-nan=
+Target Report RejectNegative Joined Enum(mips_relaxed_nan_value) Var(mips_relaxed_nan) Init(MIPS_RELAXED_NAN_NONE)
+-mrelaxed-nan=CLASS	Relax IEEE Std 754 compliance for NaN encodings.
+
+Enum
+Name(mips_relaxed_nan_value) Type(int)
+Known NaN relaxing settings (for use with the -mrelaxed-nan= option):
+
+EnumValue
+Enum(mips_relaxed_nan_value) String(none) Value(MIPS_RELAXED_NAN_NONE)
+
+EnumValue
+Enum(mips_relaxed_nan_value) String(exec) Value(MIPS_RELAXED_NAN_EXEC)
+
+EnumValue
+Enum(mips_relaxed_nan_value) String(all) Value(MIPS_RELAXED_NAN_ALL)
+
+EnumValue
+Enum(mips_relaxed_nan_value) String(force) Value(MIPS_RELAXED_NAN_ALL)
+
+mieee=
+Target Report RejectNegative Joined Enum(mips_ieee_value) Var(mips_ieee) Init(MIPS_IEEE_STRICT)
+-mieee=MODE	Set the IEEE Std 754 compliance mode.
+
+Enum
+Name(mips_ieee_value) Type(int)
+Known IEEE Std 754 compliance settings (for use with the -mieee= option):
+
+EnumValue
+Enum(mips_ieee_value) String(strict) Value(MIPS_IEEE_STRICT)
+
+EnumValue
+Enum(mips_ieee_value) String(relaxed-exec) Value(MIPS_IEEE_RELAXED_EXEC)
+
+EnumValue
+Enum(mips_ieee_value) String(relaxed) Value(MIPS_IEEE_RELAXED)
+
+EnumValue
+Enum(mips_ieee_value) String(force-relaxed) Value(MIPS_IEEE_FORCE_RELAXED)
+
 mgp32
 Target Report RejectNegative InverseMask(64BIT)
 Use 32-bit general registers.
Index: gcc/gcc/configure
===================================================================
--- gcc.orig/gcc/configure	2015-11-24 00:05:18.340215927 +0000
+++ gcc/gcc/configure	2015-11-24 00:08:04.388933865 +0000
@@ -26994,6 +26994,41 @@  fi
        && test x$with_nan != x; then
       as_fn_error "Requesting --with-nan= requires assembler support for -mnan=" "$LINENO" 5
     fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mieee= support" >&5
+$as_echo_n "checking assembler for -mieee= support... " >&6; }
+if test "${gcc_cv_as_mips_ieee+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_mips_ieee=no
+  if test x$gcc_cv_as != x; then
+    $as_echo '' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mieee=relaxed -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_mips_ieee=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_ieee" >&5
+$as_echo "$gcc_cv_as_mips_ieee" >&6; }
+if test $gcc_cv_as_mips_ieee = yes; then
+
+$as_echo "#define HAVE_AS_IEEE 1" >>confdefs.h
+
+fi
+    if test x$gcc_cv_as_mips_ieee = xno \
+       && test x$with_ieee != x; then
+      as_fn_error "Requesting --with-ieee= requires assembler support for -mieee=" "$LINENO" 5
+    fi
     ;;
     s390*-*-*)
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .gnu_attribute support" >&5
Index: gcc/gcc/configure.ac
===================================================================
--- gcc.orig/gcc/configure.ac	2015-11-24 00:05:18.821833294 +0000
+++ gcc/gcc/configure.ac	2015-11-24 00:06:12.826806774 +0000
@@ -4551,6 +4551,17 @@  pointers into PC-relative form.])
       AC_MSG_ERROR(
 	[Requesting --with-nan= requires assembler support for -mnan=])
     fi
+
+    gcc_GAS_CHECK_FEATURE([-mieee= support],
+      gcc_cv_as_mips_ieee,,
+      [-mieee=relaxed],,,
+      [AC_DEFINE(HAVE_AS_IEEE, 1,
+		 [Define if the assembler understands -mieee=.])])
+    if test x$gcc_cv_as_mips_ieee = xno \
+       && test x$with_ieee != x; then
+      AC_MSG_ERROR(
+	[Requesting --with-ieee= requires assembler support for -mieee=])
+    fi
     ;;
     s390*-*-*)
     gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
Index: gcc/gcc/doc/install.texi
===================================================================
--- gcc.orig/gcc/doc/install.texi	2015-11-24 00:05:19.098399059 +0000
+++ gcc/gcc/doc/install.texi	2015-11-24 00:06:13.003205800 +0000
@@ -1308,6 +1308,23 @@  In the absence of this configuration opt
 the legacy encoding, as when neither of the @option{-mnan=2008} and
 @option{-mnan=legacy} command-line options has been used.
 
+@item --with-ieee=@var{mode}
+On MIPS targets, set the default IEEE Std 754 compliance mode.  The
+possibilities for @var{mode} are:
+@table @code
+@item strict
+Use the strict compliance mode, as with the @option{-mieee=strict}
+command-line option.
+@item relaxed-exec
+Use the relaxed compliance mode for executables, as with the
+@option{-mieee=relaxed-exec} command-line option.
+@end table
+To use this configuration option you must have an assembler version
+installed that supports the @option{-mieee=} command-line option too.
+In the absence of this configuration option the default compliance
+mode is strict, as when none of the @option{-mieee=} command-line
+options has been used.
+
 @item --with-divide=@var{type}
 Specify how the compiler should generate code for checking for
 division by zero.  This option is only supported on the MIPS target.
Index: gcc/gcc/doc/invoke.texi
===================================================================
--- gcc.orig/gcc/doc/invoke.texi	2015-11-24 00:05:19.480659158 +0000
+++ gcc/gcc/doc/invoke.texi	2015-11-24 00:06:13.127814395 +0000
@@ -793,7 +793,8 @@  Objective-C and Objective-C++ Dialects}.
 -mgp32  -mgp64  -mfp32  -mfpxx  -mfp64  -mhard-float  -msoft-float @gol
 -mno-float  -msingle-float  -mdouble-float @gol
 -modd-spreg -mno-odd-spreg @gol
--mabs=@var{mode}  -mnan=@var{encoding} @gol
+-mabs=@var{mode}  -mnan=@var{encoding}  -mrelaxed-nan=@var{class} @gol
+-mieee=@var{mode} @gol
 -mdsp  -mno-dsp  -mdspr2  -mno-dspr2 @gol
 -mmcu -mmno-mcu @gol
 -meva -mno-eva @gol
@@ -17644,6 +17645,79 @@  their trailing significand field being 0
 The default is @option{-mnan=legacy} unless GCC has been configured with
 @option{--with-nan=2008}.
 
+@item -mrelaxed-nan=none
+@itemx -mrelaxed-nan=exec
+@itemx -mrelaxed-nan=all
+@itemx -mrelaxed-nan=force
+@opindex mrelaxed-nan=none
+@opindex mrelaxed-nan=exec
+@opindex mrelaxed-nan=all
+@opindex mrelaxed-nan=force
+These options control the IEEE Std 754 compliance mode for the special
+not-a-number (NaN) floating-point data encodings.  See
+@option{-mnan=2008} for the details of the encodings available.  These
+options not only affect compilation, but the assembly and link stages
+as well.
+
+The @option{-mrelaxed-nan=none} option selects the strict NaN compliance
+mode in which the semantics defined by IEEE Std 754 for ``signalling''
+NaN and ``quiet'' NaN input data is always strictly followed.
+
+The @option{-mrelaxed-nan=exec} option selects the relaxed NaN
+compliance mode for executables in which the semantics defined by IEEE
+Std 754 for ``signalling'' NaN and ``quiet'' NaN input data is not
+strictly followed.  The semantics is still strictly followed in shared
+libraries.
+
+The @option{-mrelaxed-nan=all} option selects the relaxed NaN compliance
+mode in which the semantics defined by IEEE Std 754 ``signalling'' NaN
+and ``quiet'' NaN input data is never strictly followed.
+
+The @option{-mrelaxed-nan=force} option is the same as
+@option{-mrelaxed-nan=all} except that it suppresses any warnings the
+linker might otherwise produce where based on objects being linked it
+considers the compliance mode selected suspicious.
+
+The default is @option{-mrelaxed-nan=none}; see the description of the
+@option{-mieee=strict} option and its counterparts however for how they
+affect it.
+
+@item -mieee=strict
+@itemx -mieee=relaxed-exec
+@itemx -mieee=relaxed
+@itemx -mieee=force-relaxed
+@opindex mieee=strict
+@opindex mieee=relaxed-exec
+@opindex mieee=relaxed
+@opindex mieee=force-relaxed
+These options provide group control over the IEEE Std 754 compliance
+mode.  They not only affect compilation, but the assembly and link
+stages as well.
+
+The @option{-mieee=strict} option selects the strict compliance mode in
+which the semantics defined by IEEE Std 754 is always strictly followed.
+This option implies @option{-fno-fast-math} and
+@option{-mrelaxed-nan=none}.
+
+The @option{-mieee=relaxed-exec} option selects the relaxed compliance
+mode for executables in which the semantics defined by IEEE Std 754 is
+not strictly followed.  The semantics is still strictly followed in
+shared libraries.  This option implies @option{-mrelaxed-nan=exec}.
+
+The @option{-mieee=relaxed} option selects the NaN compliance mode in
+which the semantics defined by IEEE Std 754 is never strictly followed.
+This option implies @option{-mrelaxed-nan=all}.
+
+The @option{-mieee=force-relaxed} option selects the NaN compliance mode
+in which the semantics defined by IEEE Std 754 is never strictly
+followed and any warnings are suppressed that the linker might otherwise
+produce where based on objects being linked it considers the compliance
+mode selected suspicious.  This option implies
+@option{-mrelaxed-nan=all}.
+
+The default is @option{-mieee=strict} unless GCC has been configured
+with @option{--with-ieee=relaxed-exec}.
+
 @item -mllsc
 @itemx -mno-llsc
 @opindex mllsc
Index: gcc/gcc/flags.h
===================================================================
--- gcc.orig/gcc/flags.h	2015-11-24 00:05:19.559801006 +0000
+++ gcc/gcc/flags.h	2015-11-24 00:06:13.182905249 +0000
@@ -28,6 +28,9 @@  extern const char *const debug_type_name
 extern void strip_off_ending (char *, int);
 extern int base_of_path (const char *path, const char **base_out);
 
+/* Set all the flags that -ffast-math and -fno-fast-math imply.  */
+extern void set_fast_math_flags (struct gcc_options *opts, int set);
+
 /* Return true iff flags are set as if -ffast-math.  */
 extern bool fast_math_flags_set_p (const struct gcc_options *);
 extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
Index: gcc/gcc/opts.c
===================================================================
--- gcc.orig/gcc/opts.c	2015-11-24 00:05:19.841002714 +0000
+++ gcc/gcc/opts.c	2015-11-24 00:06:13.390844069 +0000
@@ -193,7 +193,6 @@  static void set_debug_level (enum debug_
 			     const char *arg, struct gcc_options *opts,
 			     struct gcc_options *opts_set,
 			     location_t loc);
-static void set_fast_math_flags (struct gcc_options *opts, int set);
 static void decode_d_option (const char *arg, struct gcc_options *opts,
 			     location_t loc, diagnostic_context *dc);
 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
@@ -2222,7 +2221,7 @@  set_Wstrict_aliasing (struct gcc_options
 
 /* The following routines are useful in setting all the flags that
    -ffast-math and -fno-fast-math imply.  */
-static void
+void
 set_fast_math_flags (struct gcc_options *opts, int set)
 {
   if (!opts->frontend_set_flag_unsafe_math_optimizations)
Index: gcc/gcc/testsuite/gcc.target/mips/ieee-force-relaxed.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/ieee-force-relaxed.c	2015-11-24 00:06:14.707891892 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mieee=force-relaxed" } */
+/* { dg-final { scan-assembler "\t\\.ieee\trelaxed\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/ieee-relaxed-exec.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/ieee-relaxed-exec.c	2015-11-24 00:06:14.883748642 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mieee=relaxed-exec" } */
+/* { dg-final { scan-assembler "\t\\.ieee\tstrict\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/ieee-relaxed.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/ieee-relaxed.c	2015-11-24 00:06:15.131021325 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mieee=relaxed" } */
+/* { dg-final { scan-assembler "\t\\.ieee\trelaxed\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/ieee-strict.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/ieee-strict.c	2015-11-24 00:06:15.356777227 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mieee=strict" } */
+/* { dg-final { scan-assembler "\t\\.ieee\tstrict\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\twarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-all.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-all.c	2015-11-24 00:06:15.729173230 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mrelaxed-nan=all" } */
+/* { dg-final { scan-assembler "\t\\.ieee\trelaxed\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-exec.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-exec.c	2015-11-24 00:06:15.985771907 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mrelaxed-nan=exec" } */
+/* { dg-final { scan-assembler "\t\\.ieee\tstrict\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-force.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-force.c	2015-11-24 00:06:16.259984540 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mrelaxed-nan=force" } */
+/* { dg-final { scan-assembler "\t\\.ieee\trelaxed\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\tnowarn\n" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-none.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/relaxed-nan-none.c	2015-11-24 00:06:18.881842871 +0000
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mrelaxed-nan=none" } */
+/* { dg-final { scan-assembler "\t\\.ieee\tstrict\n" } } */
+/* { dg-final { scan-assembler "\t\\.ieee\twarn\n" } } */