public inbox for libc-ports@sourceware.org
 help / color / mirror / Atom feed
* [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
@ 2013-08-22 23:53 Maciej W. Rozycki
  2013-08-23  0:58 ` Rich Felker
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-08-22 23:53 UTC (permalink / raw)
  To: libc-ports, libc-alpha; +Cc: Doug Gilmore

Hi,

 This change is sent as an RFC only at this time, because it relies on 
Linux kernel functionality that has not been integrated upstream yet.  
The minimum kernel version required set in this change has been therefore 
artificially fixed at 3.11.0, the current version number of the Linux 
kernel.  This requirement will be adjusted appropriately in the final 
version of this change.  Feedback is welcome on this implementation so 
that it can be swiftly integrated once the required kernel support has 
been put in place.

 Also I would appreciate if we could keep sysdeps/generic/ldconfig.h cache 
flag slots 0x0c00, 0x0d00 and 0x0e00 reserved from now on and until this 
change has been finally accepted.

 As many of you have been aware it has been a long practice for software 
using IEEE 754 floating-point arithmetic run on MIPS processors to use an 
encoding of Not-a-Number (NaN) data different to one used by software run 
on other processors.  And as of IEEE 754-2008 revision [1] this encoding 
does not follow one recommended in the standard, as specified in section 
6.2.1, where it is stated that quiet NaNs should have the first bit (d1) 
of their significand set to 1 while signalling NaNs should have that bit 
set to 0, but MIPS software interprets the two bits in the opposite 
manner.

 As from revision 3.50 [2][3] the MIPS Architecture provides for 
processors that support the IEEE 754-2008 preferred NaN encoding format.  
As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
are incompatible to each other, tools will have to provide support for the 
two formats to help people avoid using incompatible binary modules.  Here 
is the glibc part.

 The change is comprised of two functional groups of features, both of 
which are required for correct support.

1. Dynamic linker support.

   To enforce the NaN encoding requirement in dynamic linking a new ELF 
   file header flag has been defined.  This flag is set for 2008-NaN 
   shared modules and executables and clear for legacy-NaN ones.  The 
   dynamic linker silently ignores any incompatible modules it encounters 
   in dependency processing.

   To avoid unnecessary processing of incompatible modules in the presence 
   of a shared module cache, a set of new cache flags has been defined to 
   mark 2008-NaN modules for the three ABIs supported.  Changes to
   sysdeps/unix/sysv/linux/mips/readelflib.c have been made following 
   an earlier code quality suggestion made here:

   http://sourceware.org/ml/libc-ports/2009-03/msg00036.html

   and are therefore a little bit more extensive than the minimum 
   required.

   Finally a new name has been defined for the dynamic linker so that 
   2008-NaN and legacy-NaN binaries can coexist on a single system that 
   supports dual-mode operation and that a legacy dynamic linker that 
   does not support verifying the 2008-NaN ELF file header flag is not 
   chosen to interpret a 2008-NaN binary by accident.

2. Floating environment support.

   IEEE 754-2008 features are controlled in the Floating-Point Control and 
   Status (FCSR) register and updates are needed to floating environment 
   support so that the 2008-NaN flag is set correctly and the kernel 
   default, inferred from the 2008-NaN ELF file header flag at the time 
   an executable is loaded, respected.

 As the NaN encoding format is a property of GCC code generation that is 
both a user-selected GCC configuration default and can be overridden with 
GCC options, code that needs to know what NaN encoding standard it has 
been configured for checks for the __mips_nan2008 macro that is defined 
internally by GCC whenever the 2008-NaN mode has been selected.  This mode 
is determined at the glibc configuration time and therefore a few 
consistency checks have been added to catch cases where compilation flags 
have been overridden by the user.

 The 2008 NaN set of features relies on kernel support as the in-kernel 
floating-point emulator needs to be aware of the NaN encoding used even on 
hard-float processors and configure the FPU context according to the value 
of the 2008 NaN ELF file header flag of the executable being started.  
Therefore the minimum version supported has been adjusted where glibc is 
built for the 2008 NaN encoding.  Legacy NaN encoding support is 
unaffected, older kernel versions remain supported.

 Preliminary mips-linux-gnu testing with the o32, n64 and n32 ABIs, legacy 
NaN showed no regressions.

 Questions, comments?

 References:

[1] "IEEE Standard for Floating-Point Arithmetic", IEEE Computer Society, 
    IEEE Std 754-2008, 29 August 2008

[2] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
    MIPS32 Architecture", MIPS Technologies, Inc., Document Number: 
    MD00082, Revision 3.50, September 20, 2012

[3] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
    MIPS64 Architecture", MIPS Technologies, Inc., Document Number: 
    MD00083, Revision 3.50, September 20, 2012

2012-08-22  Maciej W. Rozycki  <macro@codesourcery.com>

	ChangeLog:
	* config.h.in (HAVE_MIPS_NAN2008): New macro.
	* elf/elf.h (EF_MIPS_NAN2008): Likewise.
	* sysdeps/generic/ldconfig.h (FLAG_MIPS_LIB32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN64_NAN2008): Likewise.
	* elf/cache.c (print_entry): Handle the new cache flags.

	ports/ChangeLog.mips
	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NAN2008): New macro.
	(elf_machine_matches_host): Reject objects that use a different
	NaN encoding convention.
	* sysdeps/mips/fpu_control.h: Document IEEE 754-2008 feature 
	control bits.
	(_FPU_ABS2008, _FPU_NAN2008): New macros.
	(_FPU_RESERVED): Clear bits #20 and #19.
	(_FPU_DEFAULT) [__mips_nan2008]: Set bit #18.
	(_FPU_IEEE) [__mips_nan2008]: Likewise.
	* sysdeps/mips/mips64/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/mips/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID): 
	Define 2008 NaN encoding values.
	* sysdeps/mips/fpu/fesetenv.c (fesetenv): Do not allow to flip
	the _FPU_NAN2008 bit.
	* sysdeps/unix/sysv/linux/mips/readelflib.c (process_elf_file):
	Handle 2008-NaN libraries.
	* sysdeps/mips/shlib-versions [HAVE_MIPS_NAN2008]: Set 
	ld=ld-linux-mipsn8.so.1.
	* sysdeps/mips/configure.in: Define HAVE_MIPS_NAN2008 if the
	2008 NaN encoding is used.
	* sysdeps/unix/sysv/linux/mips/configure.in: Set 
	arch_minimum_kernel to 3.11.0 if 2008 NaN encoding is used.
	* sysdeps/mips/configure: Regenerate.
	* sysdeps/unix/sysv/linux/mips/configure: Regenerate.

  Maciej

glibc-mips-nan2008.diff
Index: glibc-fsf-trunk-quilt/config.h.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/config.h.in	2013-08-20 15:18:10.000000000 +0100
+++ glibc-fsf-trunk-quilt/config.h.in	2013-08-22 10:32:05.447640501 +0100
@@ -241,4 +241,8 @@
 /* The pt_chown binary is being built and used by grantpt.  */
 #undef HAVE_PT_CHOWN
 
+/* ports/sysdeps/mips/configure.in  */
+/* Define if using the IEEE 754-2008 NaN encoding on the MIPS target.  */
+#undef HAVE_MIPS_NAN2008
+
 #endif
Index: glibc-fsf-trunk-quilt/elf/cache.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/cache.c	2013-05-21 00:20:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/cache.c	2013-08-22 10:32:05.447640501 +0100
@@ -105,6 +105,15 @@ print_entry (const char *lib, int flag, 
     case FLAG_ARM_LIBSF:
       fputs (",soft-float", stdout);
       break;
+    case FLAG_MIPS_LIB32_NAN2008:
+      fputs (",nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN32_NAN2008:
+      fputs (",N32,nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN64_NAN2008:
+      fputs (",64bit,nan2008", stdout);
+      break;
     case 0:
       break;
     default:
Index: glibc-fsf-trunk-quilt/elf/elf.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/elf.h	2013-06-26 18:42:44.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/elf.h	2013-08-22 10:32:05.447640501 +0100
@@ -1383,6 +1383,7 @@ typedef struct
 #define EF_MIPS_64BIT_WHIRL	16
 #define EF_MIPS_ABI2		32
 #define EF_MIPS_ABI_ON32	64
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
 #define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
 
 /* Legal values for MIPS architecture level.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure	2013-08-22 10:32:05.447640501 +0100
@@ -1,3 +1,163 @@
 # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/mips.
 
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+if test x$libc_cv_mips_nan2008 = xyes; then
+  $as_echo "#define HAVE_MIPS_NAN2008 1" >>confdefs.h
+
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure.in	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in	2013-08-22 10:32:05.447640501 +0100
@@ -4,3 +4,12 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the
 dnl No MIPS GCC supports accessing static and hidden symbols in an
 dnl position independent way.
 dnl AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+if test x$libc_cv_mips_nan2008 = xyes; then
+  AC_DEFINE(HAVE_MIPS_NAN2008)
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-machine.h	2013-05-30 00:49:41.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h	2013-08-22 10:32:05.447640501 +0100
@@ -73,6 +73,16 @@ do { if ((l)->l_info[DT_MIPS (RLD_MAP)])
        (ElfW(Addr)) (r); \
    } while (0)
 
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+#ifdef __mips_nan2008
+# define ELF_MACHINE_NAN2008 EF_MIPS_NAN2008
+#else
+# define ELF_MACHINE_NAN2008 0
+#endif
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute_used__
 elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
@@ -83,6 +93,10 @@ elf_machine_matches_host (const ElfW(Ehd
     return 0;
 #endif
 
+  /* Don't link 2008-NaN and legacy-NaN objects together.  */
+  if ((ehdr->e_flags & EF_MIPS_NAN2008) != ELF_MACHINE_NAN2008)
+    return 0;
+
   switch (ehdr->e_machine)
     {
     case EM_MIPS:
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu/fesetenv.c	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c	2013-08-22 10:32:05.447640501 +0100
@@ -25,15 +25,16 @@ fesetenv (const fenv_t *envp)
 {
   fpu_control_t cw;
 
-  /* Read first current state to flush fpu pipeline.  */
   _FPU_GETCW (cw);
 
   if (envp == FE_DFL_ENV)
-    _FPU_SETCW (_FPU_DEFAULT);
+    cw = _FPU_DEFAULT;
   else if (envp == FE_NOMASK_ENV)
-    _FPU_SETCW (_FPU_IEEE);
+    cw = _FPU_IEEE;
   else
-    _FPU_SETCW (envp->__fp_control_register);
+    cw = (cw & _FPU_NAN2008) | (envp->__fp_control_register & ~_FPU_NAN2008);
+
+  _FPU_SETCW (cw);
 
   /* Success.  */
   return 0;
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu_control.h	2013-08-21 07:35:44.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h	2013-08-22 10:32:05.447640501 +0100
@@ -29,7 +29,9 @@
  *           available for MIPS III and newer.
  * 23     -> Condition bit
  * 22-21  -> reserved for architecture implementers
- * 20-18  -> reserved (read as 0, write with 0)
+ * 20     -> reserved (read as 0, write with 0)
+ * 19     -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable
+ * 18     -> IEEE 754-2008 recommended NaN encoding enable
  * 17     -> cause bit for unimplemented operation
  * 16     -> cause bit for invalid exception
  * 15     -> cause bit for division by zero exception
@@ -79,22 +81,33 @@ extern fpu_control_t __fpu_control;
 /* flush denormalized numbers to zero */
 #define _FPU_FLUSH_TZ   0x1000000
 
+/* IEEE 754-2008 compliance control.  */
+#define _FPU_ABS2008    0x80000
+#define _FPU_NAN2008    0x40000
+
 /* rounding control */
 #define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
 #define _FPU_RC_ZERO    0x1
 #define _FPU_RC_UP      0x2
 #define _FPU_RC_DOWN    0x3
 
-#define _FPU_RESERVED 0xfe9c0000  /* Reserved bits in cw */
+#define _FPU_RESERVED 0xfe840000  /* Reserved bits in cw, incl NAN2008.  */
 
 
 /* The fdlibm code requires strict IEEE double precision arithmetic,
    and no interrupts for exceptions, rounding to nearest.  */
-
+#ifdef __mips_nan2008
+#define _FPU_DEFAULT  0x00040000
+#else
 #define _FPU_DEFAULT  0x00000000
+#endif
 
-/* IEEE:  same as above, but exceptions */
+/* IEEE: same as above, but exceptions.  */
+#ifdef __mips_nan2008
+#define _FPU_IEEE     0x00040F80
+#else
 #define _FPU_IEEE     0x00000F80
+#endif
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-08-20 15:18:10.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-08-22 10:32:05.447640501 +0100
@@ -24,15 +24,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/shlib-versions	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions	2013-08-22 10:32:05.447640501 +0100
@@ -3,7 +3,11 @@ mips.*-.*-linux.*	libm=6			GLIBC_2.0 GLI
 # Working mips versions were never released between 2.0 and 2.2.
 mips.*-.*-linux.*	libc=6			GLIBC_2.0 GLIBC_2.2
 
+%ifdef HAVE_MIPS_NAN2008
+mips.*-.*-linux.*	ld=ld-linux-mipsn8.so.1	GLIBC_2.0 GLIBC_2.2
+%else
 mips.*-.*-linux.*	ld=ld.so.1		GLIBC_2.0 GLIBC_2.2
+%endif
 mips.*-.*-linux.*	libdl=2			GLIBC_2.0 GLIBC_2.2
 
 mips.*-.*-linux.*	libresolv=2		GLIBC_2.0 GLIBC_2.2
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-08-20 15:18:10.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-08-22 10:32:05.447640501 +0100
@@ -21,15 +21,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure	2013-08-22 10:39:07.378109215 +0100
@@ -137,4 +137,165 @@ case "$prefix" in
   esac
 esac
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    arch_minimum_kernel=3.11.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-08-22 10:35:13.417814395 +0100
@@ -75,4 +75,16 @@ case "$prefix" in
   esac
 esac
 
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    arch_minimum_kernel=3.11.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-08-22 10:32:05.447640501 +0100
@@ -18,11 +18,27 @@
 
 #include <ldconfig.h>
 
-/* Redefine the cache ID for new ABIs; o32 keeps using the generic check.  */
-#if _MIPS_SIM == _ABI64
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
-#elif _MIPS_SIM == _ABIN32
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+
+/* Redefine the cache ID for new ABIs and 2008 NaN support; legacy o32
+   keeps using the generic check.  */
+#ifdef __mips_nan2008
+# if _MIPS_SIM == _ABIO32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32_NAN2008 | FLAG_ELF_LIBC6)
+# endif
+#else
+# if _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+# endif
 #endif
 
 #ifdef _DL_CACHE_DEFAULT_ID
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-05-16 18:17:13.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-08-22 10:32:05.447640501 +0100
@@ -33,19 +33,32 @@ process_elf_file (const char *file_name,
 		  unsigned int *osversion, char **soname, void *file_contents,
 		  size_t file_length)
 {
-  ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+  union
+    {
+      Elf64_Ehdr *eh64;
+      Elf32_Ehdr *eh32;
+      ElfW(Ehdr) *eh;
+    }
+  elf_header;
   int ret;
 
-  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+  elf_header.eh = file_contents;
+  if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32)
     {
-      Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
-
       ret = process_elf32_file (file_name, lib, flag, osversion, soname,
 				file_contents, file_length);
+      if (!ret)
+	{
+	  Elf32_Word flags = elf_header.eh32->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
 
-      /* n32 libraries are always libc.so.6+.  */
-      if (!ret && (elf32_header->e_flags & EF_MIPS_ABI2) != 0)
-	*flag = FLAG_MIPS64_LIBN32|FLAG_ELF_LIBC6;
+	  /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN.  */
+	  if ((flags & EF_MIPS_ABI2) != 0)
+	    *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008
+		     : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6;
+	  else if (nan2008)
+	    *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6;
+	}
     }
   else
     {
@@ -53,7 +66,13 @@ process_elf_file (const char *file_name,
 				file_contents, file_length);
       /* n64 libraries are always libc.so.6+.  */
       if (!ret)
-	*flag = FLAG_MIPS64_LIBN64|FLAG_ELF_LIBC6;
+	{
+	  Elf64_Word flags = elf_header.eh64->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
+
+	  *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008
+		   : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6;
+	}
     }
 
   return ret;
Index: glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/sysdeps/generic/ldconfig.h	2013-05-21 00:20:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h	2013-08-22 10:32:05.447640501 +0100
@@ -21,24 +21,27 @@
 
 #include <stdint.h>
 
-#define FLAG_ANY		-1
-#define FLAG_TYPE_MASK		0x00ff
-#define FLAG_LIBC4		0x0000
-#define FLAG_ELF		0x0001
-#define FLAG_ELF_LIBC5		0x0002
-#define FLAG_ELF_LIBC6		0x0003
-#define FLAG_REQUIRED_MASK	0xff00
-#define FLAG_SPARC_LIB64	0x0100
-#define FLAG_IA64_LIB64		0x0200
-#define FLAG_X8664_LIB64	0x0300
-#define FLAG_S390_LIB64		0x0400
-#define FLAG_POWERPC_LIB64	0x0500
-#define FLAG_MIPS64_LIBN32	0x0600
-#define FLAG_MIPS64_LIBN64	0x0700
-#define FLAG_X8664_LIBX32	0x0800
-#define FLAG_ARM_LIBHF		0x0900
-#define FLAG_AARCH64_LIB64	0x0a00
-#define FLAG_ARM_LIBSF		0x0b00
+#define FLAG_ANY			-1
+#define FLAG_TYPE_MASK			0x00ff
+#define FLAG_LIBC4			0x0000
+#define FLAG_ELF			0x0001
+#define FLAG_ELF_LIBC5			0x0002
+#define FLAG_ELF_LIBC6			0x0003
+#define FLAG_REQUIRED_MASK		0xff00
+#define FLAG_SPARC_LIB64		0x0100
+#define FLAG_IA64_LIB64			0x0200
+#define FLAG_X8664_LIB64		0x0300
+#define FLAG_S390_LIB64			0x0400
+#define FLAG_POWERPC_LIB64		0x0500
+#define FLAG_MIPS64_LIBN32		0x0600
+#define FLAG_MIPS64_LIBN64		0x0700
+#define FLAG_X8664_LIBX32		0x0800
+#define FLAG_ARM_LIBHF			0x0900
+#define FLAG_AARCH64_LIB64		0x0a00
+#define FLAG_ARM_LIBSF			0x0b00
+#define FLAG_MIPS_LIB32_NAN2008		0x0c00
+#define FLAG_MIPS64_LIBN32_NAN2008	0x0d00
+#define FLAG_MIPS64_LIBN64_NAN2008	0x0e00
 
 /* Name of auxiliary cache.  */
 #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-22 23:53 [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support Maciej W. Rozycki
@ 2013-08-23  0:58 ` Rich Felker
  2013-08-23  1:41   ` Maciej W. Rozycki
  2013-08-23  3:46 ` Rich Felker
  2013-08-23 15:26 ` Joseph S. Myers
  2 siblings, 1 reply; 19+ messages in thread
From: Rich Felker @ 2013-08-23  0:58 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, Aug 23, 2013 at 12:52:43AM +0100, Maciej W. Rozycki wrote:
>  As many of you have been aware it has been a long practice for software 
> using IEEE 754 floating-point arithmetic run on MIPS processors to use an 
> encoding of Not-a-Number (NaN) data different to one used by software run 
> on other processors.  And as of IEEE 754-2008 revision [1] this encoding 
> does not follow one recommended in the standard, as specified in section 
> 6.2.1, where it is stated that quiet NaNs should have the first bit (d1) 
> of their significand set to 1 while signalling NaNs should have that bit 
> set to 0, but MIPS software interprets the two bits in the opposite 
> manner.
> 
>  As from revision 3.50 [2][3] the MIPS Architecture provides for 
> processors that support the IEEE 754-2008 preferred NaN encoding format.  
> As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
> are incompatible to each other, tools will have to provide support for the 
> two formats to help people avoid using incompatible binary modules.  Here 
> is the glibc part.

Can you elaborate on why you think this is an ABI issue? IMO it's just
s runtime issue unless you're considering raw floating point data
written to disk. In any case this seems like such a small issue that
it should just be silently fixed, rather than adding huge amounts of
ABI ugliness.

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  0:58 ` Rich Felker
@ 2013-08-23  1:41   ` Maciej W. Rozycki
  2013-08-23  1:57     ` Rich Felker
  2013-08-23  4:10     ` Rich Felker
  0 siblings, 2 replies; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-08-23  1:41 UTC (permalink / raw)
  To: Rich Felker; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, 23 Aug 2013, Rich Felker wrote:

> >  As many of you have been aware it has been a long practice for software 
> > using IEEE 754 floating-point arithmetic run on MIPS processors to use an 
> > encoding of Not-a-Number (NaN) data different to one used by software run 
> > on other processors.  And as of IEEE 754-2008 revision [1] this encoding 
> > does not follow one recommended in the standard, as specified in section 
> > 6.2.1, where it is stated that quiet NaNs should have the first bit (d1) 
> > of their significand set to 1 while signalling NaNs should have that bit 
> > set to 0, but MIPS software interprets the two bits in the opposite 
> > manner.
> > 
> >  As from revision 3.50 [2][3] the MIPS Architecture provides for 
> > processors that support the IEEE 754-2008 preferred NaN encoding format.  
> > As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
> > are incompatible to each other, tools will have to provide support for the 
> > two formats to help people avoid using incompatible binary modules.  Here 
> > is the glibc part.
> 
> Can you elaborate on why you think this is an ABI issue? IMO it's just
> s runtime issue unless you're considering raw floating point data
> written to disk. In any case this seems like such a small issue that
> it should just be silently fixed, rather than adding huge amounts of
> ABI ugliness.

 To give you a small example this:

double foo = __builtin_nan ("");

will compile to a different data pattern with opposite (qNaN vs sNaN) 
semantics depending on the NaN encoding mode selected in the compiler.  
Modules built with different NaN encodings are therefore not compatible, 
either at the link or at the load time, as applicable.  LD (from binutils) 
and ld.so take care of the link-time and the load-time integrity check, 
respectively.

 Additionally hardware has to be configured to match the encoding selected 
and executables that require a NaN encoding that is not supported by a 
given piece of hardware have to be rejected -- execve(2) is supposed to 
return in that case, which may only be handled by the kernel.  Please note 
that neither the legacy-NaN nor the 2008-NaN encoding is mandatory in the 
MIPS architecture; MIPS FPU hardware at the implementer's discretion may 
support either or both.

 I hope this answers your question.  Any further concerns?

  Maciej

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  1:41   ` Maciej W. Rozycki
@ 2013-08-23  1:57     ` Rich Felker
  2013-08-23  3:11       ` pinskia
  2013-08-23  4:10     ` Rich Felker
  1 sibling, 1 reply; 19+ messages in thread
From: Rich Felker @ 2013-08-23  1:57 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, Aug 23, 2013 at 02:41:21AM +0100, Maciej W. Rozycki wrote:
> On Fri, 23 Aug 2013, Rich Felker wrote:
> 
> > >  As many of you have been aware it has been a long practice for software 
> > > using IEEE 754 floating-point arithmetic run on MIPS processors to use an 
> > > encoding of Not-a-Number (NaN) data different to one used by software run 
> > > on other processors.  And as of IEEE 754-2008 revision [1] this encoding 
> > > does not follow one recommended in the standard, as specified in section 
> > > 6.2.1, where it is stated that quiet NaNs should have the first bit (d1) 
> > > of their significand set to 1 while signalling NaNs should have that bit 
> > > set to 0, but MIPS software interprets the two bits in the opposite 
> > > manner.
> > > 
> > >  As from revision 3.50 [2][3] the MIPS Architecture provides for 
> > > processors that support the IEEE 754-2008 preferred NaN encoding format.  
> > > As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
> > > are incompatible to each other, tools will have to provide support for the 
> > > two formats to help people avoid using incompatible binary modules.  Here 
> > > is the glibc part.
> > 
> > Can you elaborate on why you think this is an ABI issue? IMO it's just
> > s runtime issue unless you're considering raw floating point data
> > written to disk. In any case this seems like such a small issue that
> > it should just be silently fixed, rather than adding huge amounts of
> > ABI ugliness.
> 
>  To give you a small example this:
> 
> double foo = __builtin_nan ("");
> 
> will compile to a different data pattern with opposite (qNaN vs sNaN) 
> semantics depending on the NaN encoding mode selected in the compiler.  
> Modules built with different NaN encodings are therefore not compatible, 

They are compatible except in the area of subtle exception-raising
semantics that GCC *DOES NOT GET CORRECT ANYWAY*. GCC is full of
incorrect optimizations that cause the exception flags to be wrong.
Until that's fixed, I don't see why this issue is so important to
merit flagging object files build with different modes as having an
incompatible ABI. The semantics are slightly different, but the type
sizes and the way they're passed are all the same, and programs that
don't use the GCC extension __builtin_nan() or the NAN macro from
math.h, or writing raw float values to/from disk, are completely
unaffected.

> either at the link or at the load time, as applicable.  LD (from binutils) 
> and ld.so take care of the link-time and the load-time integrity check, 
> respectively.
> 
>  Additionally hardware has to be configured to match the encoding selected 
> and executables that require a NaN encoding that is not supported by a 
> given piece of hardware have to be rejected -- execve(2) is supposed to 
> return in that case, which may only be handled by the kernel.  Please note 
> that neither the legacy-NaN nor the 2008-NaN encoding is mandatory in the 
> MIPS architecture; MIPS FPU hardware at the implementer's discretion may 
> support either or both.
> 
>  I hope this answers your question.  Any further concerns?

I'm just opposed to introducing massive complexity and spurious linker
errors for the sake of something that shouldn't affect most programs,
and where the only affected programs already had wrong behavior due to
GCC's lack of proper support for floating point exception and
rounding-mode semantics. Signaling NANs are an obscure, optional
feature almost nobody uses, and if you're not intentionally using
them, you don't care if computations with NANs raise spurious
exceptions or not (especially since the exception was already raised
when you first generated the NAN, unless you loaded a NAN explicitly
via the NAN macro or strtod("NAN", 0)...

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  1:57     ` Rich Felker
@ 2013-08-23  3:11       ` pinskia
  2013-08-23  3:38         ` Rich Felker
  0 siblings, 1 reply; 19+ messages in thread
From: pinskia @ 2013-08-23  3:11 UTC (permalink / raw)
  To: Rich Felker; +Cc: Maciej W. Rozycki, libc-ports, libc-alpha, Doug Gilmore



On Aug 22, 2013, at 6:57 PM, Rich Felker <dalias@aerifal.cx> wrote:

> On Fri, Aug 23, 2013 at 02:41:21AM +0100, Maciej W. Rozycki wrote:
>> On Fri, 23 Aug 2013, Rich Felker wrote:
>> 
>>>> As many of you have been aware it has been a long practice for software 
>>>> using IEEE 754 floating-point arithmetic run on MIPS processors to use an 
>>>> encoding of Not-a-Number (NaN) data different to one used by software run 
>>>> on other processors.  And as of IEEE 754-2008 revision [1] this encoding 
>>>> does not follow one recommended in the standard, as specified in section 
>>>> 6.2.1, where it is stated that quiet NaNs should have the first bit (d1) 
>>>> of their significand set to 1 while signalling NaNs should have that bit 
>>>> set to 0, but MIPS software interprets the two bits in the opposite 
>>>> manner.
>>>> 
>>>> As from revision 3.50 [2][3] the MIPS Architecture provides for 
>>>> processors that support the IEEE 754-2008 preferred NaN encoding format.  
>>>> As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
>>>> are incompatible to each other, tools will have to provide support for the 
>>>> two formats to help people avoid using incompatible binary modules.  Here 
>>>> is the glibc part.
>>> 
>>> Can you elaborate on why you think this is an ABI issue? IMO it's just
>>> s runtime issue unless you're considering raw floating point data
>>> written to disk. In any case this seems like such a small issue that
>>> it should just be silently fixed, rather than adding huge amounts of
>>> ABI ugliness.
>> 
>> To give you a small example this:
>> 
>> double foo = __builtin_nan ("");
>> 
>> will compile to a different data pattern with opposite (qNaN vs sNaN) 
>> semantics depending on the NaN encoding mode selected in the compiler.  
>> Modules built with different NaN encodings are therefore not compatible,
> 
> They are compatible except in the area of subtle exception-raising
> semantics that GCC *DOES NOT GET CORRECT ANYWAY*. GCC is full of
> incorrect optimizations that cause the exception flags to be wrong.
> Until that's fixed, I don't see why this issue is so important to
> merit flagging object files build with different modes as having an
> incompatible ABI. The semantics are slightly different, but the type
> sizes and the way they're passed are all the same, and programs that
> don't use the GCC extension __builtin_nan() or the NAN macro from
> math.h, or writing raw float values to/from disk, are completely
> unaffected.

Can you give an example and maybe a link to a GCC bug where this is recorded before spreading this kind of information.  I really don't like blank statements without facts to back up them.

Thanks,
Andrew Pinski


> 
>> either at the link or at the load time, as applicable.  LD (from binutils) 
>> and ld.so take care of the link-time and the load-time integrity check, 
>> respectively.
>> 
>> Additionally hardware has to be configured to match the encoding selected 
>> and executables that require a NaN encoding that is not supported by a 
>> given piece of hardware have to be rejected -- execve(2) is supposed to 
>> return in that case, which may only be handled by the kernel.  Please note 
>> that neither the legacy-NaN nor the 2008-NaN encoding is mandatory in the 
>> MIPS architecture; MIPS FPU hardware at the implementer's discretion may 
>> support either or both.
>> 
>> I hope this answers your question.  Any further concerns?
> 
> I'm just opposed to introducing massive complexity and spurious linker
> errors for the sake of something that shouldn't affect most programs,
> and where the only affected programs already had wrong behavior due to
> GCC's lack of proper support for floating point exception and
> rounding-mode semantics. Signaling NANs are an obscure, optional
> feature almost nobody uses, and if you're not intentionally using
> them, you don't care if computations with NANs raise spurious
> exceptions or not (especially since the exception was already raised
> when you first generated the NAN, unless you loaded a NAN explicitly
> via the NAN macro or strtod("NAN", 0)...
> 
> Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  3:11       ` pinskia
@ 2013-08-23  3:38         ` Rich Felker
  2013-08-23  4:08           ` pinskia
  0 siblings, 1 reply; 19+ messages in thread
From: Rich Felker @ 2013-08-23  3:38 UTC (permalink / raw)
  To: pinskia; +Cc: Maciej W. Rozycki, libc-ports, libc-alpha, Doug Gilmore

On Thu, Aug 22, 2013 at 08:10:49PM -0700, pinskia@gmail.com wrote:
> >> To give you a small example this:
> >> 
> >> double foo = __builtin_nan ("");
> >> 
> >> will compile to a different data pattern with opposite (qNaN vs sNaN) 
> >> semantics depending on the NaN encoding mode selected in the compiler.  
> >> Modules built with different NaN encodings are therefore not compatible,
> > 
> > They are compatible except in the area of subtle exception-raising
> > semantics that GCC *DOES NOT GET CORRECT ANYWAY*. GCC is full of
> > incorrect optimizations that cause the exception flags to be wrong.
> > Until that's fixed, I don't see why this issue is so important to
> > merit flagging object files build with different modes as having an
> > incompatible ABI. The semantics are slightly different, but the type
> > sizes and the way they're passed are all the same, and programs that
> > don't use the GCC extension __builtin_nan() or the NAN macro from
> > math.h, or writing raw float values to/from disk, are completely
> > unaffected.
> 
> Can you give an example and maybe a link to a GCC bug where this is
> recorded before spreading this kind of information. I really don't
> like blank statements without facts to back up them.

int foo() { double x = 0; x /= 0.0; return 1; }

While this is a stupid, trivial example, the issue has come up A LOT
for us in musl's implementation of the math library (based on fdlibm)
with nontrivial code.

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-22 23:53 [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support Maciej W. Rozycki
  2013-08-23  0:58 ` Rich Felker
@ 2013-08-23  3:46 ` Rich Felker
  2013-08-23 10:53   ` Maciej W. Rozycki
  2013-08-23 15:26 ` Joseph S. Myers
  2 siblings, 1 reply; 19+ messages in thread
From: Rich Felker @ 2013-08-23  3:46 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, Aug 23, 2013 at 12:52:43AM +0100, Maciej W. Rozycki wrote:
>  As from revision 3.50 [2][3] the MIPS Architecture provides for 
> processors that support the IEEE 754-2008 preferred NaN encoding format.  
> As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
> are incompatible to each other, tools will have to provide support for the 
> two formats to help people avoid using incompatible binary modules.  Here 
> is the glibc part.
> [...]
>  References:
> 
> [1] "IEEE Standard for Floating-Point Arithmetic", IEEE Computer Society, 
>     IEEE Std 754-2008, 29 August 2008
> 
> [2] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
>     MIPS32 Architecture", MIPS Technologies, Inc., Document Number: 
>     MD00082, Revision 3.50, September 20, 2012
> 
> [3] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
>     MIPS64 Architecture", MIPS Technologies, Inc., Document Number: 
>     MD00083, Revision 3.50, September 20, 2012

These documents do not seem to be publicly available; I can only mind
much older versions online, such as 0.95:

http://www.ece.lsu.edu/ee4720/mips64v1.pdf

Perhaps you could quote some of the relevant text?

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  3:38         ` Rich Felker
@ 2013-08-23  4:08           ` pinskia
  2013-08-23  4:12             ` Rich Felker
  0 siblings, 1 reply; 19+ messages in thread
From: pinskia @ 2013-08-23  4:08 UTC (permalink / raw)
  To: Rich Felker; +Cc: Maciej W. Rozycki, libc-ports, libc-alpha, Doug Gilmore

On Aug 22, 2013, at 8:38 PM, Rich Felker <dalias@aerifal.cx> wrote:

> On Thu, Aug 22, 2013 at 08:10:49PM -0700, pinskia@gmail.com wrote:
>>>> To give you a small example this:
>>>> 
>>>> double foo = __builtin_nan ("");
>>>> 
>>>> will compile to a different data pattern with opposite (qNaN vs sNaN) 
>>>> semantics depending on the NaN encoding mode selected in the compiler.  
>>>> Modules built with different NaN encodings are therefore not compatible,
>>> 
>>> They are compatible except in the area of subtle exception-raising
>>> semantics that GCC *DOES NOT GET CORRECT ANYWAY*. GCC is full of
>>> incorrect optimizations that cause the exception flags to be wrong.
>>> Until that's fixed, I don't see why this issue is so important to
>>> merit flagging object files build with different modes as having an
>>> incompatible ABI. The semantics are slightly different, but the type
>>> sizes and the way they're passed are all the same, and programs that
>>> don't use the GCC extension __builtin_nan() or the NAN macro from
>>> math.h, or writing raw float values to/from disk, are completely
>>> unaffected.
>> 
>> Can you give an example and maybe a link to a GCC bug where this is
>> recorded before spreading this kind of information. I really don't
>> like blank statements without facts to back up them.
> 
> int foo() { double x = 0; x /= 0.0; return 1; }
> 
> While this is a stupid, trivial example, the issue has come up A LOT
> for us in musl's implementation of the math library (based on fdlibm)
> with nontrivial code.

Wait you mean dead code? I think the standard/IEEE allows to remove it. At -O0, GCC won't remove it though.

> 
> Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  1:41   ` Maciej W. Rozycki
  2013-08-23  1:57     ` Rich Felker
@ 2013-08-23  4:10     ` Rich Felker
  1 sibling, 0 replies; 19+ messages in thread
From: Rich Felker @ 2013-08-23  4:10 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, Aug 23, 2013 at 02:41:21AM +0100, Maciej W. Rozycki wrote:
> > >  As from revision 3.50 [2][3] the MIPS Architecture provides for 
> > > processors that support the IEEE 754-2008 preferred NaN encoding format.  
> > > As the two formats (further referred to as "legacy NaN" and "2008 NaN") 
> > > are incompatible to each other, tools will have to provide support for the 
> > > two formats to help people avoid using incompatible binary modules.  Here 
> > > is the glibc part.
> > 
> > Can you elaborate on why you think this is an ABI issue? IMO it's just
> > s runtime issue unless you're considering raw floating point data
> > written to disk. In any case this seems like such a small issue that
> > it should just be silently fixed, rather than adding huge amounts of
> > ABI ugliness.
> 
>  To give you a small example this:
> 
> double foo = __builtin_nan ("");
> 
> will compile to a different data pattern with opposite (qNaN vs sNaN) 
> semantics depending on the NaN encoding mode selected in the compiler.  
> Modules built with different NaN encodings are therefore not compatible, 
> either at the link or at the load time, as applicable.  LD (from binutils) 
> and ld.so take care of the link-time and the load-time integrity check, 
> respectively.

If you really care about supporting this, I have an alternate idea
that doesn't lead to incompatible ABIs. Have GCC put static objects
containing NANs in the writable data section, and add a new R_MIPS_NAN
relocation type that flips the high bit of the NAN to match the
runtime environment. The only difficulty would be making it work with
static linking; you could choose to just have the static linker
resolve all static objects containing NANs to a single, fixed NAN
format at link time, or have some startup code to process them.

For __builtin_nan() that's not used as a constant expression for
initializing static objects, GCC can just generate a call to libgcc,
or direct access to a global object, to flip the high bit
appropriately.

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  4:08           ` pinskia
@ 2013-08-23  4:12             ` Rich Felker
  0 siblings, 0 replies; 19+ messages in thread
From: Rich Felker @ 2013-08-23  4:12 UTC (permalink / raw)
  To: pinskia; +Cc: Maciej W. Rozycki, libc-ports, libc-alpha, Doug Gilmore

On Thu, Aug 22, 2013 at 09:07:34PM -0700, pinskia@gmail.com wrote:
> On Aug 22, 2013, at 8:38 PM, Rich Felker <dalias@aerifal.cx> wrote:
> 
> > On Thu, Aug 22, 2013 at 08:10:49PM -0700, pinskia@gmail.com wrote:
> >>>> To give you a small example this:
> >>>> 
> >>>> double foo = __builtin_nan ("");
> >>>> 
> >>>> will compile to a different data pattern with opposite (qNaN vs sNaN) 
> >>>> semantics depending on the NaN encoding mode selected in the compiler.  
> >>>> Modules built with different NaN encodings are therefore not compatible,
> >>> 
> >>> They are compatible except in the area of subtle exception-raising
> >>> semantics that GCC *DOES NOT GET CORRECT ANYWAY*. GCC is full of
> >>> incorrect optimizations that cause the exception flags to be wrong.
> >>> Until that's fixed, I don't see why this issue is so important to
> >>> merit flagging object files build with different modes as having an
> >>> incompatible ABI. The semantics are slightly different, but the type
> >>> sizes and the way they're passed are all the same, and programs that
> >>> don't use the GCC extension __builtin_nan() or the NAN macro from
> >>> math.h, or writing raw float values to/from disk, are completely
> >>> unaffected.
> >> 
> >> Can you give an example and maybe a link to a GCC bug where this is
> >> recorded before spreading this kind of information. I really don't
> >> like blank statements without facts to back up them.
> > 
> > int foo() { double x = 0; x /= 0.0; return 1; }
> > 
> > While this is a stupid, trivial example, the issue has come up A LOT
> > for us in musl's implementation of the math library (based on fdlibm)
> > with nontrivial code.
> 
> Wait you mean dead code? I think the standard/IEEE allows to remove
> it.

They don't. Anyway, here's a less trivial example:

double f(int y){ double x=0; x/=0; if(y) return 1; return x; }

> At -O0, GCC won't remove it though.

That's not helpful; -O0 is not usable for most purposes. The output is
gigantic and slow. And if I'm not mistaken, there are some cases where
even -O0 will mess it up...

Rich

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23  3:46 ` Rich Felker
@ 2013-08-23 10:53   ` Maciej W. Rozycki
  0 siblings, 0 replies; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-08-23 10:53 UTC (permalink / raw)
  To: Rich Felker; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, 23 Aug 2013, Rich Felker wrote:

> >  References:
> > 
> > [1] "IEEE Standard for Floating-Point Arithmetic", IEEE Computer Society, 
> >     IEEE Std 754-2008, 29 August 2008
> > 
> > [2] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
> >     MIPS32 Architecture", MIPS Technologies, Inc., Document Number: 
> >     MD00082, Revision 3.50, September 20, 2012
> > 
> > [3] "MIPS Architecture For Programmers, Volume I-A: Introduction to the 
> >     MIPS64 Architecture", MIPS Technologies, Inc., Document Number: 
> >     MD00083, Revision 3.50, September 20, 2012
> 
> These documents do not seem to be publicly available; I can only mind
> much older versions online, such as 0.95:
> 
> http://www.ece.lsu.edu/ee4720/mips64v1.pdf

 You can download current versions (5.02 and 5.01 respectively) of MIPS 
architecture documents here:

http://www.imgtec.com/mips/mips32-architecture.asp

http://www.imgtec.com/mips/mips64-architecture.asp

The IEEE standard is available from IEEE under the usual terms.

  Maciej

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-22 23:53 [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support Maciej W. Rozycki
  2013-08-23  0:58 ` Rich Felker
  2013-08-23  3:46 ` Rich Felker
@ 2013-08-23 15:26 ` Joseph S. Myers
  2013-09-05 22:47   ` [RFC][PATCH v2] " Maciej W. Rozycki
  2 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2013-08-23 15:26 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, 23 Aug 2013, Maciej W. Rozycki wrote:

>    Finally a new name has been defined for the dynamic linker so that 
>    2008-NaN and legacy-NaN binaries can coexist on a single system that 
>    supports dual-mode operation and that a legacy dynamic linker that 
>    does not support verifying the 2008-NaN ELF file header flag is not 
>    chosen to interpret a 2008-NaN binary by accident.

Adding a new name is the correct thing to do, but it means you need to 
update ports/sysdeps/unix/sysv/linux/mips/{configure.in,Makefile} to 
reflect that there are now twelve rather than six ABI variants that one or 
more generated installed header needs to reflect - as in ../arm/Makefile, 
you will need to set the *-ld-soname variables for each of the twelve 
ABIs, so that gnu/lib-names.h is correct for all the variants.

(gnu/lib-names.h will only depend on the NaN encoding in fact, 
bits/syscall.h only on whether the ABI is o32, n32 or n64, and gnu/stubs.h 
on both whether the ABI is o32, n32 or n64 and whether it's hard or soft 
float.  But the build system doesn't do anything special regarding headers 
depending only on a subset of ABI information like that; the twelve ABIs 
will just be treated as completely distinct for that purpose.)

> Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c
> ===================================================================
> --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu/fesetenv.c	2013-05-16 18:17:13.000000000 +0100
> +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c	2013-08-22 10:32:05.447640501 +0100

I don't see why you need changes here.  If someone has somehow created an 
fenv_t value with an inappropriate NAN2008 bit, that's definitely outside 
the scope of what gives defined behavior - such values should only come 
from other functions such as fegetenv (or the standard values defined in 
fenv.h).

>  /* The fdlibm code requires strict IEEE double precision arithmetic,
>     and no interrupts for exceptions, rounding to nearest.  */
> -
> +#ifdef __mips_nan2008
> +#define _FPU_DEFAULT  0x00040000
> +#else
>  #define _FPU_DEFAULT  0x00000000
> +#endif
>  
> -/* IEEE:  same as above, but exceptions */
> +/* IEEE: same as above, but exceptions.  */
> +#ifdef __mips_nan2008
> +#define _FPU_IEEE     0x00040F80
> +#else
>  #define _FPU_IEEE     0x00000F80
> +#endif

"# define" indentation inside #if.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC][PATCH v2] MIPS: IEEE 754-2008 NaN encoding support
  2013-08-23 15:26 ` Joseph S. Myers
@ 2013-09-05 22:47   ` Maciej W. Rozycki
  2013-09-06 16:24     ` Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-09-05 22:47 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, 23 Aug 2013, Joseph S. Myers wrote:

> >    Finally a new name has been defined for the dynamic linker so that 
> >    2008-NaN and legacy-NaN binaries can coexist on a single system that 
> >    supports dual-mode operation and that a legacy dynamic linker that 
> >    does not support verifying the 2008-NaN ELF file header flag is not 
> >    chosen to interpret a 2008-NaN binary by accident.
> 
> Adding a new name is the correct thing to do, but it means you need to 
> update ports/sysdeps/unix/sysv/linux/mips/{configure.in,Makefile} to 
> reflect that there are now twelve rather than six ABI variants that one or 
> more generated installed header needs to reflect - as in ../arm/Makefile, 
> you will need to set the *-ld-soname variables for each of the twelve 
> ABIs, so that gnu/lib-names.h is correct for all the variants.

 Fixed.

> > Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c
> > ===================================================================
> > --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu/fesetenv.c	2013-05-16 18:17:13.000000000 +0100
> > +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/fesetenv.c	2013-08-22 10:32:05.447640501 +0100
> 
> I don't see why you need changes here.  If someone has somehow created an 
> fenv_t value with an inappropriate NAN2008 bit, that's definitely outside 
> the scope of what gives defined behavior - such values should only come 
> from other functions such as fegetenv (or the standard values defined in 
> fenv.h).

 Indeed, I have removed this part now.

> >  /* The fdlibm code requires strict IEEE double precision arithmetic,
> >     and no interrupts for exceptions, rounding to nearest.  */
> > -
> > +#ifdef __mips_nan2008
> > +#define _FPU_DEFAULT  0x00040000
> > +#else
> >  #define _FPU_DEFAULT  0x00000000
> > +#endif
> >  
> > -/* IEEE:  same as above, but exceptions */
> > +/* IEEE: same as above, but exceptions.  */
> > +#ifdef __mips_nan2008
> > +#define _FPU_IEEE     0x00040F80
> > +#else
> >  #define _FPU_IEEE     0x00000F80
> > +#endif
> 
> "# define" indentation inside #if.

 Fixed.

 Thanks for your review.  Here's an updated version.  I hope this is OK, 
in which case I'll repost it with the kernel version requirement updated 
once the required functionality has made its way there; otherwise please 
let me know.

2012-09-06  Maciej W. Rozycki  <macro@codesourcery.com>

	ChangeLog:
	* config.h.in (HAVE_MIPS_NAN2008): New macro.
	* elf/elf.h (EF_MIPS_NAN2008): Likewise.
	* sysdeps/generic/ldconfig.h (FLAG_MIPS_LIB32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN64_NAN2008): Likewise.
	* elf/cache.c (print_entry): Handle the new cache flags.

	ports/ChangeLog.mips
	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NAN2008): New macro.
	(elf_machine_matches_host): Reject objects that use a different
	NaN encoding convention.
	* sysdeps/mips/fpu_control.h: Document IEEE 754-2008 feature 
	control bits.
	(_FPU_ABS2008, _FPU_NAN2008): New macros.
	(_FPU_RESERVED): Clear bits #20 and #19.
	(_FPU_DEFAULT) [__mips_nan2008]: Set bit #18.
	(_FPU_IEEE) [__mips_nan2008]: Likewise.
	* sysdeps/mips/mips64/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/mips/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID): 
	Define 2008 NaN encoding values.
	* sysdeps/unix/sysv/linux/mips/readelflib.c (process_elf_file):
	Handle 2008-NaN libraries.
	* sysdeps/mips/shlib-versions [HAVE_MIPS_NAN2008]: Set 
	ld=ld-linux-mipsn8.so.1.
	* sysdeps/mips/configure.in: Define HAVE_MIPS_NAN2008 if the
	2008 NaN encoding is used.
	* sysdeps/unix/sysv/linux/mips/Makefile (abi-variants): Add
	2008-NaN ABI variants.
	(abi-o32_soft-options, abi-o32_soft-condition): Update with the
	__mips_nan2008 macro.
	(abi-o32_hard-options, abi-o32_hard-condition): Likewise.
	(abi-n32_soft-options, abi-n32_soft-condition): Likewise.
	(abi-n32_hard-options, abi-n32_hard-condition): Likewise.
	(abi-n64_soft-options, abi-n64_soft-condition): Likewise.
	(abi-n64_hard-options, abi-n64_hard-condition): Likewise.
	(abi-o32_soft-ld-soname, abi-o32_hard-ld-soname): New macros.
	(abi-n32_soft-ld-soname, abi-n32_hard-ld-soname): Likewise.
	(abi-n64_soft-ld-soname, abi-n64_hard-ld-soname): Likewise.
	(abi-o32_soft_2008-options): Likewise.
	(abi-o32_soft_2008-condition): Likewise.
	(abi-o32_hard_2008-options): Likewise.
	(abi-o32_hard_2008-condition): Likewise.
	(abi-n32_soft_2008-options): Likewise.
	(abi-n32_soft_2008-condition): Likewise.
	(abi-n32_hard_2008-options): Likewise.
	(abi-n32_hard_2008-condition): Likewise.
	(abi-n64_soft_2008-options): Likewise.
	(abi-n64_soft_2008-condition): Likewise.
	(abi-n64_hard_2008-options): Likewise.
	(abi-n64_hard_2008-condition): Likewise.
	(abi-o32_soft_2008-ld-soname): Likewise.
	(abi-o32_hard_2008-ld-soname): Likewise.
	(abi-n32_soft_2008-ld-soname): Likewise.
	(abi-n32_hard_2008-ld-soname): Likewise.
	(abi-n64_soft_2008-ld-soname): Likewise.
	(abi-n64_hard_2008-ld-soname): Likewise.
	* sysdeps/unix/sysv/linux/mips/configure.in: Include the NaN
	encoding selection in default-abi.  Set arch_minimum_kernel to
	3.11.0 if 2008 NaN encoding is used.
	* sysdeps/mips/configure: Regenerate.
	* sysdeps/unix/sysv/linux/mips/configure: Regenerate.

  Maciej

