Subject: [RESUME] fpu emulator

From: Florian Lohoff <[email-masked]>
Date: Thu, 8 Feb 2001 12:20:30 +0100

Hi,
just to get it right - As i thought the FPU emulator is not really
optional - It is even required for fpu-enabled devices which means
we should clean the code in that way that if the user decides to 
compile in the fpu emulator into the kernel we do an autodetection 
upfront and change some of the entry/exit/lazy_fpu stuff.
If the user decides not to compile in the FPU Emulator he is on his
own and we ignore the whole FPU stuff and simply send SIGILL/SIGFPE
to the processes causing all fpu binarys to fail on non-fpu enabled
kernels.

Flo
-- 
Florian Lohoff                  [email-masked]             +49-5201-669912
     Why is it called "common sense" when nobody seems to have any?

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Thu, 8 Feb 2001 12:43:30 +0100

> to the processes causing all fpu binarys to fail on non-fpu enabled

Not quite.  Unless we create a variant of glibc that neither
initializes the FP control register on program startup, nor
saves/restores the FP registers in setjmp/longjmp, the
model of "simply sending SIGILL/SIGFPE" will result
in *all* processes being terminated with extreme prejudice,
starting with init!

            Regards,

            Kevin K.

---

From: Andreas Jaeger <[email-masked]>
Date: 08 Feb 2001 13:06:29 +0100

> initializes the FP control register on program startup, nor

glibc doesn't initialize it for shared programs.

> saves/restores the FP registers in setjmp/longjmp, the

Any ideas how this can be done?

> in *all* processes being terminated with extreme prejudice,

Andreas
-- 
 Andreas Jaeger
  SuSE Labs [email-masked]
   private [email-masked]
    http://www.suse.de/~aj

---

From: Florian Lohoff <[email-masked]>
Date: Thu, 8 Feb 2001 13:33:39 +0100

> in *all* processes being terminated with extreme prejudice,

Which is exactly i was trying to establish as when the fpu emulator
is not enabled the user should build a complete fp less userspace. And
when we edstablish the SIGILL/SIGFPE he is forced to do so which is
a "good thing(tm)"

Flo

---

From: Jun Sun <[email-masked]>
Date: Thu, 08 Feb 2001 12:42:40 -0800

Andreas Jaeger wrote:
 
> > in *all* processes being terminated with extreme prejudice,

There is a patch for glibc2.0.7, which I think was done by Jay Carlson.  It
basically works for glibc2.0.6 as well.  See the one for glibc2.0.6 attached
below.

I think the patch is not "clean", in the sense that you only want to apply it
if you want to configure with "--without-fp".  Otherwise the patch will break
other configurations.

Jun

--- glibc-2.0.6/sysdeps/mips/__longjmp.c.orig-rpm	Sat Sep 11 00:01:44 1999
+++ glibc-2.0.6/sysdeps/mips/__longjmp.c	Sat Sep 11 00:02:36 1999
@@ -35,6 +35,7 @@
      along the way.  */
   register int val asm ("a1");
 
+#ifdef __HAVE_FPU__
   /* Pull back the floating point callee-saved registers.  */
   asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
   asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1]));
@@ -42,13 +43,16 @@
   asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3]));
   asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
   asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+#endif
   
   /* Restore the stack pointer.  */
   asm volatile ("lw $29, %0" : : "m" (env[0].__sp));
 
+#ifdef __HAVE_FPU__
   /* Get and reconstruct the floating point csr.  */
   asm volatile ("lw $2, %0" : : "m" (env[0].__fpc_csr));
   asm volatile ("ctc1 $2, $31");
+#endif
 
   /* Get the FP.  */
   asm volatile ("lw $30, %0" : : "m" (env[0].__fp));
