Index: gcc-fsf-trunk-quilt/gcc/config.gcc
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config.gcc	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config.gcc	2013-07-17 00:14:58.230948867 +0100
@@ -3483,7 +3483,7 @@ case "${target}" in
 		;;
 
 	mips*-*-*)
-		supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt synci"
+		supported_defaults="abi arch arch_32 arch_64 float nan tune tune_32 tune_64 divide llsc mips-plt synci"
 
 		case ${with_float} in
 		"" | soft | hard)
@@ -3495,6 +3495,16 @@ case "${target}" in
 			;;
 		esac
 
+		case ${with_nan} in
+		"" | 2008 | legacy)
+			# OK
+			;;
+		*)
+			echo "Unknown NaN encoding used in --with-nan=$with_nan" 1>&2
+			exit 1
+			;;
+		esac
+
 		case ${with_abi} in
 		"" | 32 | o64 | n32 | 64 | eabi)
 			# OK
@@ -3852,7 +3862,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 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 nan mode fpu divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
Index: gcc-fsf-trunk-quilt/gcc/config.in
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config.in	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config.in	2013-07-17 00:14:58.230948867 +0100
@@ -417,6 +417,12 @@
 #endif
 
 
+/* Define if the assembler understands -mnan=. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_NAN
+#endif
+
+
 /* Define if your assembler supports the -no-mul-bug-abort option. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
Index: gcc-fsf-trunk-quilt/gcc/config/mips/linux.h
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/linux.h	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/linux.h	2013-07-17 00:14:58.230948867 +0100
@@ -17,4 +17,9 @@ You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+#define GLIBC_DYNAMIC_LINKER \
+  "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
+
+#undef UCLIBC_DYNAMIC_LINKER
+#define UCLIBC_DYNAMIC_LINKER \
+  "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
Index: gcc-fsf-trunk-quilt/gcc/config/mips/linux64.h
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/linux64.h	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/linux64.h	2013-07-17 00:14:58.230948867 +0100
@@ -22,10 +22,22 @@ along with GCC; see the file COPYING3.  
 #define GNU_USER_LINK_EMULATION64 "elf64%{EB:b}%{EL:l}tsmip"
 #define GNU_USER_LINK_EMULATIONN32 "elf32%{EB:b}%{EL:l}tsmipn32"
 
-#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld.so.1"
-#define GLIBC_DYNAMIC_LINKERN32 "/lib32/ld.so.1"
-#define UCLIBC_DYNAMIC_LINKERN32 "/lib32/ld-uClibc.so.0"
+#define GLIBC_DYNAMIC_LINKER32 \
+  "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
+#define GLIBC_DYNAMIC_LINKER64 \
+  "%{mnan=2008:/lib64/ld-linux-mipsn8.so.1;:/lib64/ld.so.1}"
+#define GLIBC_DYNAMIC_LINKERN32 \
+  "%{mnan=2008:/lib32/ld-linux-mipsn8.so.1;:/lib32/ld.so.1}"
+
+#undef UCLIBC_DYNAMIC_LINKER32
+#define UCLIBC_DYNAMIC_LINKER32 \
+  "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
+#undef UCLIBC_DYNAMIC_LINKER64
+#define UCLIBC_DYNAMIC_LINKER64 \
+  "%{mnan=2008:/lib/ld64-uClibc-mipsn8.so.0;:/lib/ld64-uClibc.so.0}"
+#define UCLIBC_DYNAMIC_LINKERN32 \
+  "%{mnan=2008:/lib32/ld-uClibc-mipsn8.so.0;:/lib32/ld-uClibc.so.0}"
+
 #define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32"
 #define GNU_USER_DYNAMIC_LINKERN32 \
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips-modes.def
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips-modes.def	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips-modes.def	2013-07-17 00:14:58.230948867 +0100
@@ -17,12 +17,7 @@ You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* MIPS has a quirky almost-IEEE format for all its
-   floating point.  */
-RESET_FLOAT_FORMAT (SF, mips_single_format);
-RESET_FLOAT_FORMAT (DF, mips_double_format);
-
-FLOAT_MODE (TF, 16, mips_quad_format);
+FLOAT_MODE (TF, 16, ieee_quad_format);
 
 /* Vector modes.  */
 VECTOR_MODES (INT, 4);        /* V4QI  V2HI      */
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips-opts.h
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips-opts.h	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips-opts.h	2013-07-17 02:36:34.110892228 +0100
@@ -27,6 +27,12 @@ enum mips_code_readable_setting {
   CODE_READABLE_YES
 };
 