glibc-mips-nan2008.diff
Index: glibc-fsf-trunk-quilt/config.h.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/config.h.in	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/config.h.in	2013-09-03 22:06:53.447494356 +0100
@@ -241,4 +241,8 @@
 /* The pt_chown binary is being built and used by grantpt.  */
 #undef HAVE_PT_CHOWN
 
+/* ports/sysdeps/mips/configure.in  */
+/* Define if using the IEEE 754-2008 NaN encoding on the MIPS target.  */
+#undef HAVE_MIPS_NAN2008
+
 #endif
Index: glibc-fsf-trunk-quilt/elf/cache.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/cache.c	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/cache.c	2013-09-03 22:06:53.447494356 +0100
@@ -105,6 +105,15 @@ print_entry (const char *lib, int flag, 
     case FLAG_ARM_LIBSF:
       fputs (",soft-float", stdout);
       break;
+    case FLAG_MIPS_LIB32_NAN2008:
+      fputs (",nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN32_NAN2008:
+      fputs (",N32,nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN64_NAN2008:
+      fputs (",64bit,nan2008", stdout);
+      break;
     case 0:
       break;
     default:
Index: glibc-fsf-trunk-quilt/elf/elf.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/elf.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/elf.h	2013-09-03 22:06:53.447494356 +0100
@@ -1383,6 +1383,7 @@ typedef struct
 #define EF_MIPS_64BIT_WHIRL	16
 #define EF_MIPS_ABI2		32
 #define EF_MIPS_ABI_ON32	64
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
 #define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
 
 /* Legal values for MIPS architecture level.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure	2013-09-03 22:06:53.447494356 +0100
@@ -1,3 +1,163 @@
 # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/mips.
 
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+if test x$libc_cv_mips_nan2008 = xyes; then
+  $as_echo "#define HAVE_MIPS_NAN2008 1" >>confdefs.h
+
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure.in	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in	2013-09-03 22:06:53.447494356 +0100
@@ -4,3 +4,12 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the
 dnl No MIPS GCC supports accessing static and hidden symbols in an
 dnl position independent way.
 dnl AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+if test x$libc_cv_mips_nan2008 = xyes; then
+  AC_DEFINE(HAVE_MIPS_NAN2008)
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-machine.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h	2013-09-03 22:06:53.447494356 +0100
@@ -73,6 +73,16 @@ do { if ((l)->l_info[DT_MIPS (RLD_MAP)])
        (ElfW(Addr)) (r); \
    } while (0)
 
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+#ifdef __mips_nan2008
+# define ELF_MACHINE_NAN2008 EF_MIPS_NAN2008
+#else
+# define ELF_MACHINE_NAN2008 0
+#endif
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute_used__
 elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
@@ -83,6 +93,10 @@ elf_machine_matches_host (const ElfW(Ehd
     return 0;
 #endif
 
+  /* Don't link 2008-NaN and legacy-NaN objects together.  */
+  if ((ehdr->e_flags & EF_MIPS_NAN2008) != ELF_MACHINE_NAN2008)
+    return 0;
+
   switch (ehdr->e_machine)
     {
     case EM_MIPS:
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu_control.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h	2013-09-03 22:06:53.447494356 +0100
@@ -29,7 +29,9 @@
  *           available for MIPS III and newer.
  * 23     -> Condition bit
  * 22-21  -> reserved for architecture implementers
- * 20-18  -> reserved (read as 0, write with 0)
+ * 20     -> reserved (read as 0, write with 0)
+ * 19     -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable
+ * 18     -> IEEE 754-2008 recommended NaN encoding enable
  * 17     -> cause bit for unimplemented operation
  * 16     -> cause bit for invalid exception
  * 15     -> cause bit for division by zero exception
@@ -79,22 +81,33 @@ extern fpu_control_t __fpu_control;
 /* flush denormalized numbers to zero */
 #define _FPU_FLUSH_TZ   0x1000000
 
+/* IEEE 754-2008 compliance control.  */
+#define _FPU_ABS2008    0x80000
+#define _FPU_NAN2008    0x40000
+
 /* rounding control */
 #define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
 #define _FPU_RC_ZERO    0x1
 #define _FPU_RC_UP      0x2
 #define _FPU_RC_DOWN    0x3
 
-#define _FPU_RESERVED 0xfe9c0000  /* Reserved bits in cw */
+#define _FPU_RESERVED 0xfe840000  /* Reserved bits in cw, incl NAN2008.  */
 
 
 /* The fdlibm code requires strict IEEE double precision arithmetic,
    and no interrupts for exceptions, rounding to nearest.  */
+#ifdef __mips_nan2008
+# define _FPU_DEFAULT 0x00040000
+#else
+# define _FPU_DEFAULT 0x00000000
+#endif
 
-#define _FPU_DEFAULT  0x00000000
-
-/* IEEE:  same as above, but exceptions */
-#define _FPU_IEEE     0x00000F80
+/* IEEE: same as above, but exceptions.  */
+#ifdef __mips_nan2008
+# define _FPU_IEEE    0x00040F80
+#else
+# define _FPU_IEEE    0x00000F80
+#endif
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-03 22:06:53.447494356 +0100
@@ -24,15 +24,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/shlib-versions	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions	2013-09-03 22:06:53.447494356 +0100
@@ -3,7 +3,11 @@ mips.*-.*-linux.*	libm=6			GLIBC_2.0 GLI
 # Working mips versions were never released between 2.0 and 2.2.
 mips.*-.*-linux.*	libc=6			GLIBC_2.0 GLIBC_2.2
 
+%ifdef HAVE_MIPS_NAN2008
+mips.*-.*-linux.*	ld=ld-linux-mipsn8.so.1	GLIBC_2.0 GLIBC_2.2
+%else
 mips.*-.*-linux.*	ld=ld.so.1		GLIBC_2.0 GLIBC_2.2
+%endif
 mips.*-.*-linux.*	libdl=2			GLIBC_2.0 GLIBC_2.2
 
 mips.*-.*-linux.*	libresolv=2		GLIBC_2.0 GLIBC_2.2
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-03 22:06:53.447494356 +0100
@@ -21,15 +21,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-03 22:06:53.447494356 +0100
@@ -8,7 +8,9 @@ sysdep_routines += cachectl cacheflush s
 sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
 endif
 
-abi-variants := o32_soft o32_hard n32_soft n32_hard n64_soft n64_hard
+abi-variants := o32_soft o32_hard o32_soft_2008 o32_hard_2008
+abi-variants += n32_soft n32_hard n32_soft_2008 n32_hard_2008
+abi-variants += n64_soft n64_hard n64_soft_2008 n64_hard_2008
 
 ifeq (,$(filter $(default-abi),$(abi-variants)))
 Unknown ABI, must be one of $(abi-variants)
@@ -18,29 +20,89 @@ abi-includes := sgidefs.h
 
 # _MIPS_SIM_ABI32 == 1, _MIPS_SIM_NABI32 == 2, _MIPS_SIM_ABI64 == 3
 abi-o32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-o32_soft-condition := defined(__mips_soft_float) \
-			   && (_MIPS_SIM == _MIPS_SIM_ABI32)
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-o32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
+			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft-ld-soname := ld.so.1
 abi-o32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-o32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-o32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard-ld-soname := ld.so.1
+abi-o32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-o32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-o32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-o32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n32_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft-ld-soname := ld.so.1
 abi-n32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard-ld-soname := ld.so.1
+abi-n32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n64_soft-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n64_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n64_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft-ld-soname := ld.so.1
 abi-n64_hard-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n64_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n64_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard-ld-soname := ld.so.1
+abi-n64_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n64_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n64_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n64_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 
 ifeq ($(subdir),elf)
 ifeq ($(build-shared),yes)
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-03 22:19:06.339721332 +0100
@@ -105,8 +105,168 @@ if test -z "$libc_mips_float"; then
   as_fn_error $? "could not determine if compiler is using hard or soft floating point ABI" "$LINENO" 5
 fi
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
 config_vars="$config_vars
-default-abi = ${libc_mips_abi}_${libc_mips_float}"
+default-abi = ${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}"
 
 case "$prefix" in
 /usr | /usr/)
@@ -138,3 +298,9 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    arch_minimum_kernel=3.11.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-03 22:16:55.857444871 +0100
@@ -44,7 +44,19 @@ if test -z "$libc_mips_float"; then
   AC_MSG_ERROR([could not determine if compiler is using hard or soft floating point ABI])
 fi
 
-LIBC_CONFIG_VAR([default-abi], [${libc_mips_abi}_${libc_mips_float}])
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
+LIBC_CONFIG_VAR([default-abi],
+  [${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}])
 
 case "$prefix" in
 /usr | /usr/)
@@ -76,3 +88,9 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    arch_minimum_kernel=3.11.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-03 22:06:53.447494356 +0100
@@ -18,11 +18,27 @@
 
 #include <ldconfig.h>
 
-/* Redefine the cache ID for new ABIs; o32 keeps using the generic check.  */
-#if _MIPS_SIM == _ABI64
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
-#elif _MIPS_SIM == _ABIN32
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+
+/* Redefine the cache ID for new ABIs and 2008 NaN support; legacy o32
+   keeps using the generic check.  */
+#ifdef __mips_nan2008
+# if _MIPS_SIM == _ABIO32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32_NAN2008 | FLAG_ELF_LIBC6)
+# endif
+#else
+# if _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+# endif
 #endif
 
 #ifdef _DL_CACHE_DEFAULT_ID
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-03 22:06:53.447494356 +0100
@@ -33,19 +33,32 @@ process_elf_file (const char *file_name,
 		  unsigned int *osversion, char **soname, void *file_contents,
 		  size_t file_length)
 {
-  ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+  union
+    {
+      Elf64_Ehdr *eh64;
+      Elf32_Ehdr *eh32;
+      ElfW(Ehdr) *eh;
+    }
+  elf_header;
   int ret;
 
-  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+  elf_header.eh = file_contents;
+  if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32)
     {
-      Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
-
       ret = process_elf32_file (file_name, lib, flag, osversion, soname,
 				file_contents, file_length);
+      if (!ret)
+	{
+	  Elf32_Word flags = elf_header.eh32->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
 
-      /* n32 libraries are always libc.so.6+.  */
-      if (!ret && (elf32_header->e_flags & EF_MIPS_ABI2) != 0)
-	*flag = FLAG_MIPS64_LIBN32|FLAG_ELF_LIBC6;
+	  /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN.  */
+	  if ((flags & EF_MIPS_ABI2) != 0)
+	    *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008
+		     : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6;
+	  else if (nan2008)
+	    *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6;
+	}
     }
   else
     {
@@ -53,7 +66,13 @@ process_elf_file (const char *file_name,
 				file_contents, file_length);
       /* n64 libraries are always libc.so.6+.  */
       if (!ret)
-	*flag = FLAG_MIPS64_LIBN64|FLAG_ELF_LIBC6;
+	{
+	  Elf64_Word flags = elf_header.eh64->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
+
+	  *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008
+		   : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6;
+	}
     }
 
   return ret;
Index: glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/sysdeps/generic/ldconfig.h	2013-09-03 22:04:28.000000000 +0100
+++ glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h	2013-09-03 22:06:53.447494356 +0100
@@ -21,24 +21,27 @@
 
 #include <stdint.h>
 
-#define FLAG_ANY		-1
-#define FLAG_TYPE_MASK		0x00ff
-#define FLAG_LIBC4		0x0000
-#define FLAG_ELF		0x0001
-#define FLAG_ELF_LIBC5		0x0002
-#define FLAG_ELF_LIBC6		0x0003
-#define FLAG_REQUIRED_MASK	0xff00
-#define FLAG_SPARC_LIB64	0x0100
-#define FLAG_IA64_LIB64		0x0200
-#define FLAG_X8664_LIB64	0x0300
-#define FLAG_S390_LIB64		0x0400
-#define FLAG_POWERPC_LIB64	0x0500
-#define FLAG_MIPS64_LIBN32	0x0600
-#define FLAG_MIPS64_LIBN64	0x0700
-#define FLAG_X8664_LIBX32	0x0800
-#define FLAG_ARM_LIBHF		0x0900
-#define FLAG_AARCH64_LIB64	0x0a00
-#define FLAG_ARM_LIBSF		0x0b00
+#define FLAG_ANY			-1
+#define FLAG_TYPE_MASK			0x00ff
+#define FLAG_LIBC4			0x0000
+#define FLAG_ELF			0x0001
+#define FLAG_ELF_LIBC5			0x0002
+#define FLAG_ELF_LIBC6			0x0003
+#define FLAG_REQUIRED_MASK		0xff00
+#define FLAG_SPARC_LIB64		0x0100
+#define FLAG_IA64_LIB64			0x0200
+#define FLAG_X8664_LIB64		0x0300
+#define FLAG_S390_LIB64			0x0400
+#define FLAG_POWERPC_LIB64		0x0500
+#define FLAG_MIPS64_LIBN32		0x0600
+#define FLAG_MIPS64_LIBN64		0x0700
+#define FLAG_X8664_LIBX32		0x0800
+#define FLAG_ARM_LIBHF			0x0900
+#define FLAG_AARCH64_LIB64		0x0a00
+#define FLAG_ARM_LIBSF			0x0b00
+#define FLAG_MIPS_LIB32_NAN2008		0x0c00
+#define FLAG_MIPS64_LIBN32_NAN2008	0x0d00
+#define FLAG_MIPS64_LIBN64_NAN2008	0x0e00
 
 /* Name of auxiliary cache.  */
 #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v2] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-05 22:47   ` [RFC][PATCH v2] " Maciej W. Rozycki
@ 2013-09-06 16:24     ` Joseph S. Myers
  2013-09-10  9:36       ` Maciej W. Rozycki
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2013-09-06 16:24 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Thu, 5 Sep 2013, Maciej W. Rozycki wrote:

>  Thanks for your review.  Here's an updated version.  I hope this is OK, 
> in which case I'll repost it with the kernel version requirement updated 
> once the required functionality has made its way there; otherwise please 
> let me know.

This is OK (with the year in the ChangeLog entry fixed) on the basis that 
you'll update the kernel version once the kernel support is upstream (and 
until then, put a comment on it about it not being the final kernel 
version), but leave it a few days before commit in case anyone else spots 
anything wrong.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v2] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-06 16:24     ` Joseph S. Myers
@ 2013-09-10  9:36       ` Maciej W. Rozycki
  2013-09-10 23:24         ` Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-09-10  9:36 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Fri, 6 Sep 2013, Joseph S. Myers wrote:

> >  Thanks for your review.  Here's an updated version.  I hope this is OK, 
> > in which case I'll repost it with the kernel version requirement updated 
> > once the required functionality has made its way there; otherwise please 
> > let me know.
> 
> This is OK (with the year in the ChangeLog entry fixed) on the basis that 
> you'll update the kernel version once the kernel support is upstream (and 
> until then, put a comment on it about it not being the final kernel 
> version), but leave it a few days before commit in case anyone else spots 
> anything wrong.

 I infer you'd prefer to have this change committed even though the 
required kernel part isn't there yet, right?  I have therefore set the 
minimum version required artificially to 10.0.0 so that this code is not 
accidentally activated on a kernel that doesn't support the 2008-NaN 
feature and put a FIXME note next to it.  Please let me know if this is 
what you had in mind.

2013-09-10  Maciej W. Rozycki  <macro@codesourcery.com>

	ChangeLog:
	* config.h.in (HAVE_MIPS_NAN2008): New macro.
	* elf/elf.h (EF_MIPS_NAN2008): Likewise.
	* sysdeps/generic/ldconfig.h (FLAG_MIPS_LIB32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN64_NAN2008): Likewise.
	* elf/cache.c (print_entry): Handle the new cache flags.

	ports/ChangeLog.mips
	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NAN2008): New macro.
	(elf_machine_matches_host): Reject objects that use a different
	NaN encoding convention.
	* sysdeps/mips/fpu_control.h: Document IEEE 754-2008 feature 
	control bits.
	(_FPU_ABS2008, _FPU_NAN2008): New macros.
	(_FPU_RESERVED): Clear bits #20 and #19.
	(_FPU_DEFAULT) [__mips_nan2008]: Set bit #18.
	(_FPU_IEEE) [__mips_nan2008]: Likewise.
	* sysdeps/mips/mips64/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/mips/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID): 
	Define 2008 NaN encoding values.
	* sysdeps/unix/sysv/linux/mips/readelflib.c (process_elf_file):
	Handle 2008-NaN libraries.
	* sysdeps/mips/shlib-versions [HAVE_MIPS_NAN2008]: Set 
	ld=ld-linux-mipsn8.so.1.
	* sysdeps/mips/configure.in: Define HAVE_MIPS_NAN2008 if the
	2008 NaN encoding is used.
	* sysdeps/unix/sysv/linux/mips/Makefile (abi-variants): Add
	2008-NaN ABI variants.
	(abi-o32_soft-options, abi-o32_soft-condition): Update with the
	__mips_nan2008 macro.
	(abi-o32_hard-options, abi-o32_hard-condition): Likewise.
	(abi-n32_soft-options, abi-n32_soft-condition): Likewise.
	(abi-n32_hard-options, abi-n32_hard-condition): Likewise.
	(abi-n64_soft-options, abi-n64_soft-condition): Likewise.
	(abi-n64_hard-options, abi-n64_hard-condition): Likewise.
	(abi-o32_soft-ld-soname, abi-o32_hard-ld-soname): New macros.
	(abi-n32_soft-ld-soname, abi-n32_hard-ld-soname): Likewise.
	(abi-n64_soft-ld-soname, abi-n64_hard-ld-soname): Likewise.
	(abi-o32_soft_2008-options): Likewise.
	(abi-o32_soft_2008-condition): Likewise.
	(abi-o32_hard_2008-options): Likewise.
	(abi-o32_hard_2008-condition): Likewise.
	(abi-n32_soft_2008-options): Likewise.
	(abi-n32_soft_2008-condition): Likewise.
	(abi-n32_hard_2008-options): Likewise.
	(abi-n32_hard_2008-condition): Likewise.
	(abi-n64_soft_2008-options): Likewise.
	(abi-n64_soft_2008-condition): Likewise.
	(abi-n64_hard_2008-options): Likewise.
	(abi-n64_hard_2008-condition): Likewise.
	(abi-o32_soft_2008-ld-soname): Likewise.
	(abi-o32_hard_2008-ld-soname): Likewise.
	(abi-n32_soft_2008-ld-soname): Likewise.
	(abi-n32_hard_2008-ld-soname): Likewise.
	(abi-n64_soft_2008-ld-soname): Likewise.
	(abi-n64_hard_2008-ld-soname): Likewise.
	* sysdeps/unix/sysv/linux/mips/configure.in: Include the NaN
	encoding selection in default-abi.  Set arch_minimum_kernel to
	10.0.0 if 2008 NaN encoding is used.
	* sysdeps/mips/configure: Regenerate.
	* sysdeps/unix/sysv/linux/mips/configure: Regenerate.

  Maciej

glibc-mips-nan2008.diff
Index: glibc-fsf-trunk-quilt/config.h.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/config.h.in	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/config.h.in	2013-09-10 00:18:22.018801136 +0100
@@ -241,4 +241,8 @@
 /* The pt_chown binary is being built and used by grantpt.  */
 #undef HAVE_PT_CHOWN
 
+/* ports/sysdeps/mips/configure.in  */
+/* Define if using the IEEE 754-2008 NaN encoding on the MIPS target.  */
+#undef HAVE_MIPS_NAN2008
+
 #endif
Index: glibc-fsf-trunk-quilt/elf/cache.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/cache.c	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/cache.c	2013-09-10 00:18:22.018801136 +0100
@@ -105,6 +105,15 @@ print_entry (const char *lib, int flag, 
     case FLAG_ARM_LIBSF:
       fputs (",soft-float", stdout);
       break;
+    case FLAG_MIPS_LIB32_NAN2008:
+      fputs (",nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN32_NAN2008:
+      fputs (",N32,nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN64_NAN2008:
+      fputs (",64bit,nan2008", stdout);
+      break;
     case 0:
       break;
     default:
Index: glibc-fsf-trunk-quilt/elf/elf.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/elf.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/elf.h	2013-09-10 00:18:22.018801136 +0100
@@ -1383,6 +1383,7 @@ typedef struct
 #define EF_MIPS_64BIT_WHIRL	16
 #define EF_MIPS_ABI2		32
 #define EF_MIPS_ABI_ON32	64
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
 #define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
 
 /* Legal values for MIPS architecture level.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure	2013-09-10 00:18:22.018801136 +0100
@@ -1,3 +1,163 @@
 # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/mips.
 
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+if test x$libc_cv_mips_nan2008 = xyes; then
+  $as_echo "#define HAVE_MIPS_NAN2008 1" >>confdefs.h
+
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure.in	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in	2013-09-10 00:18:22.018801136 +0100
@@ -4,3 +4,12 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the
 dnl No MIPS GCC supports accessing static and hidden symbols in an
 dnl position independent way.
 dnl AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+if test x$libc_cv_mips_nan2008 = xyes; then
+  AC_DEFINE(HAVE_MIPS_NAN2008)
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-machine.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h	2013-09-10 00:18:22.018801136 +0100
@@ -73,6 +73,16 @@ do { if ((l)->l_info[DT_MIPS (RLD_MAP)])
        (ElfW(Addr)) (r); \
    } while (0)
 
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+#ifdef __mips_nan2008
+# define ELF_MACHINE_NAN2008 EF_MIPS_NAN2008
+#else
+# define ELF_MACHINE_NAN2008 0
+#endif
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute_used__
 elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
@@ -83,6 +93,10 @@ elf_machine_matches_host (const ElfW(Ehd
     return 0;
 #endif
 
+  /* Don't link 2008-NaN and legacy-NaN objects together.  */
+  if ((ehdr->e_flags & EF_MIPS_NAN2008) != ELF_MACHINE_NAN2008)
+    return 0;
+
   switch (ehdr->e_machine)
     {
     case EM_MIPS:
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu_control.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h	2013-09-10 00:18:22.018801136 +0100
@@ -29,7 +29,9 @@
  *           available for MIPS III and newer.
  * 23     -> Condition bit
  * 22-21  -> reserved for architecture implementers
- * 20-18  -> reserved (read as 0, write with 0)
+ * 20     -> reserved (read as 0, write with 0)
+ * 19     -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable
+ * 18     -> IEEE 754-2008 recommended NaN encoding enable
  * 17     -> cause bit for unimplemented operation
  * 16     -> cause bit for invalid exception
  * 15     -> cause bit for division by zero exception
@@ -79,22 +81,33 @@ extern fpu_control_t __fpu_control;
 /* flush denormalized numbers to zero */
 #define _FPU_FLUSH_TZ   0x1000000
 
+/* IEEE 754-2008 compliance control.  */
+#define _FPU_ABS2008    0x80000
+#define _FPU_NAN2008    0x40000
+
 /* rounding control */
 #define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
 #define _FPU_RC_ZERO    0x1
 #define _FPU_RC_UP      0x2
 #define _FPU_RC_DOWN    0x3
 
-#define _FPU_RESERVED 0xfe9c0000  /* Reserved bits in cw */
+#define _FPU_RESERVED 0xfe840000  /* Reserved bits in cw, incl NAN2008.  */
 
 
 /* The fdlibm code requires strict IEEE double precision arithmetic,
    and no interrupts for exceptions, rounding to nearest.  */
+#ifdef __mips_nan2008
+# define _FPU_DEFAULT 0x00040000
+#else
+# define _FPU_DEFAULT 0x00000000
+#endif
 
-#define _FPU_DEFAULT  0x00000000
-
-/* IEEE:  same as above, but exceptions */
-#define _FPU_IEEE     0x00000F80
+/* IEEE: same as above, but exceptions.  */
+#ifdef __mips_nan2008
+# define _FPU_IEEE    0x00040F80
+#else
+# define _FPU_IEEE    0x00000F80
+#endif
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-10 00:18:22.018801136 +0100
@@ -24,15 +24,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/shlib-versions	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions	2013-09-10 00:18:22.018801136 +0100
@@ -3,7 +3,11 @@ mips.*-.*-linux.*	libm=6			GLIBC_2.0 GLI
 # Working mips versions were never released between 2.0 and 2.2.
 mips.*-.*-linux.*	libc=6			GLIBC_2.0 GLIBC_2.2
 
+%ifdef HAVE_MIPS_NAN2008
+mips.*-.*-linux.*	ld=ld-linux-mipsn8.so.1	GLIBC_2.0 GLIBC_2.2
+%else
 mips.*-.*-linux.*	ld=ld.so.1		GLIBC_2.0 GLIBC_2.2
+%endif
 mips.*-.*-linux.*	libdl=2			GLIBC_2.0 GLIBC_2.2
 
 mips.*-.*-linux.*	libresolv=2		GLIBC_2.0 GLIBC_2.2
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-10 00:18:22.018801136 +0100
@@ -21,15 +21,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-10 00:18:22.018801136 +0100
@@ -8,7 +8,9 @@ sysdep_routines += cachectl cacheflush s
 sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
 endif
 
-abi-variants := o32_soft o32_hard n32_soft n32_hard n64_soft n64_hard
+abi-variants := o32_soft o32_hard o32_soft_2008 o32_hard_2008
+abi-variants += n32_soft n32_hard n32_soft_2008 n32_hard_2008
+abi-variants += n64_soft n64_hard n64_soft_2008 n64_hard_2008
 
 ifeq (,$(filter $(default-abi),$(abi-variants)))
 Unknown ABI, must be one of $(abi-variants)
@@ -18,29 +20,89 @@ abi-includes := sgidefs.h
 
 # _MIPS_SIM_ABI32 == 1, _MIPS_SIM_NABI32 == 2, _MIPS_SIM_ABI64 == 3
 abi-o32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-o32_soft-condition := defined(__mips_soft_float) \
-			   && (_MIPS_SIM == _MIPS_SIM_ABI32)
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-o32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
+			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft-ld-soname := ld.so.1
 abi-o32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-o32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-o32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard-ld-soname := ld.so.1
+abi-o32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-o32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-o32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-o32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n32_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft-ld-soname := ld.so.1
 abi-n32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard-ld-soname := ld.so.1
+abi-n32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n64_soft-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n64_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n64_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft-ld-soname := ld.so.1
 abi-n64_hard-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n64_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n64_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard-ld-soname := ld.so.1
+abi-n64_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n64_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n64_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n64_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 
 ifeq ($(subdir),elf)
 ifeq ($(build-shared),yes)
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-10 00:27:40.429686137 +0100
@@ -105,8 +105,168 @@ if test -z "$libc_mips_float"; then
   as_fn_error $? "could not determine if compiler is using hard or soft floating point ABI" "$LINENO" 5
 fi
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
 config_vars="$config_vars
-default-abi = ${libc_mips_abi}_${libc_mips_float}"
+default-abi = ${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}"
 
 case "$prefix" in
 /usr | /usr/)
@@ -138,3 +298,12 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    # FIXME: Adjust this setting to the actual first upstream kernel
+    # version to support the 2008 NaN encoding and then remove this
+    # comment.
+    arch_minimum_kernel=10.0.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-10 00:27:26.428109202 +0100
@@ -44,7 +44,19 @@ if test -z "$libc_mips_float"; then
   AC_MSG_ERROR([could not determine if compiler is using hard or soft floating point ABI])
 fi
 
-LIBC_CONFIG_VAR([default-abi], [${libc_mips_abi}_${libc_mips_float}])
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
+LIBC_CONFIG_VAR([default-abi],
+  [${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}])
 
 case "$prefix" in
 /usr | /usr/)
@@ -76,3 +88,12 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    # FIXME: Adjust this setting to the actual first upstream kernel
+    # version to support the 2008 NaN encoding and then remove this
+    # comment.
+    arch_minimum_kernel=10.0.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-10 00:18:22.018801136 +0100
@@ -18,11 +18,27 @@
 
 #include <ldconfig.h>
 
-/* Redefine the cache ID for new ABIs; o32 keeps using the generic check.  */
-#if _MIPS_SIM == _ABI64
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
-#elif _MIPS_SIM == _ABIN32
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+
+/* Redefine the cache ID for new ABIs and 2008 NaN support; legacy o32
+   keeps using the generic check.  */
+#ifdef __mips_nan2008
+# if _MIPS_SIM == _ABIO32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32_NAN2008 | FLAG_ELF_LIBC6)
+# endif
+#else
+# if _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+# endif
 #endif
 
 #ifdef _DL_CACHE_DEFAULT_ID
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-10 00:18:22.018801136 +0100
@@ -33,19 +33,32 @@ process_elf_file (const char *file_name,
 		  unsigned int *osversion, char **soname, void *file_contents,
 		  size_t file_length)
 {
-  ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+  union
+    {
+      Elf64_Ehdr *eh64;
+      Elf32_Ehdr *eh32;
+      ElfW(Ehdr) *eh;
+    }
+  elf_header;
   int ret;
 
-  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+  elf_header.eh = file_contents;
+  if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32)
     {
-      Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
-
       ret = process_elf32_file (file_name, lib, flag, osversion, soname,
 				file_contents, file_length);
+      if (!ret)
+	{
+	  Elf32_Word flags = elf_header.eh32->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
 
-      /* n32 libraries are always libc.so.6+.  */
-      if (!ret && (elf32_header->e_flags & EF_MIPS_ABI2) != 0)
-	*flag = FLAG_MIPS64_LIBN32|FLAG_ELF_LIBC6;
+	  /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN.  */
+	  if ((flags & EF_MIPS_ABI2) != 0)
+	    *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008
+		     : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6;
+	  else if (nan2008)
+	    *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6;
+	}
     }
   else
     {
@@ -53,7 +66,13 @@ process_elf_file (const char *file_name,
 				file_contents, file_length);
       /* n64 libraries are always libc.so.6+.  */
       if (!ret)
-	*flag = FLAG_MIPS64_LIBN64|FLAG_ELF_LIBC6;
+	{
+	  Elf64_Word flags = elf_header.eh64->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
+
+	  *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008
+		   : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6;
+	}
     }
 
   return ret;
Index: glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/sysdeps/generic/ldconfig.h	2013-09-10 00:17:30.000000000 +0100
+++ glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h	2013-09-10 00:18:22.018801136 +0100
@@ -21,24 +21,27 @@
 
 #include <stdint.h>
 
-#define FLAG_ANY		-1
-#define FLAG_TYPE_MASK		0x00ff
-#define FLAG_LIBC4		0x0000
-#define FLAG_ELF		0x0001
-#define FLAG_ELF_LIBC5		0x0002
-#define FLAG_ELF_LIBC6		0x0003
-#define FLAG_REQUIRED_MASK	0xff00
-#define FLAG_SPARC_LIB64	0x0100
-#define FLAG_IA64_LIB64		0x0200
-#define FLAG_X8664_LIB64	0x0300
-#define FLAG_S390_LIB64		0x0400
-#define FLAG_POWERPC_LIB64	0x0500
-#define FLAG_MIPS64_LIBN32	0x0600
-#define FLAG_MIPS64_LIBN64	0x0700
-#define FLAG_X8664_LIBX32	0x0800
-#define FLAG_ARM_LIBHF		0x0900
-#define FLAG_AARCH64_LIB64	0x0a00
-#define FLAG_ARM_LIBSF		0x0b00
+#define FLAG_ANY			-1
+#define FLAG_TYPE_MASK			0x00ff
+#define FLAG_LIBC4			0x0000
+#define FLAG_ELF			0x0001
+#define FLAG_ELF_LIBC5			0x0002
+#define FLAG_ELF_LIBC6			0x0003
+#define FLAG_REQUIRED_MASK		0xff00
+#define FLAG_SPARC_LIB64		0x0100
+#define FLAG_IA64_LIB64			0x0200
+#define FLAG_X8664_LIB64		0x0300
+#define FLAG_S390_LIB64			0x0400
+#define FLAG_POWERPC_LIB64		0x0500
+#define FLAG_MIPS64_LIBN32		0x0600
+#define FLAG_MIPS64_LIBN64		0x0700
+#define FLAG_X8664_LIBX32		0x0800
+#define FLAG_ARM_LIBHF			0x0900
+#define FLAG_AARCH64_LIB64		0x0a00
+#define FLAG_ARM_LIBSF			0x0b00
+#define FLAG_MIPS_LIB32_NAN2008		0x0c00
+#define FLAG_MIPS64_LIBN32_NAN2008	0x0d00
+#define FLAG_MIPS64_LIBN64_NAN2008	0x0e00
 
 /* Name of auxiliary cache.  */
 #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v2] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-10  9:36       ` Maciej W. Rozycki