--- glibc-2.0.6/sysdeps/mips/setjmp_aux.c.orig-rpm	Sat Sep 11 00:04:00 1999
+++ glibc-2.0.6/sysdeps/mips/setjmp_aux.c	Sat Sep 11 00:04:24 1999
@@ -26,6 +26,7 @@
 int
 __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
 {
+#ifdef __HAVE_FPU__
   /* Store the floating point callee-saved registers...  */
   asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
   asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
@@ -33,6 +34,7 @@
   asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
   asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
   asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#endif
 
   /* .. and the PC;  */
   asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
@@ -56,8 +58,10 @@
   asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
   asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
 
+#ifdef __HAVE_FPU__
   /* .. and finally get and reconstruct the floating point csr.  */
   asm ("cfc1 %0, $31" : "=r" (env[0].__jmpbuf[0].__fpc_csr));
+#endif
 
   /* Save the signal mask if requested.  */
   return __sigjmp_save (env, savemask);
--- glibc-2.0.6/sysdeps/mips/fpu_control.h.orig-rpm	Sat Sep 11 00:18:51 1999
+++ glibc-2.0.6/sysdeps/mips/fpu_control.h	Sat Sep 11 00:10:44 1999
@@ -83,8 +83,13 @@
 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
 
 /* Macros for accessing the hardware control word.  */
+#ifdef __HAVE_FPU__
 #define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw) : )
 #define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
+#else
+#define _FPU_GETCW(cw) (_FPU_DEFAULT)
+#define _FPU_SETCW(cw) 
+#endif
 
 /* Default control word set at startup.  */
 extern fpu_control_t __fpu_control;

---

From: Andreas Jaeger <[email-masked]>
Date: 09 Feb 2001 10:17:05 +0100

Jun Sun <[email-masked]> writes:

> Jun--- glibc-2.0.6/sysdeps/mips/__longjmp.c.orig-rpm	Sat Sep 11 00:01:44 1999

I looked through the whole of glibc and GCC and __HAVE_FPU__ is nowhere
defined for MIPS.  __HAVE_FPU__ is defined for m68k in GCC but that's
the only platform.

Therefore I don't think the patch makes any sense at all,
Andreas

---

From: Jun Sun <[email-masked]>
Date: Fri, 09 Feb 2001 11:30:57 -0800

> defined for MIPS.  __HAVE_FPU__ is defined for m68k in GCC but that's

You are right - it is not defined in glibc.  Instead it is defined in egcs. 
For this particular build, I need to apply the mips patch for egcs 1.0.3a,
which supplies __HAVE_FPU__.  You can find it somewhere on oss.sgi site. 
There is an additional patch for softfloat which makes __HAVE_FPU__
conditional.  See the attachement.
 
> Therefore I don't think the patch makes any sense at all,

Therefore, it does make sense. :-)

Jun

--- egcs-1.0.3a/gcc/config/mips/t-linux.orig	Mon Sep  6 21:38:16 1999
+++ egcs-1.0.3a/gcc/config/mips/t-linux	Wed Sep  8 08:43:58 1999
@@ -9,8 +9,28 @@
 LIBGCC1 =
 CROSS_LIBGCC1 =
 
-MULTILIB_OPTIONS= EL/EB
-MULTILIB_DIRNAMES= el eb
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#ifdef __MIPSEL__' > dp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+	echo '#endif' >> dp-bit.c
+	echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#define FLOAT' > fp-bit.c
+	echo '#ifdef __MIPSEL__' >> fp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+	echo '#endif' >> fp-bit.c
+	echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+
+MULTILIB_OPTIONS= EL/EB msoft-float
+MULTILIB_DIRNAMES= el eb soft-float
 MULTILIB_MATCHES=
 MULTILIB_EXCEPTIONS=
 
--- egcs-1.0.3a/gcc/config/mips/linux.h.orig	Mon Sep  6 21:38:16 1999
+++ egcs-1.0.3a/gcc/config/mips/linux.h	Wed Sep  8 08:43:40 1999
@@ -82,7 +82,7 @@
 %{!mabi*: -U__mips64} \
 %{fno-PIC:-U__PIC__ -U__pic__} %{fno-pic:-U__PIC__ -U__pic__} \
 %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
-%{-D__HAVE_FPU__ } \
+%{!msoft-float: -D__HAVE_FPU__ } \
 %{posix:-D_POSIX_SOURCE} \
 %{pthread:-D_REENTRANT}"
 
@@ -756,3 +756,7 @@
 
 #undef	MAX_WCHAR_TYPE_SIZE
 #define MAX_WCHAR_TYPE_SIZE	MAX_LONG_TYPE_SIZE
+
+/* US Software GOFAST library support.  */
+#include "gofast.h"
+#define INIT_TARGET_OPTABS INIT_GOFAST_OPTABS

---

From: Andreas Jaeger <[email-masked]>
Date: 09 Feb 2001 21:31:18 +0100

> Therefore, it does make sense. :-)

As long as that old patch hasn't found it's way into the official
sources, the patch doesn't make sense ;-).  I'm willing to discuss
these issues again after those or similar patches have been added to
the CVS archive of GCC - but without this, there's no way to get the
patches into glibc.

Andreas

---

From: Jun Sun <[email-masked]>
Date: Fri, 09 Feb 2001 13:09:50 -0800

> the CVS archive of GCC - but without this, there's no way to get the

Well, like I said earlier.  This is not a clean patch - it cannot be checked
in because it will break other configurations, AFAIK.  (OK, I probably should
have called it *hack* from the beginning :-0)

It would be nice to have some clean solutions...

Jun