+/* Enumerates the setting of the -mabs and -mnan options.  */
+enum mips_ieee_754_setting {
+  MIPS_IEEE_754_LEGACY,
+  MIPS_IEEE_754_2008
+};
+
 /* Enumerates the setting of the -mr10k-cache-barrier option.  */
 enum mips_r10k_cache_barrier_setting {
   R10K_CACHE_BARRIER_NONE,
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips.c
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips.c	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips.c	2013-07-17 01:46:58.480404688 +0100
@@ -8846,6 +8846,12 @@ mips_file_start (void)
     fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n"
 	     "\t.previous\n", TARGET_LONG64 ? 64 : 32);
 
+#ifdef HAVE_AS_NAN
+  /* Record the NaN encoding.  */
+  fprintf (asm_out_file, "\t.nan\t%s\n",
+	   mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
+#endif
+
 #ifdef HAVE_AS_GNU_ATTRIBUTE
   {
     int attr;
@@ -16978,6 +16984,15 @@ mips_option_override (void)
 	}
     }
 
+  /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format
+     for all its floating point.  */
+  if (mips_nan != MIPS_IEEE_754_2008)
+    {
+      REAL_MODE_FORMAT (SFmode) = &mips_single_format;
+      REAL_MODE_FORMAT (DFmode) = &mips_double_format;
+      REAL_MODE_FORMAT (TFmode) = &mips_quad_format;
+    }
+
   /* Make sure that the user didn't turn off paired single support when
      MIPS-3D support is requested.  */
   if (TARGET_MIPS3D
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips.h
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips.h	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips.h	2013-07-17 01:48:07.980896215 +0100
@@ -507,6 +507,12 @@ struct mips_cpu_info {
       if (TARGET_PAIRED_SINGLE_FLOAT)					\
 	builtin_define ("__mips_paired_single_float");			\
 									\
+      if (mips_abs == MIPS_IEEE_754_2008)				\
+	builtin_define ("__mips_abs2008");				\
+									\
+      if (mips_nan == MIPS_IEEE_754_2008)				\
+	builtin_define ("__mips_nan2008");				\
+									\
       if (TARGET_BIG_ENDIAN)						\
 	{								\
 	  builtin_define_std ("MIPSEB");				\
@@ -743,6 +749,7 @@ struct mips_cpu_info {
    --with-abi is ignored if -mabi is specified.
    --with-float is ignored if -mhard-float or -msoft-float are
      specified.
+   --with-nan is ignored if -mnan is specified.
    --with-divide is ignored if -mdivide-traps or -mdivide-breaks are
      specified. */
 #define OPTION_DEFAULT_SPECS \
@@ -754,6 +761,7 @@ struct mips_cpu_info {
   {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
   {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
+  {"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
   {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
   {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \
   {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
@@ -1162,7 +1170,7 @@ struct mips_cpu_info {
 %(subtarget_asm_debugging_spec) \
 %{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \
 %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
-%{mfp32} %{mfp64} \
+%{mfp32} %{mfp64} %{mnan=*} \
 %{mshared} %{mno-shared} \
 %{msym32} %{mno-sym32} \
 %{mtune=*} \
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips.md
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips.md	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips.md	2013-07-17 01:46:40.980224662 +0100
@@ -2711,14 +2711,15 @@
 ;; Do not use the integer abs macro instruction, since that signals an
 ;; exception on -2147483648 (sigh).
 
-;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
-;; invalid; it does not clear their sign bits.  We therefore can't use
-;; abs.fmt if the signs of NaNs matter.
+;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
+;; instruction that treats all NaN inputs as invalid; it does not clear
+;; their sign bit.  We therefore can't use that form if the signs of
+;; NaNs matter.
 
 (define_insn "abs<mode>2"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
 	(abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
-  "!HONOR_NANS (<MODE>mode)"
+  "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
   "abs.<fmt>\t%0,%1"
   [(set_attr "type" "fabs")
    (set_attr "mode" "<UNITMODE>")])
@@ -2793,14 +2794,15 @@
   [(set_attr "alu_type"	"sub")
    (set_attr "mode"	"DI")])
 
-;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
-;; invalid; it does not flip their sign bit.  We therefore can't use
-;; neg.fmt if the signs of NaNs matter.
+;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
+;; instruction that treats all NaN inputs as invalid; it does not flip
+;; their sign bit.  We therefore can't use that form if the signs of
+;; NaNs matter.
 
 (define_insn "neg<mode>2"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
 	(neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
-  "!HONOR_NANS (<MODE>mode)"
+  "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
   "neg.<fmt>\t%0,%1"
   [(set_attr "type" "fneg")
    (set_attr "mode" "<UNITMODE>")])
Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips.opt
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips.opt	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/config/mips/mips.opt	2013-07-17 01:40:55.960243874 +0100
@@ -205,6 +205,34 @@ mfused-madd
 Target Report Mask(FUSED_MADD)
 Generate floating-point multiply-add instructions
 
+mabs=
+Target RejectNegative Joined Enum(mips_abs) Var(mips_abs) Init(MIPS_IEEE_754_LEGACY)
+-mabs=MODE	Select the IEEE 754 ABS/NEG instruction compliance mode
+
+Enum
+Name(mips_abs) Type(int)
+Known compliance modes (for use with the -mabs= option):
+
+EnumValue
+Enum(mips_abs) String(2008) Value(MIPS_IEEE_754_2008)
+
+EnumValue
+Enum(mips_abs) String(legacy) Value(MIPS_IEEE_754_LEGACY)
+
+mnan=
+Target RejectNegative Joined Enum(mips_nan) Var(mips_nan) Init(MIPS_IEEE_754_LEGACY) Condition(HAVE_AS_NAN)
+-mnan=ENCODING	Select the IEEE 754 NaN data encoding
+
+Enum
+Name(mips_nan) Type(int)
+Known encodings (for use with the -mnan= option):
+
+EnumValue
+Enum(mips_nan) String(2008) Value(MIPS_IEEE_754_2008)
+
+EnumValue
+Enum(mips_nan) String(legacy) Value(MIPS_IEEE_754_LEGACY)
+
 mgp32
 Target Report RejectNegative InverseMask(64BIT)
 Use 32-bit general registers
Index: gcc-fsf-trunk-quilt/gcc/configure
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/configure	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/configure	2013-07-17 00:14:58.230948867 +0100
@@ -26019,6 +26019,41 @@ $as_echo "$gcc_cv_ld_mips_personality_re
 $as_echo "#define HAVE_LD_PERSONALITY_RELAXATION 1" >>confdefs.h
 
     fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mnan= support" >&5
+$as_echo_n "checking assembler for -mnan= support... " >&6; }
+if test "${gcc_cv_as_mips_nan+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_mips_nan=no
+  if test x$gcc_cv_as != x; then
+    $as_echo '' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mnan=2008 -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_nan=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_nan" >&5
+$as_echo "$gcc_cv_as_mips_nan" >&6; }
+if test $gcc_cv_as_mips_nan = yes; then
+
+$as_echo "#define HAVE_AS_NAN 1" >>confdefs.h
+
+fi
+    if test x$gcc_cv_as_mips_nan = xno \
+       && test x$with_nan != x; then
+      as_fn_error "Requesting --with-nan= requires assembler support for -mnan=" "$LINENO" 5
+    fi
     ;;
 esac
 
Index: gcc-fsf-trunk-quilt/gcc/configure.ac
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/configure.ac	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/configure.ac	2013-07-17 00:14:58.230948867 +0100
@@ -4168,6 +4168,17 @@ EOF
       [Define if your linker can relax absolute .eh_frame personality
 pointers into PC-relative form.])
     fi
+
+    gcc_GAS_CHECK_FEATURE([-mnan= support],
+      gcc_cv_as_mips_nan,,
+      [-mnan=2008],,,
+      [AC_DEFINE(HAVE_AS_NAN, 1,
+		 [Define if the assembler understands -mnan=.])])
+    if test x$gcc_cv_as_mips_nan = xno \
+       && test x$with_nan != x; then
+      AC_MSG_ERROR(
+	[Requesting --with-nan= requires assembler support for -mnan=])
+    fi
     ;;
 esac
 
Index: gcc-fsf-trunk-quilt/gcc/doc/install.texi
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/doc/install.texi	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/doc/install.texi	2013-07-17 00:14:58.230948867 +0100
@@ -1221,6 +1221,24 @@ ISA for floating-point arithmetics.  You
 enables @option{-msse2} or @samp{avx} which enables @option{-mavx} by default.
 This option is only supported on i386 and x86-64 targets.
 
+@item --with-nan=@var{encoding}
+On MIPS targets, set the default encoding convention to use for the
+special not-a-number (NaN) IEEE 754 floating-point data.  The
+possibilities for @var{encoding} are:
+@table @code
+@item legacy
+Use the legacy encoding, as with the @option{-mnan=legacy} command-line
+option.
+@item 2008
+Use the 754-2008 encoding, as with the @option{-mnan=2008} command-line
+option.
+@end table
+To use this configuration option you must have an assembler version
+installed that supports the @option{-mnan=} command-line option too.
+In the absence of this configuration option the default convention is
+the legacy encoding, as when neither of the @option{-mnan=2008} and
+@option{-mnan=legacy} 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-fsf-trunk-quilt/gcc/doc/invoke.texi
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/doc/invoke.texi	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/doc/invoke.texi	2013-07-17 00:36:17.290923621 +0100
@@ -750,7 +750,8 @@ Objective-C and Objective-C++ Dialects}.
 -mabi=@var{abi}  -mabicalls  -mno-abicalls @gol
 -mshared  -mno-shared  -mplt  -mno-plt  -mxgot  -mno-xgot @gol
 -mgp32  -mgp64  -mfp32  -mfp64  -mhard-float  -msoft-float @gol
--mno-float -msingle-float  -mdouble-float  @gol
+-mno-float  -msingle-float  -mdouble-float @gol
+-mabs=@var{mode}  -mnan=@var{encoding} @gol
 -mdsp  -mno-dsp  -mdspr2  -mno-dspr2 @gol
 -mmcu -mmno-mcu @gol
 -meva -mno-eva @gol
@@ -16313,6 +16314,48 @@ operations.
 Assume that the floating-point coprocessor supports double-precision
 operations.  This is the default.
 
+@item -mabs=2008
+@itemx -mabs=legacy
+@opindex mabs=2008
+@opindex mabs=legacy
+These options control the treatment of the special not-a-number (NaN)
+IEEE 754 floating-point data with the @code{abs.@i{fmt}} and
+@code{neg.@i{fmt}} machine instructions.
+
+By default or when the @option{-mabs=legacy} is used the legacy
+treatment is selected.  In this case these instructions are considered
+arithmetic and avoided where correct operation is required and the
+input operand might be a NaN.  A longer sequence of instructions that
+manipulate the sign bit of floating-point datum manually is used
+instead unless the @option{-ffinite-math-only} option has also been
+specified.
+
+The @option{-mabs=2008} option selects the IEEE 754-2008 treatment.  In
+this case these instructions are considered non-arithmetic and therefore
+operating correctly in all cases, including in particular where the
+input operand is a NaN.  These instructions are therefore always used
+for the respective operations.
+
+@item -mnan=2008
+@itemx -mnan=legacy
+@opindex mnan=2008
+@opindex mnan=legacy
+These options control the encoding of the special not-a-number (NaN)
+IEEE 754 floating-point data.
+
+The @option{-mnan=legacy} option selects the legacy encoding.  In this
+case quiet NaNs (qNaNs) are denoted by the first bit of their trailing
+significand field being 0, whereas signalling NaNs (sNaNs) are denoted
+by the first bit of their trailing significand field being 1.
+
+The @option{-mnan=2008} option selects the IEEE 754-2008 encoding.  In
+this case qNaNs are denoted by the first bit of their trailing
+significand field being 1, whereas sNaNs are denoted by the first bit of
+their trailing significand field being 0.
+
+The default is @option{-mnan=legacy} unless GCC has been configured with
+@option{--with-nan=2008}.
+
 @item -mllsc
 @itemx -mno-llsc
 @opindex mllsc
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabs-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabs-2008.c	2013-07-17 01:13:22.889995188 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 double
+fabs_2008 (double d)
+{
+  return __builtin_fabs (d);
+}
+
+/* { dg-final { scan-assembler "\tabs\.d\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabs-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabs-legacy.c	2013-07-17 01:13:28.390890027 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 double
+fabs_legacy (double d)
+{
+  return __builtin_fabs (d);
+}
+
+/* { dg-final { scan-assembler-not "\tabs\.d\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabsf-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabsf-2008.c	2013-07-17 01:13:31.389925538 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 float
+fabsf_2008 (float f)
+{
+  return __builtin_fabsf (f);
+}
+
+/* { dg-final { scan-assembler "\tabs\.s\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabsf-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fabsf-legacy.c	2013-07-17 01:13:35.389946235 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 float
+fabsf_legacy (float f)
+{
+  return __builtin_fabsf (f);
+}
+
+/* { dg-final { scan-assembler-not "\tabs\.s\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fneg-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fneg-2008.c	2013-07-17 01:13:38.390880503 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 double
+fneg_2008 (double d)
+{
+  return -d;
+}
+
+/* { dg-final { scan-assembler "\tneg\.d\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fneg-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fneg-legacy.c	2013-07-17 01:13:41.890878871 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 double
+fneg_legacy (double d)
+{
+  return -d;
+}
+
+/* { dg-final { scan-assembler-not "\tneg\.d\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fnegf-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fnegf-2008.c	2013-07-17 01:13:45.890961174 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 float
+fnegf_2008 (float f)
+{
+  return -f;
+}
+
+/* { dg-final { scan-assembler "\tneg\.s\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fnegf-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/fnegf-legacy.c	2013-07-17 01:13:49.890831045 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 float
+fnegf_legacy (float f)
+{
+  return -f;
+}
+
+/* { dg-final { scan-assembler-not "\tneg\.s\t" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/mips.exp
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/testsuite/gcc.target/mips/mips.exp	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/mips.exp	2013-07-17 01:12:47.880922358 +0100
@@ -276,8 +276,10 @@ foreach option {
 
 # Add -mfoo= options to mips_option_groups.
 foreach option {
+    abs
     branch-cost
     code-readable
+    nan
     r10k-cache-barrier
     tune
 } {
@@ -705,6 +707,18 @@ proc mips-dg-init {} {
 	    "-msoft-float",
 	    #endif
 
+	    #ifdef __mips_abs2008
+	    "-mabs=2008",
+	    #else
+	    "-mabs=legacy",
+	    #endif
+
+	    #ifdef __mips_nan2008
+	    "-mnan=2008",
+	    #else
+	    "-mnan=legacy",
+	    #endif
+
 	    #if __mips_fpr == 64
 	    "-mfp64",
 	    #else
@@ -826,6 +840,8 @@ proc mips-dg-finish {} {
 #            |                           |
 #         -mfp64                      -mfp32
 #            |                           |
+#         -mabs=2008/-mabs=legacy     <no option>
+#            |                           |
 #         -mhard-float                -msoft-float
 #            |                           |
 #         -mno-sym32                  -msym32
@@ -913,6 +929,8 @@ proc mips-dg-options { args } {
     mips_option_dependency options "-mips3d" "-mpaired-single"
     mips_option_dependency options "-mpaired-single" "-mfp64"
     mips_option_dependency options "-mfp64" "-mhard-float"
+    mips_option_dependency options "-mabs=2008" "-mhard-float"
+    mips_option_dependency options "-mabs=legacy" "-mhard-float"
     mips_option_dependency options "-mrelax-pic-calls" "-mno-plt"
     mips_option_dependency options "-mrelax-pic-calls" "-mabicalls"
     mips_option_dependency options "-mrelax-pic-calls" "-mexplicit-relocs"
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nan-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nan-2008.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+double d = __builtin_nan ("");
+
+/* { dg-final { scan-assembler "\t\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2146959360\n\t.word\t0\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nan-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nan-legacy.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+double d = __builtin_nan ("");
+
+/* { dg-final { scan-assembler "\t\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2146959359\n\t.word\t-1\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nanf-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nanf-2008.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+float f = __builtin_nanf ("");
+
+/* { dg-final { scan-assembler "\t\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2143289344\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nanf-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nanf-legacy.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+float f = __builtin_nanf ("");
+
+/* { dg-final { scan-assembler "\t\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2143289343\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nans-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nans-2008.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+double ds = __builtin_nans ("");
+
+/* { dg-final { scan-assembler "\t\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2146697216\n\t.word\t0\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nans-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nans-legacy.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+double ds = __builtin_nans ("");
+
+/* { dg-final { scan-assembler "\t\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2147483647\n\t.word\t-1\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nansf-2008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nansf-2008.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+float fs = __builtin_nansf ("");
+
+/* { dg-final { scan-assembler "\t\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2141192192\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nansf-legacy.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-fsf-trunk-quilt/gcc/testsuite/gcc.target/mips/nansf-legacy.c	2013-07-17 00:14:58.230948867 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+/* { dg-require-effective-target mips_nan } */
+
+float fs = __builtin_nansf ("");
+
+/* { dg-final { scan-assembler "\t\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\.word\t2147483647\n" } } */
Index: gcc-fsf-trunk-quilt/gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc-fsf-trunk-quilt.orig/gcc/testsuite/lib/target-supports.exp	2013-07-17 00:14:56.000000000 +0100
+++ gcc-fsf-trunk-quilt/gcc/testsuite/lib/target-supports.exp	2013-07-17 00:14:58.230948867 +0100
@@ -975,6 +975,18 @@ proc check_effective_target_mips_eabi { 
     }]
 }
 
+# Return 1 if this is a MIPS target supporting -mnan=.
+# Old versions of binutils may not support this option.
+
+proc check_effective_target_mips_nan { } {
+    if { ![istarget mips*-*-*] } {
+	return 0
+    }
+    return [check_no_compiler_messages mips_nan object {
+	int dummy;
+    } "-mnan=2008"]
+}
+
 # Return 1 if the current multilib does not generate PIC by default.
 
 proc check_effective_target_nonpic { } {