@ 2013-09-10 23:24         ` Joseph S. Myers
  2013-09-16 15:14           ` [PATCH v3] " Maciej W. Rozycki
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2013-09-10 23:24 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Doug Gilmore

On Tue, 10 Sep 2013, Maciej W. Rozycki wrote:

>  I infer you'd prefer to have this change committed even though the 
> required kernel part isn't there yet, right?  I have therefore set the 
> minimum version required artificially to 10.0.0 so that this code is not 
> accidentally activated on a kernel that doesn't support the 2008-NaN 
> feature and put a FIXME note next to it.  Please let me know if this is 
> what you had in mind.

Yes, using 10.0.0 here seems reasonable.

More generally, that would also seem appropriate if a new architecture 
port were submitted and approved before the kernel port is upstream.  
Rather than require a strict ordering of components going upstream 
(binutils, GCC, Linux kernel, glibc; GDB anywhere after binutils), lots of 
unnecessary delays can be avoided by each component reviewing 
independently, possibly in parallel, with the understanding that 
incompatible changes may still be possible if a component you depend on 
that's not yet upstream has such changes.  (Because of circular 
dependencies, you can't fully avoid that anyway; GCC for various 
architectures includes information about signal frames produced by the 
Linux kernel, for example.)

At the point when the kernel support goes upstream, the version in glibc 
can then be changed to reflect the correct upstream kernel version (in the 
case of new architecture ports, it's possible more __ASSUME_* macros may 
also be defined, or conditionals removed, based on what was in the kernel 
version that went upstream).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-10 23:24         ` Joseph S. Myers
@ 2013-09-16 15:14           ` Maciej W. Rozycki
  2013-09-16 15:26             ` Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-09-16 15:14 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: libc-ports, libc-alpha, Thomas Schwinge, Doug Gilmore

On Wed, 11 Sep 2013, Joseph S. Myers wrote:

> >  I infer you'd prefer to have this change committed even though the 
> > required kernel part isn't there yet, right?  I have therefore set the 
> > minimum version required artificially to 10.0.0 so that this code is not 
> > accidentally activated on a kernel that doesn't support the 2008-NaN 
> > feature and put a FIXME note next to it.  Please let me know if this is 
> > what you had in mind.
> 
> Yes, using 10.0.0 here seems reasonable.

 Thanks.  Here's a small update including a change made by Thomas that I 
missed in the original submission (sorry):

	* sysdeps/mips/math_private.h [__mips_nan2008]
	(HIGH_ORDER_BIT_IS_SET_FOR_SNAN): Don't define.
	* sysdeps/mips/bits/nan.h [__mips_nan2008] (NAN, __qnan_bytes):
	Define appropriately.

I hope that these changes are OK.  No regressions in o32/n64/n32 testing.

 OK for this version?

ChangeLog:

2013-09-14  Maciej W. Rozycki  <macro@codesourcery.com>

	* config.h.in (HAVE_MIPS_NAN2008): New macro.
	* elf/elf.h (EF_MIPS_NAN2008): Likewise.
	* sysdeps/generic/ldconfig.h (FLAG_MIPS_LIB32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN32_NAN2008): Likewise.
	(FLAG_MIPS64_LIBN64_NAN2008): Likewise.
	* elf/cache.c (print_entry): Handle the new cache flags.

ports/ChangeLog.mips:

2013-09-14  Maciej W. Rozycki  <macro@codesourcery.com>
	    Thomas Schwinge  <thomas@codesourcery.com>

	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NAN2008): New macro.
	(elf_machine_matches_host): Reject objects that use a different
	NaN encoding convention.
	* sysdeps/mips/fpu_control.h: Document IEEE 754-2008 feature 
	control bits.
	(_FPU_ABS2008, _FPU_NAN2008): New macros.
	(_FPU_RESERVED): Clear bits #20 and #19.
	(_FPU_DEFAULT) [__mips_nan2008]: Set bit #18.
	(_FPU_IEEE) [__mips_nan2008]: Likewise.
	* sysdeps/mips/math_private.h [__mips_nan2008]
	(HIGH_ORDER_BIT_IS_SET_FOR_SNAN): Don't define.
	* sysdeps/mips/bits/nan.h [__mips_nan2008] (NAN, __qnan_bytes):
	Define appropriately.
	* sysdeps/mips/mips64/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/mips/soft-fp/sfp-machine.h [__mips_nan2008]
	(_FP_NANFRAC_S, _FP_NANFRAC_D, _FP_NANFRAC_Q): Define 2008-NaN
	payloads.
	(_FP_QNANNEGATEDP): Set to 0.
	* sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID): 
	Define 2008 NaN encoding values.
	* sysdeps/unix/sysv/linux/mips/readelflib.c (process_elf_file):
	Handle 2008-NaN libraries.
	* sysdeps/mips/shlib-versions [HAVE_MIPS_NAN2008]: Set 
	ld=ld-linux-mipsn8.so.1.
	* sysdeps/mips/configure.in: Define HAVE_MIPS_NAN2008 if the
	2008 NaN encoding is used.
	* sysdeps/unix/sysv/linux/mips/Makefile (abi-variants): Add
	2008-NaN ABI variants.
	(abi-o32_soft-options, abi-o32_soft-condition): Update with the
	__mips_nan2008 macro.
	(abi-o32_hard-options, abi-o32_hard-condition): Likewise.
	(abi-n32_soft-options, abi-n32_soft-condition): Likewise.
	(abi-n32_hard-options, abi-n32_hard-condition): Likewise.
	(abi-n64_soft-options, abi-n64_soft-condition): Likewise.
	(abi-n64_hard-options, abi-n64_hard-condition): Likewise.
	(abi-o32_soft-ld-soname, abi-o32_hard-ld-soname): New macros.
	(abi-n32_soft-ld-soname, abi-n32_hard-ld-soname): Likewise.
	(abi-n64_soft-ld-soname, abi-n64_hard-ld-soname): Likewise.
	(abi-o32_soft_2008-options): Likewise.
	(abi-o32_soft_2008-condition): Likewise.
	(abi-o32_hard_2008-options): Likewise.
	(abi-o32_hard_2008-condition): Likewise.
	(abi-n32_soft_2008-options): Likewise.
	(abi-n32_soft_2008-condition): Likewise.
	(abi-n32_hard_2008-options): Likewise.
	(abi-n32_hard_2008-condition): Likewise.
	(abi-n64_soft_2008-options): Likewise.
	(abi-n64_soft_2008-condition): Likewise.
	(abi-n64_hard_2008-options): Likewise.
	(abi-n64_hard_2008-condition): Likewise.
	(abi-o32_soft_2008-ld-soname): Likewise.
	(abi-o32_hard_2008-ld-soname): Likewise.
	(abi-n32_soft_2008-ld-soname): Likewise.
	(abi-n32_hard_2008-ld-soname): Likewise.
	(abi-n64_soft_2008-ld-soname): Likewise.
	(abi-n64_hard_2008-ld-soname): Likewise.
	* sysdeps/unix/sysv/linux/mips/configure.in: Include the NaN
	encoding selection in default-abi.  Set arch_minimum_kernel to
	10.0.0 if 2008 NaN encoding is used.
	* sysdeps/mips/configure: Regenerate.
	* sysdeps/unix/sysv/linux/mips/configure: Regenerate.

  Maciej

glibc-mips-nan2008.diff
Index: glibc-fsf-trunk-quilt/config.h.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/config.h.in	2013-09-13 01:45:54.599688560 +0100
+++ glibc-fsf-trunk-quilt/config.h.in	2013-09-13 01:46:49.597642970 +0100
@@ -238,4 +238,8 @@
 /* The pt_chown binary is being built and used by grantpt.  */
 #undef HAVE_PT_CHOWN
 
+/* ports/sysdeps/mips/configure.in  */
+/* Define if using the IEEE 754-2008 NaN encoding on the MIPS target.  */
+#undef HAVE_MIPS_NAN2008
+
 #endif
Index: glibc-fsf-trunk-quilt/elf/cache.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/cache.c	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/elf/cache.c	2013-09-13 01:46:49.597642970 +0100
@@ -105,6 +105,15 @@ print_entry (const char *lib, int flag, 
     case FLAG_ARM_LIBSF:
       fputs (",soft-float", stdout);
       break;
+    case FLAG_MIPS_LIB32_NAN2008:
+      fputs (",nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN32_NAN2008:
+      fputs (",N32,nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN64_NAN2008:
+      fputs (",64bit,nan2008", stdout);
+      break;
     case 0:
       break;
     default:
Index: glibc-fsf-trunk-quilt/elf/elf.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/elf.h	2013-09-13 01:45:54.599688560 +0100
+++ glibc-fsf-trunk-quilt/elf/elf.h	2013-09-13 01:46:49.597642970 +0100
@@ -1383,6 +1383,7 @@ typedef struct
 #define EF_MIPS_64BIT_WHIRL	16
 #define EF_MIPS_ABI2		32
 #define EF_MIPS_ABI_ON32	64
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
 #define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
 
 /* Legal values for MIPS architecture level.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/bits/nan.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/bits/nan.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/bits/nan.h	2013-09-13 01:46:49.597642970 +0100
@@ -22,10 +22,11 @@
 
 
 /* IEEE Not A Number.  */
-/* Note that MIPS has the qNaN and sNaN patterns reversed compared to most
-   other architectures.  IEEE 754-1985 left the definition of this open to
-   implementations, and for MIPS the top bit of the mantissa must be SET to
-   indicate a sNaN.  */
+/* In legacy-NaN mode MIPS has the qNaN and sNaN patterns reversed
+   compared to most other architectures.  IEEE 754-1985 left the
+   definition of this open to implementations, and for MIPS the top bit
+   of the mantissa must be SET to indicate a sNaN.  In 2008-NaN mode
+   MIPS aligned to IEEE 754-2008.  */
 
 #if __GNUC_PREREQ(3,3)
 
@@ -33,20 +34,35 @@
 
 #elif defined __GNUC__
 
-# define NAN \
-  (__extension__							      \
-   ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; })  \
-    { __l: 0x7fbfffffUL }).__d)
+# ifdef __mips_nan2008
+#  define NAN \
+   (__extension__							      \
+    ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \
+     { __l: 0x7fc00000UL }).__d)
+# else
+#  define NAN \
+   (__extension__							      \
+    ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \
+     { __l: 0x7fbfffffUL }).__d)
+# endif
 
 #else
 
 # include <endian.h>
 
 # if __BYTE_ORDER == __BIG_ENDIAN
-#  define __qnan_bytes		{ 0x7f, 0xbf, 0xff, 0xff }
+#  ifdef __mips_nan2008
+#   define __qnan_bytes		{ 0x7f, 0xc0, 0, 0 }
+#  else
+#   define __qnan_bytes		{ 0x7f, 0xbf, 0xff, 0xff }
+#  endif
 # endif
 # if __BYTE_ORDER == __LITTLE_ENDIAN
-#  define __qnan_bytes		{ 0xff, 0xff, 0xbf, 0x7f }
+#  ifdef __mips_nan2008
+#   define __qnan_bytes		{ 0, 0, 0xc0, 0x7f }
+#  else
+#   define __qnan_bytes		{ 0xff, 0xff, 0xbf, 0x7f }
+#  endif
 # endif
 
 static union { unsigned char __c[4]; float __d; } __qnan_union
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure	2013-09-13 01:46:49.597642970 +0100
@@ -1,3 +1,163 @@
 # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/mips.
 
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+if test x$libc_cv_mips_nan2008 = xyes; then
+  $as_echo "#define HAVE_MIPS_NAN2008 1" >>confdefs.h
+
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/configure.in	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/configure.in	2013-09-13 01:46:49.597642970 +0100
@@ -4,3 +4,12 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the
 dnl No MIPS GCC supports accessing static and hidden symbols in an
 dnl position independent way.
 dnl AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+if test x$libc_cv_mips_nan2008 = xyes; then
+  AC_DEFINE(HAVE_MIPS_NAN2008)
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-machine.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h	2013-09-13 01:46:49.597642970 +0100
@@ -73,6 +73,16 @@ do { if ((l)->l_info[DT_MIPS (RLD_MAP)])
        (ElfW(Addr)) (r); \
    } while (0)
 
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+#ifdef __mips_nan2008
+# define ELF_MACHINE_NAN2008 EF_MIPS_NAN2008
+#else
+# define ELF_MACHINE_NAN2008 0
+#endif
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute_used__
 elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
@@ -83,6 +93,10 @@ elf_machine_matches_host (const ElfW(Ehd
     return 0;
 #endif
 
+  /* Don't link 2008-NaN and legacy-NaN objects together.  */
+  if ((ehdr->e_flags & EF_MIPS_NAN2008) != ELF_MACHINE_NAN2008)
+    return 0;
+
   switch (ehdr->e_machine)
     {
     case EM_MIPS:
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu_control.h	2013-09-13 01:45:54.000000000 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h	2013-09-13 01:46:49.597642970 +0100
@@ -29,7 +29,9 @@
  *           available for MIPS III and newer.
  * 23     -> Condition bit
  * 22-21  -> reserved for architecture implementers
- * 20-18  -> reserved (read as 0, write with 0)
+ * 20     -> reserved (read as 0, write with 0)
+ * 19     -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable
+ * 18     -> IEEE 754-2008 recommended NaN encoding enable
  * 17     -> cause bit for unimplemented operation
  * 16     -> cause bit for invalid exception
  * 15     -> cause bit for division by zero exception
@@ -79,22 +81,33 @@ extern fpu_control_t __fpu_control;
 /* flush denormalized numbers to zero */
 #define _FPU_FLUSH_TZ   0x1000000
 
+/* IEEE 754-2008 compliance control.  */
+#define _FPU_ABS2008    0x80000
+#define _FPU_NAN2008    0x40000
+
 /* rounding control */
 #define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
 #define _FPU_RC_ZERO    0x1
 #define _FPU_RC_UP      0x2
 #define _FPU_RC_DOWN    0x3
 
-#define _FPU_RESERVED 0xfe9c0000  /* Reserved bits in cw */
+#define _FPU_RESERVED 0xfe840000  /* Reserved bits in cw, incl NAN2008.  */
 
 
 /* The fdlibm code requires strict IEEE double precision arithmetic,
    and no interrupts for exceptions, rounding to nearest.  */
+#ifdef __mips_nan2008
+# define _FPU_DEFAULT 0x00040000
+#else
+# define _FPU_DEFAULT 0x00000000
+#endif
 
-#define _FPU_DEFAULT  0x00000000
-
-/* IEEE:  same as above, but exceptions */
-#define _FPU_IEEE     0x00000F80
+/* IEEE: same as above, but exceptions.  */
+#ifdef __mips_nan2008
+# define _FPU_IEEE    0x00040F80
+#else
+# define _FPU_IEEE    0x00000F80
+#endif
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/math_private.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/math_private.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/math_private.h	2013-09-13 01:46:49.597642970 +0100
@@ -18,9 +18,13 @@
 
 #ifndef _MATH_PRIVATE_H
 
+#ifdef __mips_nan2008
+/* MIPS aligned to IEEE 754-2008.  */
+#else
 /* One of the few architectures where the meaning of the quiet/signaling bit is
    inverse to IEEE 754-2008 (as well as common practice for IEEE 754-1985).  */
-#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+# define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+#endif
 
 #include_next <math_private.h>
 
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/soft-fp/sfp-machine.h	2013-09-13 01:46:49.597642970 +0100
@@ -24,15 +24,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1)
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/shlib-versions	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/shlib-versions	2013-09-13 01:46:49.597642970 +0100
@@ -3,7 +3,11 @@ mips.*-.*-linux.*	libm=6			GLIBC_2.0 GLI
 # Working mips versions were never released between 2.0 and 2.2.
 mips.*-.*-linux.*	libc=6			GLIBC_2.0 GLIBC_2.2
 
+%ifdef HAVE_MIPS_NAN2008
+mips.*-.*-linux.*	ld=ld-linux-mipsn8.so.1	GLIBC_2.0 GLIBC_2.2
+%else
 mips.*-.*-linux.*	ld=ld.so.1		GLIBC_2.0 GLIBC_2.2
+%endif
 mips.*-.*-linux.*	libdl=2			GLIBC_2.0 GLIBC_2.2
 
 mips.*-.*-linux.*	libresolv=2		GLIBC_2.0 GLIBC_2.2
Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/soft-fp/sfp-machine.h	2013-09-13 01:46:49.597642970 +0100
@@ -21,15 +21,25 @@
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
 #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
 
-#define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
-#define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
-#define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#ifdef __mips_nan2008
+# define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+# define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+# define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#else
+# define _FP_NANFRAC_S		(_FP_QNANBIT_S - 1)
+# define _FP_NANFRAC_D		(_FP_QNANBIT_D - 1), -1
+# define _FP_NANFRAC_Q		(_FP_QNANBIT_Q - 1), -1, -1, -1
+#endif
 #define _FP_NANSIGN_S		0
 #define _FP_NANSIGN_D		0
 #define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 1
+#ifdef __mips_nan2008
+# define _FP_QNANNEGATEDP 0
+#else
+# define _FP_QNANNEGATEDP 1
+#endif
 
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/Makefile	2013-09-13 01:46:49.597642970 +0100
@@ -8,7 +8,9 @@ sysdep_routines += cachectl cacheflush s
 sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
 endif
 
-abi-variants := o32_soft o32_hard n32_soft n32_hard n64_soft n64_hard
+abi-variants := o32_soft o32_hard o32_soft_2008 o32_hard_2008
+abi-variants += n32_soft n32_hard n32_soft_2008 n32_hard_2008
+abi-variants += n64_soft n64_hard n64_soft_2008 n64_hard_2008
 
 ifeq (,$(filter $(default-abi),$(abi-variants)))
 Unknown ABI, must be one of $(abi-variants)
@@ -18,29 +20,89 @@ abi-includes := sgidefs.h
 
 # _MIPS_SIM_ABI32 == 1, _MIPS_SIM_NABI32 == 2, _MIPS_SIM_ABI64 == 3
 abi-o32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-o32_soft-condition := defined(__mips_soft_float) \
-			   && (_MIPS_SIM == _MIPS_SIM_ABI32)
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-o32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
+			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft-ld-soname := ld.so.1
 abi-o32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-o32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-o32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard-ld-soname := ld.so.1
+abi-o32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-o32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-o32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-o32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI32)
+abi-o32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n32_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n32_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft-ld-soname := ld.so.1
 abi-n32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n32_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n32_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard-ld-soname := ld.so.1
+abi-n32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n32_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n32_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_NABI32)
+abi-n32_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 abi-n64_soft-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_soft_float -U__mips_hard_float
-abi-n64_soft-condition := defined(__mips_soft_float) \
+			-D__mips_soft_float -U__mips_hard_float \
+			-U__mips_nan2008
+abi-n64_soft-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_soft_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft-ld-soname := ld.so.1
 abi-n64_hard-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
-			-D__mips_hard_float -U__mips_soft_float
-abi-n64_hard-condition := defined(__mips_hard_float) \
+			-D__mips_hard_float -U__mips_soft_float \
+			-U__mips_nan2008
+abi-n64_hard-condition := !defined(__mips_nan2008) \
+			  && defined(__mips_hard_float) \
 			  && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard-ld-soname := ld.so.1
+abi-n64_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_soft_float -U__mips_hard_float \
+			     -D__mips_nan2008
+abi-n64_soft_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_soft_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_soft_2008-ld-soname := ld-linux-mipsn8.so.1
+abi-n64_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \
+			     -D__mips_hard_float -U__mips_soft_float \
+			     -D__mips_nan2008
+abi-n64_hard_2008-condition := defined(__mips_nan2008) \
+			       && defined(__mips_hard_float) \
+			       && (_MIPS_SIM == _MIPS_SIM_ABI64)
+abi-n64_hard_2008-ld-soname := ld-linux-mipsn8.so.1
 
 ifeq ($(subdir),elf)
 ifeq ($(build-shared),yes)
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure	2013-09-13 01:46:49.597642970 +0100
@@ -105,8 +105,168 @@ if test -z "$libc_mips_float"; then
   as_fn_error $? "could not determine if compiler is using hard or soft floating point ABI" "$LINENO" 5
 fi
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5
+$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; }
+if ${libc_cv_mips_nan2008+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+dnl
+#ifdef __mips_nan2008
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_mips_nan2008=yes
+else
+  libc_cv_mips_nan2008=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5
+$as_echo "$libc_cv_mips_nan2008" >&6; }
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
 config_vars="$config_vars
-default-abi = ${libc_mips_abi}_${libc_mips_float}"
+default-abi = ${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}"
 
 case "$prefix" in
 /usr | /usr/)
@@ -138,3 +298,12 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    # FIXME: Adjust this setting to the actual first upstream kernel
+    # version to support the 2008 NaN encoding and then remove this
+    # comment.
+    arch_minimum_kernel=10.0.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/configure.in	2013-09-13 01:46:49.597642970 +0100
@@ -44,7 +44,19 @@ if test -z "$libc_mips_float"; then
   AC_MSG_ERROR([could not determine if compiler is using hard or soft floating point ABI])
 fi
 
-LIBC_CONFIG_VAR([default-abi], [${libc_mips_abi}_${libc_mips_float}])
+AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
+  libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl
+#ifdef __mips_nan2008
+yes
+#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)])
+
+libc_mips_nan=
+if test x"$libc_cv_mips_nan2008" = xyes; then
+  libc_mips_nan=_2008
+fi
+
+LIBC_CONFIG_VAR([default-abi],
+  [${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}])
 
 case "$prefix" in
 /usr | /usr/)
@@ -76,3 +88,12 @@ case "$prefix" in
 esac
 
 libc_cv_gcc_unwind_find_fde=yes
+
+if test -z "$arch_minimum_kernel"; then
+  if test x$libc_cv_mips_nan2008 = xyes; then
+    # FIXME: Adjust this setting to the actual first upstream kernel
+    # version to support the 2008 NaN encoding and then remove this
+    # comment.
+    arch_minimum_kernel=10.0.0
+  fi
+fi
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h	2013-09-13 01:46:49.597642970 +0100
@@ -18,11 +18,27 @@
 
 #include <ldconfig.h>
 
-/* Redefine the cache ID for new ABIs; o32 keeps using the generic check.  */
-#if _MIPS_SIM == _ABI64
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
-#elif _MIPS_SIM == _ABIN32
-# define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \
+     || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008))
+# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?"
+#endif
+
+/* Redefine the cache ID for new ABIs and 2008 NaN support; legacy o32
+   keeps using the generic check.  */
+#ifdef __mips_nan2008
+# if _MIPS_SIM == _ABIO32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64_NAN2008 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32_NAN2008 | FLAG_ELF_LIBC6)
+# endif
+#else
+# if _MIPS_SIM == _ABI64
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6)
+# elif _MIPS_SIM == _ABIN32
+#  define _DL_CACHE_DEFAULT_ID	(FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6)
+# endif
 #endif
 
 #ifdef _DL_CACHE_DEFAULT_ID
Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/readelflib.c	2013-09-13 01:46:49.597642970 +0100
@@ -33,19 +33,32 @@ process_elf_file (const char *file_name,
 		  unsigned int *osversion, char **soname, void *file_contents,
 		  size_t file_length)
 {
-  ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+  union
+    {
+      Elf64_Ehdr *eh64;
+      Elf32_Ehdr *eh32;
+      ElfW(Ehdr) *eh;
+    }
+  elf_header;
   int ret;
 
-  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+  elf_header.eh = file_contents;
+  if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32)
     {
-      Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
-
       ret = process_elf32_file (file_name, lib, flag, osversion, soname,
 				file_contents, file_length);
+      if (!ret)
+	{
+	  Elf32_Word flags = elf_header.eh32->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
 
-      /* n32 libraries are always libc.so.6+.  */
-      if (!ret && (elf32_header->e_flags & EF_MIPS_ABI2) != 0)
-	*flag = FLAG_MIPS64_LIBN32|FLAG_ELF_LIBC6;
+	  /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN.  */
+	  if ((flags & EF_MIPS_ABI2) != 0)
+	    *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008
+		     : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6;
+	  else if (nan2008)
+	    *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6;
+	}
     }
   else
     {
@@ -53,7 +66,13 @@ process_elf_file (const char *file_name,
 				file_contents, file_length);
       /* n64 libraries are always libc.so.6+.  */
       if (!ret)
-	*flag = FLAG_MIPS64_LIBN64|FLAG_ELF_LIBC6;
+	{
+	  Elf64_Word flags = elf_header.eh64->e_flags;
+	  int nan2008 = (flags & EF_MIPS_NAN2008) != 0;
+
+	  *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008
+		   : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6;
+	}
     }
 
   return ret;
Index: glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h
===================================================================
--- glibc-fsf-trunk-quilt.orig/sysdeps/generic/ldconfig.h	2013-09-13 01:42:20.637954668 +0100
+++ glibc-fsf-trunk-quilt/sysdeps/generic/ldconfig.h	2013-09-13 01:46:49.597642970 +0100
@@ -21,24 +21,27 @@
 
 #include <stdint.h>
 
-#define FLAG_ANY		-1
-#define FLAG_TYPE_MASK		0x00ff
-#define FLAG_LIBC4		0x0000
-#define FLAG_ELF		0x0001
-#define FLAG_ELF_LIBC5		0x0002
-#define FLAG_ELF_LIBC6		0x0003
-#define FLAG_REQUIRED_MASK	0xff00
-#define FLAG_SPARC_LIB64	0x0100
-#define FLAG_IA64_LIB64		0x0200
-#define FLAG_X8664_LIB64	0x0300
-#define FLAG_S390_LIB64		0x0400
-#define FLAG_POWERPC_LIB64	0x0500
-#define FLAG_MIPS64_LIBN32	0x0600
-#define FLAG_MIPS64_LIBN64	0x0700
-#define FLAG_X8664_LIBX32	0x0800
-#define FLAG_ARM_LIBHF		0x0900
-#define FLAG_AARCH64_LIB64	0x0a00
-#define FLAG_ARM_LIBSF		0x0b00
+#define FLAG_ANY			-1
+#define FLAG_TYPE_MASK			0x00ff
+#define FLAG_LIBC4			0x0000
+#define FLAG_ELF			0x0001
+#define FLAG_ELF_LIBC5			0x0002
+#define FLAG_ELF_LIBC6			0x0003
+#define FLAG_REQUIRED_MASK		0xff00
+#define FLAG_SPARC_LIB64		0x0100
+#define FLAG_IA64_LIB64			0x0200
+#define FLAG_X8664_LIB64		0x0300
+#define FLAG_S390_LIB64			0x0400
+#define FLAG_POWERPC_LIB64		0x0500
+#define FLAG_MIPS64_LIBN32		0x0600
+#define FLAG_MIPS64_LIBN64		0x0700
+#define FLAG_X8664_LIBX32		0x0800
+#define FLAG_ARM_LIBHF			0x0900
+#define FLAG_AARCH64_LIB64		0x0a00
+#define FLAG_ARM_LIBSF			0x0b00
+#define FLAG_MIPS_LIB32_NAN2008		0x0c00
+#define FLAG_MIPS64_LIBN32_NAN2008	0x0d00
+#define FLAG_MIPS64_LIBN64_NAN2008	0x0e00
 
 /* Name of auxiliary cache.  */
 #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-16 15:14           ` [PATCH v3] " Maciej W. Rozycki
@ 2013-09-16 15:26             ` Joseph S. Myers
  2013-09-18 20:48               ` Maciej W. Rozycki
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2013-09-16 15:26 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-ports, libc-alpha, Thomas Schwinge, Doug Gilmore

On Mon, 16 Sep 2013, Maciej W. Rozycki wrote:

>  Thanks.  Here's a small update including a change made by Thomas that I 
> missed in the original submission (sorry):
> 
> 	* sysdeps/mips/math_private.h [__mips_nan2008]
> 	(HIGH_ORDER_BIT_IS_SET_FOR_SNAN): Don't define.
> 	* sysdeps/mips/bits/nan.h [__mips_nan2008] (NAN, __qnan_bytes):
> 	Define appropriately.
> 
> I hope that these changes are OK.  No regressions in o32/n64/n32 testing.
> 
>  OK for this version?

OK, though the bits/nan.h change in the case for pre-3.3 GCC is redundant 
since no such GCC will define __mips_nan2008.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3] MIPS: IEEE 754-2008 NaN encoding support
  2013-09-16 15:26             ` Joseph S. Myers
@ 2013-09-18 20:48               ` Maciej W. Rozycki
  0 siblings, 0 replies; 19+ messages in thread
From: Maciej W. Rozycki @ 2013-09-18 20:48 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: libc-ports, libc-alpha, Thomas Schwinge, Doug Gilmore

On Mon, 16 Sep 2013, Joseph S. Myers wrote:

> >  Thanks.  Here's a small update including a change made by Thomas that I 
> > missed in the original submission (sorry):
> > 
> > 	* sysdeps/mips/math_private.h [__mips_nan2008]
> > 	(HIGH_ORDER_BIT_IS_SET_FOR_SNAN): Don't define.
> > 	* sysdeps/mips/bits/nan.h [__mips_nan2008] (NAN, __qnan_bytes):
> > 	Define appropriately.
> > 
> > I hope that these changes are OK.  No regressions in o32/n64/n32 testing.
> > 
> >  OK for this version?
> 
> OK, though the bits/nan.h change in the case for pre-3.3 GCC is redundant 
> since no such GCC will define __mips_nan2008.

 I've been pondering about that part, in particular whether as an 
alternative we'd need a #error directive to catch the unsupported 
__mips_nan2008/pre-3.3-GCC case.  Eventually I decided to propose it as 
is, as it is technically correct, however without any explicit mention of 
it so as not to suggest anything.  Now that you've questioned it by 
yourself, I have replaced that hunk altogether with a informational note:

/* No 2008-NaN mode support in any GCC version before 4.9.  */

 I have applied this change now, with this adjustment made.  Thanks for 
your review.

  Maciej

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2013-09-18 20:48 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-22 23:53 [RFC][PATCH] MIPS: IEEE 754-2008 NaN encoding support Maciej W. Rozycki
2013-08-23  0:58 ` Rich Felker
2013-08-23  1:41   ` Maciej W. Rozycki
2013-08-23  1:57     ` Rich Felker
2013-08-23  3:11       ` pinskia
2013-08-23  3:38         ` Rich Felker
2013-08-23  4:08           ` pinskia
2013-08-23  4:12             ` Rich Felker
2013-08-23  4:10     ` Rich Felker
2013-08-23  3:46 ` Rich Felker
2013-08-23 10:53   ` Maciej W. Rozycki
2013-08-23 15:26 ` Joseph S. Myers
2013-09-05 22:47   ` [RFC][PATCH v2] " Maciej W. Rozycki
2013-09-06 16:24     ` Joseph S. Myers
2013-09-10  9:36       ` Maciej W. Rozycki
2013-09-10 23:24         ` Joseph S. Myers
2013-09-16 15:14           ` [PATCH v3] " Maciej W. Rozycki
2013-09-16 15:26             ` Joseph S. Myers
2013-09-18 20:48               ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).