## Automatically generated incremental diff
## From:   linux-2.2.14-pre6
## To:     linux-2.2.14-pre7
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.2.14-pre6/arch/alpha/Makefile linux-2.2.14-pre7/arch/alpha/Makefile
--- linux-2.2.14-pre6/arch/alpha/Makefile	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/alpha/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -116,11 +116,9 @@
 	@$(MAKEBOOT) clean
 
 archmrproper:
-	-$(MAKE) -C arch/alpha/math-emu cleansymlinks
 
 archdep:
 	@$(MAKEBOOT) dep
-	-$(MAKE) -C arch/alpha/math-emu symlinks
 
 bootpfile:
 	@$(MAKEBOOT) bootpfile
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/double.h linux-2.2.14-pre7/arch/alpha/math-emu/double.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/double.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/double.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,129 @@
+/*
+ * Definitions for IEEE Double Precision
+ */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_D		(2 * _FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_D		_FP_W_TYPE_SIZE
+#endif
+
+#define _FP_FRACBITS_D		53
+#define _FP_FRACXBITS_D		(_FP_FRACTBITS_D - _FP_FRACBITS_D)
+#define _FP_WFRACBITS_D		(_FP_WORKBITS + _FP_FRACBITS_D)
+#define _FP_WFRACXBITS_D	(_FP_FRACTBITS_D - _FP_WFRACBITS_D)
+#define _FP_EXPBITS_D		11
+#define _FP_EXPBIAS_D		1023
+#define _FP_EXPMAX_D		2047
+
+#define _FP_QNANBIT_D		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_D		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_D		\
+	((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_D
+{
+  double flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+#else
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned sign  : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)		_FP_DECL(2,X)
+#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_2(D,X,val)
+#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_2(D,val,X)
+
+#define FP_UNPACK_D(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_2(D,X,val);		\
+    _FP_UNPACK_CANONICAL(D,2,X);	\
+  } while (0)
+
+#define FP_PACK_D(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,2,X);		\
+    _FP_PACK_RAW_2(D,val,X);		\
+  } while (0)
+
+#define FP_NEG_D(R,X)		_FP_NEG(D,2,R,X)
+#define FP_ADD_D(R,X,Y)		_FP_ADD(D,2,R,X,Y)
+#define FP_SUB_D(R,X,Y)		_FP_SUB(D,2,R,X,Y)
+#define FP_MUL_D(R,X,Y)		_FP_MUL(D,2,R,X,Y)
+#define FP_DIV_D(R,X,Y)		_FP_DIV(D,2,R,X,Y)
+#define FP_SQRT_D(R,X)		_FP_SQRT(D,2,R,X)
+
+#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,2,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,2,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,2,X,r,rs,rt)
+
+#else
+
+union _FP_UNION_D
+{
+  double flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+#else
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)		_FP_DECL(1,X)
+#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_1(D,X,val)
+#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_1(D,val,X)
+
+#define FP_UNPACK_D(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1(D,X,val);		\
+    _FP_UNPACK_CANONICAL(D,1,X);	\
+  } while (0)
+
+#define FP_PACK_D(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,1,X);		\
+    _FP_PACK_RAW_1(D,val,X);		\
+  } while (0)
+
+#define FP_NEG_D(R,X)		_FP_NEG(D,1,R,X)
+#define FP_ADD_D(R,X,Y)		_FP_ADD(D,1,R,X,Y)
+#define FP_SUB_D(R,X,Y)		_FP_SUB(D,1,R,X,Y)
+#define FP_MUL_D(R,X,Y)		_FP_MUL(D,1,R,X,Y)
+#define FP_DIV_D(R,X,Y)		_FP_DIV(D,1,R,X,Y)
+#define FP_SQRT_D(R,X)		_FP_SQRT(D,1,R,X)
+
+/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
+   the target machine.  */
+
+#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,1,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,1,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,1,X,r,rs,rt)
+
+#endif /* W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/Makefile linux-2.2.14-pre7/arch/alpha/math-emu/Makefile
--- linux-2.2.14-pre6/arch/alpha/math-emu/Makefile	1999-08-25 17:29:45.000000000 -0700
+++ linux-2.2.14-pre7/arch/alpha/math-emu/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -5,17 +5,8 @@
 O_TARGET :=	math-emu.o
 O_OBJS   :=	fp-emul.o udivmodti4.o
 
-LINKS	:=	double.h op-common.h op-1.h op-2.h op-4.h single.h \
-		soft-fp.h udivmodti4.c
-
 ifeq ($(CONFIG_MATHEMU),m)
 M_OBJS   := $(O_TARGET)
 endif
 
 include $(TOPDIR)/Rules.make
-
-symlinks:
-	ln -sf $(patsubst %,../../sparc64/math-emu/%,$(LINKS)) .
-
-cleansymlinks:
-	rm -f $(LINKS)
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/op-1.h linux-2.2.14-pre7/arch/alpha/math-emu/op-1.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/op-1.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/op-1.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,245 @@
+/*
+ * Basic one-word fraction declaration and manipulation.
+ */
+
+#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
+#define _FP_FRAC_COPY_1(D,S)	(D##_f = S##_f)
+#define _FP_FRAC_SET_1(X,I)	(X##_f = I)
+#define _FP_FRAC_HIGH_1(X)	(X##_f)
+#define _FP_FRAC_LOW_1(X)	(X##_f)
+#define _FP_FRAC_WORD_1(X,w)	(X##_f)
+
+#define _FP_FRAC_ADDI_1(X,I)	(X##_f += I)
+#define _FP_FRAC_SLL_1(X,N)			\
+  do {						\
+    if (__builtin_constant_p(N) && (N) == 1)	\
+      X##_f += X##_f;				\
+    else					\
+      X##_f <<= (N);				\
+  } while (0)
+#define _FP_FRAC_SRL_1(X,N)	(X##_f >>= N)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRS_1(X,N,sz)	__FP_FRAC_SRS_1(X##_f, N, sz)
+
+#define __FP_FRAC_SRS_1(X,N,sz)						\
+   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1		\
+		     ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
+
+#define _FP_FRAC_ADD_1(R,X,Y)	(R##_f = X##_f + Y##_f)
+#define _FP_FRAC_SUB_1(R,X,Y)	(R##_f = X##_f - Y##_f)
+#define _FP_FRAC_CLZ_1(z, X)	__FP_CLZ(z, X##_f)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
+#define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
+#define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
+#define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
+#define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
+
+#define _FP_ZEROFRAC_1		0
+#define _FP_MINFRAC_1		1
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_1(fs, X, val)				\
+  do {								\
+    union _FP_UNION_##fs _flo; _flo.flt = (val);		\
+								\
+    X##_f = _flo.bits.frac;					\
+    X##_e = _flo.bits.exp;					\
+    X##_s = _flo.bits.sign;					\
+  } while (0)
+
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_1(fs, val, X)				\
+  do {								\
+    union _FP_UNION_##fs _flo;					\
+								\
+    _flo.bits.frac = X##_f;					\
+    _flo.bits.exp  = X##_e;					\
+    _flo.bits.sign = X##_s;					\
+								\
+    (val) = _flo.flt;						\
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   multiplication immediately.  */
+
+#define _FP_MUL_MEAT_1_imm(fs, R, X, Y)					\
+  do {									\
+    R##_f = X##_f * Y##_f;						\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
+  } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit)				\
+  do {									\
+    _FP_W_TYPE _Z_f0, _Z_f1;						\
+    doit(_Z_f1, _Z_f0, X##_f, Y##_f);					\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
+    R##_f = _Z_f0;							\
+  } while (0)
+
+/* Finally, a simple widening multiply algorithm.  What fun!  */
+
+#define _FP_MUL_MEAT_1_hard(fs, R, X, Y)				\
+  do {									\
+    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;		\
+									\
+    /* split the words in half */					\
+    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);					\
+    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
+    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);					\
+    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
+									\
+    /* multiply the pieces */						\
+    _z_f0 = _xl * _yl;							\
+    _a_f0 = _xh * _yl;							\
+    _a_f1 = _xl * _yh;							\
+    _z_f1 = _xh * _yh;							\
+									\
+    /* reassemble into two full words */				\
+    if ((_a_f0 += _a_f1) < _a_f1)					\
+      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
+    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);				\
+    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);				\
+    _FP_FRAC_ADD_2(_z, _z, _a);						\
+									\
+    /* normalize */							\
+    _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs);	\
+    R##_f = _z_f0;							\
+  } while (0)
+
+
+/*
+ * Division algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   division immediately.  Give this macro either _FP_DIV_HELP_imm for
+   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
+   choose will depend on what the compiler does with divrem4.  */
+
+#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)		\
+  do {							\
+    _FP_W_TYPE _q, _r;					\
+    X##_f <<= (X##_f < Y##_f				\
+	       ? R##_e--, _FP_WFRACBITS_##fs		\
+	       : _FP_WFRACBITS_##fs - 1);		\
+    doit(_q, _r, X##_f, Y##_f);				\
+    R##_f = _q | (_r != 0);				\
+  } while (0)
+
+/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
+   that may be useful in this situation.  This first is for a primitive
+   that requires normalization, the second for one that does not.  Look
+   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
+
+#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)				\
+  do {									\
+    _FP_W_TYPE _nh, _nl, _q, _r;					\
+									\
+    /* Normalize Y -- i.e. make the most significant bit set.  */	\
+    Y##_f <<= _FP_WFRACXBITS_##fs - 1;					\
+									\
+    /* Shift X op correspondingly high, that is, up one full word.  */	\
+    if (X##_f <= Y##_f)							\
+      {									\
+	_nl = 0;							\
+	_nh = X##_f;							\
+      }									\
+    else								\
+      {									\
+	R##_e++;							\
+	_nl = X##_f << (_FP_W_TYPE_SIZE-1);				\
+	_nh = X##_f >> 1;						\
+      }									\
+    									\
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);				\
+    R##_f = _q | (_r != 0);						\
+  } while (0)
+
+#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)		\
+  do {							\
+    _FP_W_TYPE _nh, _nl, _q, _r;			\
+    if (X##_f < Y##_f)					\
+      {							\
+	R##_e--;					\
+	_nl = X##_f << _FP_WFRACBITS_##fs;		\
+	_nh = X##_f >> _FP_WFRACXBITS_##fs;		\
+      }							\
+    else						\
+      {							\
+	_nl = X##_f << (_FP_WFRACBITS_##fs - 1);	\
+	_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);	\
+      }							\
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);		\
+    R##_f = _q | (_r != 0);				\
+  } while (0)
+  
+  
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+ 
+#define _FP_SQRT_MEAT_1(R, S, T, X, q)			\
+  do {							\
+    while (q)						\
+      {							\
+        T##_f = S##_f + q;				\
+        if (T##_f <= X##_f)				\
+          {						\
+            S##_f = T##_f + q;				\
+            X##_f -= T##_f;				\
+            R##_f += q;					\
+          }						\
+        _FP_FRAC_SLL_1(X, 1);				\
+        q >>= 1;					\
+      }							\
+  } while (0)
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)	(r = X##_f)
+#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)	(X##_f = r)
+
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S)				\
+  do {									\
+    D##_f = S##_f;							\
+    if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs)			\
+      _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs),	\
+		     _FP_WFRACBITS_##sfs);				\
+    else								\
+      D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs;		\
+  } while (0)
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/op-2.h linux-2.2.14-pre7/arch/alpha/math-emu/op-2.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/op-2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/op-2.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,433 @@
+/*
+ * Basic two-word fraction declaration and manipulation.
+ */
+
+#define _FP_FRAC_DECL_2(X)	_FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_COPY_2(D,S)	(D##_f0 = S##_f0, D##_f1 = S##_f1)
+#define _FP_FRAC_SET_2(X,I)	__FP_FRAC_SET_2(X, I)
+#define _FP_FRAC_HIGH_2(X)	(X##_f1)
+#define _FP_FRAC_LOW_2(X)	(X##_f0)
+#define _FP_FRAC_WORD_2(X,w)	(X##_f##w)
+
+#define _FP_FRAC_SLL_2(X,N)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+        if (__builtin_constant_p(N) && (N) == 1) 			\
+          {								\
+            X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0);	\
+            X##_f0 += X##_f0;						\
+          }								\
+        else								\
+          {								\
+	    X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N));	\
+	    X##_f0 <<= (N);						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);			\
+	X##_f0 = 0;							\
+      }									\
+  } while (0)
+
+#define _FP_FRAC_SRL_2(X,N)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+	X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N));	\
+	X##_f1 >>= (N);							\
+      }									\
+    else								\
+      {									\
+	X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);			\
+	X##_f1 = 0;							\
+      }									\
+  } while (0)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRS_2(X,N,sz)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+	X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) |	\
+		  (__builtin_constant_p(N) && (N) == 1			\
+		   ? X##_f0 & 1						\
+		   : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0));	\
+	X##_f1 >>= (N);							\
+      }									\
+    else								\
+      {									\
+	X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |			\
+	          (((X##_f1 << (sz - (N))) | X##_f0) != 0));		\
+	X##_f1 = 0;							\
+      }									\
+  } while (0)
+
+#define _FP_FRAC_ADDI_2(X,I) \
+  __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
+
+#define _FP_FRAC_ADD_2(R,X,Y) \
+  __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_SUB_2(R,X,Y) \
+  __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_CLZ_2(R,X)	\
+  do {				\
+    if (X##_f1)			\
+      __FP_CLZ(R,X##_f1);	\
+    else 			\
+    {				\
+      __FP_CLZ(R,X##_f0);	\
+      R += _FP_W_TYPE_SIZE;	\
+    }				\
+  } while(0)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_2(X)	((_FP_WS_TYPE)X##_f1 < 0)
+#define _FP_FRAC_ZEROP_2(X)	((X##_f1 | X##_f0) == 0)
+#define _FP_FRAC_OVERP_2(fs,X)	(X##_f1 & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
+#define _FP_FRAC_GT_2(X, Y)	\
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
+#define _FP_FRAC_GE_2(X, Y)	\
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
+
+#define _FP_ZEROFRAC_2		0, 0
+#define _FP_MINFRAC_2		0, 1
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_2(X,I1,I0)	(X##_f0 = I0, X##_f1 = I1)
+
+#define __FP_CLZ_2(R, xh, xl)	\
+  do {				\
+    if (xh)			\
+      __FP_CLZ(R,xl);		\
+    else 			\
+    {				\
+      __FP_CLZ(R,xl);		\
+      R += _FP_W_TYPE_SIZE;	\
+    }				\
+  } while(0)
+
+#if 0
+
+#ifndef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i) \
+  (xh += ((xl += i) < i))
+#endif
+#ifndef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
+  (rh = xh + yh + ((rl = xl + yl) < xl))
+#endif
+#ifndef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
+  (rh = xh - yh - ((rl = xl - yl) > xl))
+#endif
+
+#else
+
+#undef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i)	add_ssaaaa(xh, xl, xh, xl, 0, i)
+#undef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2			add_ssaaaa
+#undef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2			sub_ddmmss
+
+#endif
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_2(fs, X, val)			\
+  do {							\
+    union _FP_UNION_##fs _flo; _flo.flt = (val);	\
+							\
+    X##_f0 = _flo.bits.frac0;				\
+    X##_f1 = _flo.bits.frac1;				\
+    X##_e  = _flo.bits.exp;				\
+    X##_s  = _flo.bits.sign;				\
+  } while (0)
+
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_2(fs, val, X)			\
+  do {							\
+    union _FP_UNION_##fs _flo;				\
+							\
+    _flo.bits.frac0 = X##_f0;				\
+    _flo.bits.frac1 = X##_f1;				\
+    _flo.bits.exp   = X##_e;				\
+    _flo.bits.sign  = X##_s;				\
+							\
+    (val) = _flo.flt;					\
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit)				\
+  do {									\
+    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	\
+									\
+    doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
+    doit(_b_f1, _b_f0, X##_f0, Y##_f1);					\
+    doit(_c_f1, _c_f0, X##_f1, Y##_f0);					\
+    doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
+									\
+    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),	\
+		    0, _b_f1, _b_f0, 0,					\
+		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));	\
+    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),	\
+		    0, _c_f1, _c_f0, 0,					\
+		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));	\
+									\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
+    R##_f0 = _FP_FRAC_WORD_4(_z,0);					\
+    R##_f1 = _FP_FRAC_WORD_4(_z,1);					\
+  } while (0)
+
+/* This next macro appears to be totally broken. Fortunately nowhere
+ * seems to use it :-> The problem is that we define _z[4] but
+ * then use it in _FP_FRAC_SRS_4, which will attempt to access
+ * _z_f[n] which will cause an error. The fix probably involves 
+ * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 
+ */
+#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y)					\
+  do {									\
+    _FP_W_TYPE _x[2], _y[2], _z[4];					\
+    _x[0] = X##_f0; _x[1] = X##_f1;					\
+    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
+									\
+    mpn_mul_n(_z, _x, _y, 2);						\
+									\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs);	\
+    R##_f0 = _z[0];							\
+    R##_f1 = _z[1];							\
+  } while (0)
+
+
+/*
+ * Division algorithms:
+ * This seems to be giving me difficulties -- PMM 
+ * Look, NetBSD seems to be able to comment algorithms. Can't you?
+ * I've thrown printks at the problem.
+ * This now appears to work, but I still don't really know why.
+ * Also, I don't think the result is properly normalised...
+ */
+
+#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y)				\
+  do {									\
+    extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],	\
+			       _FP_W_TYPE n1, _FP_W_TYPE n0,		\
+			       _FP_W_TYPE d1, _FP_W_TYPE d0);		\
+    _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0;		\
+    _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0;				\
+    _FP_W_TYPE _rmem[2], _qmem[2];					\
+    /* I think this check is to ensure that the result is normalised.   \
+     * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in         \
+     * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y.      \
+     * In this case we tweak things. (this is based on comments in      \
+     * the NetBSD FPU emulation code. )                                 \
+     * We know X,Y are normalised because we ensure this as part of     \
+     * the unpacking process. -- PMM                                    \
+     */									\
+    if (_FP_FRAC_GT_2(X, Y))						\
+      {									\
+/*	R##_e++; */							\
+	_n_f3 = X##_f1 >> 1;						\
+	_n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1;		\
+	_n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1);			\
+	_n_f0 = 0;							\
+      }									\
+    else								\
+      {									\
+	R##_e--;							\
+	_n_f3 = X##_f1;							\
+	_n_f2 = X##_f0;							\
+	_n_f1 = _n_f0 = 0;						\
+      }									\
+									\
+    /* Normalize, i.e. make the most significant bit of the 		\
+       denominator set.  CHANGED: - 1 to nothing -- PMM */		\
+    _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */);			\
+									\
+    /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4 	\
+       primitive snagged from libgcc2.c.  */				\
+									\
+    _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1);		\
+    _q_f1 = _qmem[0];							\
+    umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0);				\
+    _r_f1 = _rmem[0];							\
+    _r_f0 = _n_f1;							\
+    if (_FP_FRAC_GT_2(_m, _r))						\
+      {									\
+	_q_f1--;							\
+	_FP_FRAC_ADD_2(_r, _r, Y);					\
+	if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
+	  {								\
+	    _q_f1--;							\
+	    _FP_FRAC_ADD_2(_r, _r, Y);					\
+	  }								\
+      }									\
+    _FP_FRAC_SUB_2(_r, _r, _m);						\
+									\
+    _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1);		\
+    _q_f0 = _qmem[0];							\
+    umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0);				\
+    _r_f1 = _rmem[0];							\
+    _r_f0 = _n_f0;							\
+    if (_FP_FRAC_GT_2(_m, _r))						\
+      {									\
+	_q_f0--;							\
+	_FP_FRAC_ADD_2(_r, _r, Y);					\
+	if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
+	  {								\
+	    _q_f0--;							\
+	    _FP_FRAC_ADD_2(_r, _r, Y);					\
+	  }								\
+      }									\
+    _FP_FRAC_SUB_2(_r, _r, _m);						\
+									\
+    R##_f1 = _q_f1;							\
+    R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0);				\
+    /* adjust so answer is normalized again. I'm not sure what the 	\
+     * final sz param should be. In practice it's never used since      \
+     * N is 1 which is always going to be < _FP_W_TYPE_SIZE...		\
+     */									\
+    /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs);	*/			\
+  } while (0)
+
+
+#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y)					\
+  do {									\
+    _FP_W_TYPE _x[4], _y[2], _z[4];					\
+    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
+    _x[0] = _x[3] = 0;							\
+    if (_FP_FRAC_GT_2(X, Y))						\
+      {									\
+	R##_e++;							\
+	_x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) |	\
+		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
+			    (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE)));	\
+	_x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE);		\
+      }									\
+    else								\
+      {									\
+	_x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) |		\
+		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
+			    (_FP_WFRACBITS - _FP_W_TYPE_SIZE)));	\
+	_x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE);		\
+      }									\
+									\
+    (void) mpn_divrem (_z, 0, _x, 4, _y, 2);				\
+    R##_f1 = _z[1];							\
+    R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0);				\
+  } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+ 
+#define _FP_SQRT_MEAT_2(R, S, T, X, q)			\
+  do {							\
+    while (q)						\
+      {							\
+        T##_f1 = S##_f1 + q;				\
+        if (T##_f1 <= X##_f1)				\
+          {						\
+            S##_f1 = T##_f1 + q;			\
+            X##_f1 -= T##_f1;				\
+            R##_f1 += q;				\
+          }						\
+        _FP_FRAC_SLL_2(X, 1);				\
+        q >>= 1;					\
+      }							\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
+    while (q)						\
+      {							\
+        T##_f0 = S##_f0 + q;				\
+        T##_f1 = S##_f1;				\
+        if (T##_f1 < X##_f1 || 				\
+            (T##_f1 == X##_f1 && T##_f0 < X##_f0))	\
+          {						\
+            S##_f0 = T##_f0 + q;			\
+            if (((_FP_WS_TYPE)T##_f0) < 0 &&		\
+                ((_FP_WS_TYPE)S##_f0) >= 0)		\
+              S##_f1++;					\
+            _FP_FRAC_SUB_2(X, X, T);			\
+            R##_f0 += q;				\
+          }						\
+        _FP_FRAC_SLL_2(X, 1);				\
+        q >>= 1;					\
+      }							\
+  } while (0)
+
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_2(r, X, rsize)	\
+  do {						\
+    if (rsize <= _FP_W_TYPE_SIZE)		\
+      r = X##_f0;				\
+    else					\
+      {						\
+	r = X##_f1;				\
+	r <<= _FP_W_TYPE_SIZE;			\
+	r += X##_f0;				\
+      }						\
+  } while (0)
+
+#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)				\
+  do {									\
+    X##_f0 = r;								\
+    X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);	\
+  } while (0)
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S)				\
+  do {									\
+    _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),	\
+		   _FP_WFRACBITS_##sfs);				\
+    D##_f = S##_f0;							\
+  } while (0)
+
+#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S)				\
+  do {									\
+    D##_f0 = S##_f;							\
+    D##_f1 = 0;								\
+    _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));	\
+  } while (0)
+
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/op-4.h linux-2.2.14-pre7/arch/alpha/math-emu/op-4.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/op-4.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/op-4.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,297 @@
+/*
+ * Basic four-word fraction declaration and manipulation.
+ *
+ * When adding quadword support for 32 bit machines, we need
+ * to be a little careful as double multiply uses some of these
+ * macros: (in op-2.h)
+ * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
+ * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
+ * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
+ * _FP_FRAC_DECL_4: it appears to be broken and is not used 
+ * anywhere anyway. )
+ *
+ * I've now fixed all the macros that were here from the sparc64 code.
+ * [*none* of the shift macros were correct!] -- PMM 02/1998
+ * 
+ * The only quadword stuff that remains to be coded is: 
+ * 1) the conversion to/from ints, which requires 
+ * that we check (in op-common.h) that the following do the right thing
+ * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
+ * 2) multiply, divide and sqrt, which require:
+ * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q),
+ * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to
+ * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h.
+ * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for
+ * these; they are used nowhere else. ]
+ */
+
+#define _FP_FRAC_DECL_4(X)	_FP_W_TYPE X##_f[4]
+#define _FP_FRAC_COPY_4(D,S)			\
+  (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1],	\
+   D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
+/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
+ * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
+ * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
+ * which just assigns the In values to the array X##_f[]. 
+ * This is why the number of parameters doesn't appear to match
+ * at first glance...      -- PMM 
+ */
+#define _FP_FRAC_SET_4(X,I)	__FP_FRAC_SET_4(X, I)
+#define _FP_FRAC_HIGH_4(X)	(X##_f[3])
+#define _FP_FRAC_LOW_4(X)	(X##_f[0])
+#define _FP_FRAC_WORD_4(X,w)	(X##_f[w])
+
+#define _FP_FRAC_SLL_4(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _up = (N) % _FP_W_TYPE_SIZE;					\
+    _down = _FP_W_TYPE_SIZE - _up;					\
+    for (_i = 3; _i > _skip; --_i)					\
+      X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down;	\
+/* bugfixed: was X##_f[_i] <<= _up;  -- PMM 02/1998 */                  \
+    X##_f[_i] = X##_f[0] << _up; 	                                \
+    for (--_i; _i >= 0; --_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+/* This one was broken too */
+#define _FP_FRAC_SRL_4(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    for (_i = 0; _i < 3-_skip; ++_i)					\
+      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up;	\
+    X##_f[_i] = X##_f[3] >> _down;			         	\
+    for (++_i; _i < 4; ++_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+
+/* Right shift with sticky-lsb. 
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRS_4(X,N,size)					\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _FP_W_TYPE _s;							\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    for (_s = _i = 0; _i < _skip; ++_i)					\
+      _s |= X##_f[_i];							\
+    _s |= X##_f[_i] << _up;						\
+/* s is now != 0 if we want to set the LSbit */                         \
+    for (_i = 0; _i < 3-_skip; ++_i)					\
+      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up;	\
+    X##_f[_i] = X##_f[3] >> _down;					\
+    for (++_i; _i < 4; ++_i)						\
+      X##_f[_i] = 0;							\
+    /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
+    X##_f[0] |= (_s != 0);                                              \
+  } while (0)
+
+#define _FP_FRAC_ADD_4(R,X,Y)						\
+  __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
+		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
+		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_SUB_4(R,X,Y)                                           \
+  __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
+		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
+		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_ADDI_4(X,I)                                            \
+  __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
+
+#define _FP_ZEROFRAC_4  0,0,0,0
+#define _FP_MINFRAC_4   0,0,0,1
+
+#define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
+#define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
+#define _FP_FRAC_OVERP_4(fs,X)  (X##_f[0] & _FP_OVERFLOW_##fs)
+
+#define _FP_FRAC_EQ_4(X,Y)                              \
+ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]          \
+  && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
+
+#define _FP_FRAC_GT_4(X,Y)                              \
+ (X##_f[3] > Y##_f[3] ||                                \
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
+    (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0])       \
+   ))                                                   \
+  ))                                                    \
+ )
+
+#define _FP_FRAC_GE_4(X,Y)                              \
+ (X##_f[3] > Y##_f[3] ||                                \
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
+    (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0])      \
+   ))                                                   \
+  ))                                                    \
+ )
+
+
+#define _FP_FRAC_CLZ_4(R,X)             \
+  do {                                  \
+    if (X##_f[3])                       \
+    {                                   \
+        __FP_CLZ(R,X##_f[3]);           \
+    }                                   \
+    else if (X##_f[2])                  \
+    {                                   \
+        __FP_CLZ(R,X##_f[2]);           \
+        R += _FP_W_TYPE_SIZE;           \
+    }                                   \
+    else if (X##_f[1])                  \
+    {                                   \
+        __FP_CLZ(R,X##_f[2]);           \
+        R += _FP_W_TYPE_SIZE*2;         \
+    }                                   \
+    else                                \
+    {                                   \
+        __FP_CLZ(R,X##_f[0]);           \
+        R += _FP_W_TYPE_SIZE*3;         \
+    }                                   \
+  } while(0)
+
+
+#define _FP_UNPACK_RAW_4(fs, X, val)                            \
+  do {                                                          \
+    union _FP_UNION_##fs _flo; _flo.flt = (val);        	\
+    X##_f[0] = _flo.bits.frac0;                                 \
+    X##_f[1] = _flo.bits.frac1;                                 \
+    X##_f[2] = _flo.bits.frac2;                                 \
+    X##_f[3] = _flo.bits.frac3;                                 \
+    X##_e  = _flo.bits.exp;                                     \
+    X##_s  = _flo.bits.sign;                                    \
+  } while (0)
+
+#define _FP_PACK_RAW_4(fs, val, X)                              \
+  do {                                                          \
+    union _FP_UNION_##fs _flo;					\
+    _flo.bits.frac0 = X##_f[0];                                 \
+    _flo.bits.frac1 = X##_f[1];                                 \
+    _flo.bits.frac2 = X##_f[2];                                 \
+    _flo.bits.frac3 = X##_f[3];                                 \
+    _flo.bits.exp   = X##_e;                                    \
+    _flo.bits.sign  = X##_s;                                    \
+    (val) = _flo.flt;                                   	\
+  } while (0)
+
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_4(X,I3,I2,I1,I0)					\
+  (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+
+#ifndef __FP_FRAC_ADD_4
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  (r0 = x0 + y0,							\
+   r1 = x1 + y1 + (r0 < x0),						\
+   r2 = x2 + y2 + (r1 < x1),						\
+   r3 = x3 + y3 + (r2 < x2))
+#endif
+
+#ifndef __FP_FRAC_SUB_4
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  (r0 = x0 - y0,                                                        \
+   r1 = x1 - y1 - (r0 > x0),                                            \
+   r2 = x2 - y2 - (r1 > x1),                                            \
+   r3 = x3 - y3 - (r2 > x2))
+#endif
+
+#ifndef __FP_FRAC_ADDI_4
+/* I always wanted to be a lisp programmer :-> */
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                 \
+  (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2)))
+#endif
+
+/* Convert FP values between word sizes. This appears to be more
+ * complicated than I'd have expected it to be, so these might be
+ * wrong... These macros are in any case somewhat bogus because they
+ * use information about what various FRAC_n variables look like 
+ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
+ * the ones in op-2.h and op-1.h. 
+ */
+#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S)                               \
+   do {                                                                 \
+     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
+                        _FP_WFRACBITS_##sfs);                           \
+     D##_f = S##_f[0];                                                   \
+  } while (0)
+
+#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S)                               \
+   do {                                                                 \
+     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
+                        _FP_WFRACBITS_##sfs);                           \
+     D##_f0 = S##_f[0];                                                  \
+     D##_f1 = S##_f[1];                                                  \
+  } while (0)
+
+/* Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+/* Put the FP value X into r, which is an integer of size rsize. */
+#define _FP_FRAC_ASSEMBLE_4(r, X, rsize)                                \
+  do {                                                                  \
+    if (rsize <= _FP_W_TYPE_SIZE)                                       \
+      r = X##_f[0];                                                     \
+    else if (rsize <= 2*_FP_W_TYPE_SIZE)                                \
+    {                                                                   \
+      r = X##_f[1];                                                     \
+      r <<= _FP_W_TYPE_SIZE;                                            \
+      r += X##_f[0];                                                    \
+    }                                                                   \
+    else                                                                \
+    {                                                                   \
+      /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
+      /* and int == 4words as a single case.                         */ \
+      r = X##_f[3];                                                     \
+      r <<= _FP_W_TYPE_SIZE;                                            \
+      r += X##_f[2];                                                    \
+      r <<= _FP_W_TYPE_SIZE;                                            \
+      r += X##_f[1];                                                    \
+      r <<= _FP_W_TYPE_SIZE;                                            \
+      r += X##_f[0];                                                    \
+    }                                                                   \
+  } while (0)
+
+/* "No disassemble Number Five!" */
+/* move an integer of size rsize into X's fractional part. We rely on
+ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
+ * having to mask the values we store into it.
+ */
+#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize)                             \
+  do {                                                                  \
+    X##_f[0] = r;                                                       \
+    X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);   \
+    X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
+    X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
+  } while (0);
+
+#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)                               \
+   do {                                                                 \
+     D##_f[0] = S##_f;                                                  \
+     D##_f[1] = D##_f[2] = D##_f[3] = 0;                                \
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
+   } while (0)
+
+#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S)                               \
+   do {                                                                 \
+     D##_f[0] = S##_f0;                                                 \
+     D##_f[1] = S##_f1;                                                 \
+     D##_f[2] = D##_f[3] = 0;                                           \
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
+   } while (0)
+
+/* FIXME! This has to be written */
+#define _FP_SQRT_MEAT_4(R, S, T, X, q)
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/op-common.h linux-2.2.14-pre7/arch/alpha/math-emu/op-common.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/op-common.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/op-common.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,726 @@
+#define _FP_DECL(wc, X)			\
+  _FP_I_TYPE X##_c, X##_s, X##_e, X##_r=0;	\
+  _FP_FRAC_DECL_##wc(X)
+
+/*
+ * Finish truely unpacking a native fp value by classifying the kind
+ * of fp value and normalizing both the exponent and the fraction.
+ */
+
+#ifndef _FP_UNPACK_CANONICAL
+#define _FP_UNPACK_CANONICAL(fs, wc, X)					\
+do {									\
+  switch (X##_e)							\
+  {									\
+  default:								\
+    _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs;				\
+    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
+    X##_e -= _FP_EXPBIAS_##fs;						\
+    X##_c = FP_CLS_NORMAL;						\
+    break;								\
+									\
+  case 0:								\
+    if (_FP_FRAC_ZEROP_##wc(X))						\
+      X##_c = FP_CLS_ZERO;						\
+    else								\
+      /* A denormalized number.  */					\
+      __FP_UNPACK_DENORM(fs, wc, X);					\
+    break;								\
+									\
+  case _FP_EXPMAX_##fs:							\
+    if (_FP_FRAC_ZEROP_##wc(X))						\
+      X##_c = FP_CLS_INF;						\
+    else								\
+      /* We don't differentiate between signaling and quiet nans.  */	\
+      X##_c = FP_CLS_NAN;						\
+    break;								\
+  }									\
+} while (0)
+#endif /* _FP_UNPACK_CANONICAL */
+
+
+/*
+ * Before packing the bits back into the native fp result, take care
+ * of such mundane things as rounding and overflow.  Also, for some
+ * kinds of fp values, the original parts may not have been fully
+ * extracted -- but that is ok, we can regenerate them now.
+ */
+
+#ifndef _FP_PACK_CANONICAL
+#define _FP_PACK_CANONICAL(fs, wc, X)				\
+({int __pk__ret = X##_r;					\
+  switch (X##_c)						\
+  {								\
+  case FP_CLS_NORMAL:						\
+    X##_e += _FP_EXPBIAS_##fs;					\
+    if (X##_e > 0)						\
+      {								\
+	__pk__ret |= _FP_ROUND(wc, X);				\
+	if (_FP_FRAC_OVERP_##wc(fs, X))				\
+	  {							\
+	    _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));		\
+	    X##_e++;						\
+	  }							\
+	else							\
+	  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
+	if (X##_e >= _FP_EXPMAX_##fs)				\
+	  {							\
+	    /* overflow to infinity */				\
+	    X##_e = _FP_EXPMAX_##fs;				\
+	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
+            __pk__ret |= EFLAG_OVERFLOW;			\
+	  }							\
+      }								\
+    else							\
+      {								\
+	/* we've got a denormalized number */			\
+	X##_e = -X##_e + 1;					\
+	if (X##_e <= _FP_WFRACBITS_##fs)			\
+	  {							\
+	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
+	    __pk__ret |= _FP_ROUND(wc, X);			\
+	    _FP_FRAC_SLL_##wc(X, 1);				\
+	    if (_FP_FRAC_OVERP_##wc(fs, X))			\
+	      {							\
+	        X##_e = 1;					\
+	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
+	      }							\
+	    else						\
+	      {							\
+		X##_e = 0;					\
+		_FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1);		\
+                __pk__ret |= EFLAG_UNDERFLOW;			\
+	      }							\
+	  }							\
+	else							\
+	  {							\
+	    /* underflow to zero */				\
+	    X##_e = 0;						\
+	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
+            __pk__ret |= EFLAG_UNDERFLOW;			\
+	  }							\
+      }								\
+    break;							\
+								\
+  case FP_CLS_ZERO:						\
+    X##_e = 0;							\
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
+    break;							\
+								\
+  case FP_CLS_INF:						\
+    X##_e = _FP_EXPMAX_##fs;					\
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
+    break;							\
+								\
+  case FP_CLS_NAN:						\
+    X##_e = _FP_EXPMAX_##fs;					\
+    if (!_FP_KEEPNANFRACP)					\
+      {								\
+	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
+	X##_s = 0;						\
+      }								\
+    else							\
+      _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs;		\
+    break;							\
+  }								\
+  __pk__ret;							\
+})
+#endif /* _FP_PACK_CANONICAL */
+
+/*
+ * Main addition routine.  The input values should be cooked.
+ */
+#ifndef _FP_ADD
+#define _FP_ADD(fs, wc, R, X, Y)					     \
+do {									     \
+  /* Propagate any flags that may have been set during unpacking */	     \
+  R##_r |= (X##_r | Y##_r);						     \
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))				     \
+  {									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):			     \
+    {									     \
+      /* shift the smaller number so that its exponent matches the larger */ \
+      _FP_I_TYPE diff = X##_e - Y##_e;					     \
+									     \
+      if (diff < 0)							     \
+	{								     \
+	  diff = -diff;							     \
+	  if (diff <= _FP_WFRACBITS_##fs)				     \
+	    _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);		     \
+	  else if (!_FP_FRAC_ZEROP_##wc(X)) {				     \
+	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			     \
+	    R_r |= EFLAG_INEXACT;					     \
+	  }								     \
+	  else								     \
+	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			     \
+	  R##_e = Y##_e;						     \
+	}								     \
+      else								     \
+	{								     \
+	  if (diff > 0)							     \
+	    {								     \
+	      if (diff <= _FP_WFRACBITS_##fs)				     \
+	        _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);		     \
+	      else if (!_FP_FRAC_ZEROP_##wc(Y))	{			     \
+	        _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			     \
+	         R_r |= EFLAG_INEXACT;					     \
+	      }								     \
+	      else							     \
+	        _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc);		     \
+	    }								     \
+	  R##_e = X##_e;						     \
+	}								     \
+									     \
+      R##_c = FP_CLS_NORMAL;						     \
+									     \
+      if (X##_s == Y##_s)						     \
+	{								     \
+	  R##_s = X##_s;						     \
+	  _FP_FRAC_ADD_##wc(R, X, Y);					     \
+	  if (_FP_FRAC_OVERP_##wc(fs, R))				     \
+	    {								     \
+	      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);		     \
+	      R##_e++;							     \
+	    }								     \
+	}								     \
+      else								     \
+	{								     \
+	  R##_s = X##_s;						     \
+	  _FP_FRAC_SUB_##wc(R, X, Y);					     \
+	  if (_FP_FRAC_ZEROP_##wc(R))					     \
+	    {								     \
+	      /* return an exact zero */				     \
+	      if (FP_ROUNDMODE == FP_RND_MINF)				     \
+		R##_s |= Y##_s;						     \
+	      else							     \
+		R##_s &= Y##_s;						     \
+	      R##_c = FP_CLS_ZERO;					     \
+	    }								     \
+	  else								     \
+	    {								     \
+	      if (_FP_FRAC_NEGP_##wc(R))				     \
+		{							     \
+		  _FP_FRAC_SUB_##wc(R, Y, X);				     \
+		  R##_s = Y##_s;					     \
+		}							     \
+									     \
+	      /* renormalize after subtraction */			     \
+	      _FP_FRAC_CLZ_##wc(diff, R);				     \
+	      diff -= _FP_WFRACXBITS_##fs;				     \
+	      if (diff)							     \
+		{							     \
+		  R##_e -= diff;					     \
+		  _FP_FRAC_SLL_##wc(R, diff);				     \
+		}							     \
+	    }								     \
+	}								     \
+      break;								     \
+    }									     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):				     \
+    _FP_CHOOSENAN(fs, wc, R, X, Y);					     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):			     \
+    R##_e = X##_e;							     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):			     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):				     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):				     \
+    _FP_FRAC_COPY_##wc(R, X);						     \
+    R##_s = X##_s;							     \
+    R##_c = X##_c;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):			     \
+    R##_e = Y##_e;							     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):			     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):				     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):				     \
+    _FP_FRAC_COPY_##wc(R, Y);						     \
+    R##_s = Y##_s;							     \
+    R##_c = Y##_c;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):				     \
+    if (X##_s != Y##_s)							     \
+      {									     \
+	/* +INF + -INF => NAN */					     \
+	_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);				     \
+	R##_s = X##_s ^ Y##_s;						     \
+	R##_c = FP_CLS_NAN;						     \
+	R##_r |= EFLAG_INVALID;						     \
+	break;								     \
+      }									     \
+    /* FALLTHRU */							     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):			     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):				     \
+    R##_s = X##_s;							     \
+    R##_c = FP_CLS_INF;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):			     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):				     \
+    R##_s = Y##_s;							     \
+    R##_c = FP_CLS_INF;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):			     \
+    /* make sure the sign is correct */					     \
+    if (FP_ROUNDMODE == FP_RND_MINF)					     \
+      R##_s = X##_s | Y##_s;						     \
+    else								     \
+      R##_s = X##_s & Y##_s;						     \
+    R##_c = FP_CLS_ZERO;						     \
+    break;								     \
+									     \
+  default:								     \
+    abort();								     \
+  }									     \
+} while (0)
+#endif /* _FP_ADD */
+
+
+/*
+ * Main negation routine.  FIXME -- when we care about setting exception
+ * bits reliably, this will not do.  We should examine all of the fp classes.
+ */
+#ifndef _FP_NEG
+#define _FP_NEG(fs, wc, R, X)		\
+  do {					\
+    R##_r |= X##_r;			\
+    _FP_FRAC_COPY_##wc(R, X);		\
+    R##_c = X##_c;			\
+    R##_e = X##_e;			\
+    R##_s = 1 ^ X##_s;			\
+  } while (0)
+#endif /* _FP_NEG */
+
+
+/*
+ * Main multiplication routine.  The input values should be cooked.
+ */
+#ifndef _FP_MUL
+#define _FP_MUL(fs, wc, R, X, Y)			\
+do {							\
+  /* Propagate any flags that may have been set during unpacking */	     \
+  R##_r |= (X##_r | Y##_r);						     \
+  R##_s = X##_s ^ Y##_s;				\
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
+  {							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_NORMAL;				\
+    R##_e = X##_e + Y##_e + 1;				\
+							\
+    _FP_MUL_MEAT_##fs(R,X,Y);				\
+							\
+    if (_FP_FRAC_OVERP_##wc(fs, R))			\
+      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
+    else						\
+      R##_e--;						\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
+    _FP_CHOOSENAN(fs, wc, R, X, Y);			\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
+    R##_s = X##_s;					\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
+    _FP_FRAC_COPY_##wc(R, X);				\
+    R##_c = X##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
+    R##_s = Y##_s;					\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
+    _FP_FRAC_COPY_##wc(R, Y);				\
+    R##_c = Y##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
+    R##_c = FP_CLS_NAN;					\
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
+    break;						\
+							\
+  default:						\
+    abort();						\
+  }							\
+} while (0)
+#endif /* _FP_MUL */
+
+
+/*
+ * Main division routine.  The input values should be cooked.
+ */
+#ifndef _FP_DIV
+#define _FP_DIV(fs, wc, R, X, Y)			\
+do {							\
+  /* Propagate any flags that may have been set during unpacking */	     \
+  R##_r |= (X##_r | Y##_r);						     \
+  R##_s = X##_s ^ Y##_s;				\
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
+  {							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_NORMAL;				\
+    R##_e = X##_e - Y##_e;				\
+							\
+    _FP_DIV_MEAT_##fs(R,X,Y);				\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
+    _FP_CHOOSENAN(fs, wc, R, X, Y);			\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
+    R##_s = X##_s;					\
+    _FP_FRAC_COPY_##wc(R, X);				\
+    R##_c = X##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
+    R##_s = Y##_s;					\
+    _FP_FRAC_COPY_##wc(R, Y);				\
+    R##_c = Y##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_ZERO;				\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_INF;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
+    R##_c = FP_CLS_NAN;					\
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
+    break;						\
+							\
+  default:						\
+    abort();						\
+  }							\
+} while (0)
+#endif _FP_DIV
+
+
+/*
+ * Main differential comparison routine.  The inputs should be raw not
+ * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
+ */
+#ifndef _FP_CMP
+#define _FP_CMP(fs, wc, ret, X, Y, un)					\
+  do {									\
+    /* NANs are unordered */						\
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
+	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
+      {									\
+	ret = un;							\
+      }									\
+    /* Deal with infinities */						\
+    else if (X##_c == FP_CLS_INF) {					\
+	if(Y##_c == FP_CLS_INF) {					\
+	    ret = Y##_s - X##_s;					\
+	}								\
+	else {								\
+	    ret = X##_s ? -1 : 1; 					\
+	}								\
+    }									\
+    else if(Y##_c == FP_CLS_INF) {					\
+	ret = Y##_s ? 1 : -1;						\
+    }									\
+    else								\
+      {									\
+	int __is_zero_x;						\
+	int __is_zero_y;						\
+									\
+	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
+	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
+									\
+	if (__is_zero_x && __is_zero_y)					\
+		ret = 0;						\
+	else if (__is_zero_x)						\
+		ret = Y##_s ? 1 : -1;					\
+	else if (__is_zero_y)						\
+		ret = X##_s ? -1 : 1;					\
+	else if (X##_s != Y##_s)					\
+	  ret = X##_s ? -1 : 1;						\
+	else if (X##_e > Y##_e)						\
+	  ret = X##_s ? -1 : 1;						\
+	else if (X##_e < Y##_e)						\
+	  ret = X##_s ? 1 : -1;						\
+	else if (_FP_FRAC_GT_##wc(X, Y))				\
+	  ret = X##_s ? -1 : 1;						\
+	else if (_FP_FRAC_GT_##wc(Y, X))				\
+	  ret = X##_s ? 1 : -1;						\
+	else								\
+	  ret = 0;							\
+      }									\
+  } while (0)
+#endif /* _FP_CMP */
+
+
+/* Simplification for strict equality.  */
+
+#ifndef _FP_CMP_EQ
+#define _FP_CMP_EQ(fs, wc, ret, X, Y)					  \
+  do {									  \
+    /* NANs are unordered */						  \
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		  \
+	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	  \
+      {									  \
+	ret = 1;							  \
+      }									  \
+    else								  \
+      {									  \
+	ret = !(X##_e == Y##_e						  \
+		&& _FP_FRAC_EQ_##wc(X, Y)				  \
+		&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
+      }									  \
+  } while (0)
+#endif /* _FP_CMP_EQ */
+
+/*
+ * Main square root routine.  The input value should be cooked.
+ */
+#ifndef _FP_SQRT
+#define _FP_SQRT(fs, wc, R, X)						\
+do {									\
+    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
+    _FP_W_TYPE q;							\
+    R##_r |= X##_r;							\
+    switch (X##_c)							\
+    {									\
+    case FP_CLS_NAN:							\
+        _FP_CHOOSENAN_SQRT(fs, wc, R, X);			        \
+    	break;								\
+    case FP_CLS_INF:							\
+    	if (X##_s)							\
+    	  {								\
+    	    R##_s = 0;							\
+	    R##_c = FP_CLS_NAN; /* sNAN */				\
+    	  }								\
+    	else								\
+    	  {								\
+    	    R##_s = 0;							\
+    	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
+    	  }								\
+    	break;								\
+    case FP_CLS_ZERO:							\
+	R##_s = X##_s;							\
+    	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
+	break;								\
+    case FP_CLS_NORMAL:							\
+    	R##_s = 0;							\
+        if (X##_s)							\
+          {								\
+	    R##_c = FP_CLS_NAN; /* sNAN */				\
+	    break;							\
+          }								\
+    	R##_c = FP_CLS_NORMAL;						\
+        if (X##_e & 1)							\
+          _FP_FRAC_SLL_##wc(X, 1);					\
+        R##_e = X##_e >> 1;						\
+        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
+        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
+        q = _FP_OVERFLOW_##fs;						\
+        _FP_FRAC_SLL_##wc(X, 1);					\
+        _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
+        _FP_FRAC_SRL_##wc(R, 1);					\
+    }									\
+  } while (0)
+#endif /* FP_SQRT */
+
+/*
+ * Convert from FP to integer
+ */
+
+/* "When a NaN, infinity, large positive argument >= 2147483648.0, or 
+ * large negative argument <= -2147483649.0 is converted to an integer,
+ * the invalid_current bit...should be set and fp_exception_IEEE_754 should
+ * be raised. If the floating point invalid trap is disabled, no trap occurs
+ * and a numerical result is generated: if the sign bit of the operand
+ * is 0, the result is 2147483647; if the sign bit of the operand is 1,
+ * the result is -2147483648."
+ * Similarly for conversion to extended ints, except that the boundaries
+ * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
+ * -2^63 for s=1.
+ * -- SPARC Architecture Manual V9, Appendix B, which specifies how
+ * SPARCs resolve implementation dependencies in the IEEE-754 spec.
+ * I don't believe that the code below follows this. I'm not even sure
+ * it's right! 
+ * It doesn't cope with needing to convert to an n bit integer when there
+ * is no n bit integer type. Fortunately gcc provides long long so this
+ * isn't a problem for sparc32.
+ * I have, however, fixed its NaN handling to conform as above.
+ *         -- PMM 02/1998
+ * NB: rsigned is not 'is r declared signed?' but 'should the value stored
+ * in r be signed or unsigned?'. r is always(?) declared unsigned.
+ * Comments below are mine, BTW -- PMM 
+ */
+#ifndef _FP_TO_INT
+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)		\
+  do {								\
+    switch (X##_c)						\
+      {								\
+      case FP_CLS_NORMAL:					\
+	if (X##_e < 0)						\
+	  {							\
+	  /* case FP_CLS_NAN: see above! */			\
+	  case FP_CLS_ZERO:					\
+	    r = 0;						\
+	  }							\
+	else if (X##_e >= rsize - (rsigned != 0))		\
+	  {	/* overflow */					\
+	  case FP_CLS_NAN:                                      \
+          case FP_CLS_INF:					\
+	    if (rsigned)					\
+	      {							\
+		r = 1;						\
+		r <<= rsize - 1;				\
+		r -= 1 - X##_s;					\
+	      }							\
+	    else						\
+	      {							\
+		r = 0;						\
+		if (!X##_s)					\
+		  r = ~r;					\
+	      }							\
+	  }							\
+	else							\
+	  {							\
+	    if (_FP_W_TYPE_SIZE*wc < rsize)			\
+	      {							\
+		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);		\
+		r <<= X##_e - _FP_WFRACBITS_##fs;		\
+	      }							\
+	    else						\
+	      {							\
+		if (X##_e >= _FP_WFRACBITS_##fs)		\
+		  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1)); \
+		else						\
+		  _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
+		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);		\
+	      }							\
+	    if (rsigned && X##_s)				\
+	      r = -r;						\
+	  }							\
+	break;							\
+      }								\
+  } while (0)
+
+#endif /* _FP_TO_INT */
+
+#ifndef _FP_FROM_INT
+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
+  do {									\
+    if (r)								\
+      {									\
+	X##_c = FP_CLS_NORMAL;						\
+									\
+	if ((X##_s = (r < 0)))						\
+	  r = -r;							\
+	/* Note that `r' is now considered unsigned, so we don't have	\
+	   to worry about the single signed overflow case.  */		\
+									\
+	if (rsize <= _FP_W_TYPE_SIZE)					\
+	  __FP_CLZ(X##_e, r);						\
+	else								\
+	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), 	\
+		     (_FP_W_TYPE)r);					\
+	if (rsize < _FP_W_TYPE_SIZE)					\
+		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
+	X##_e = rsize - X##_e - 1;					\
+									\
+	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)	\
+	  __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);	\
+	r &= ~((_FP_W_TYPE)1 << X##_e);					\
+	_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);	\
+	_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));		\
+      }									\
+    else								\
+      {									\
+	X##_c = FP_CLS_ZERO, X##_s = 0;					\
+      }									\
+  } while (0)
+#endif /* FP_FROM_INT */
+
+#ifndef FP_CONV
+#define FP_CONV(dfs,sfs,dwc,swc,D,S)			\
+  do {							\
+    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);	\
+    D##_e = S##_e;					\
+    D##_c = S##_c;					\
+    D##_s = S##_s;					\
+    D##_r |= S##_r;					\
+  } while (0)
+#endif FP_CONV
+
+/*
+ * Helper primitives.
+ */
+
+/* Count leading zeros in a word.  */
+
+#ifndef __FP_CLZ
+#if _FP_W_TYPE_SIZE < 64
+/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
+#define __FP_CLZ(r, x)				\
+  do {						\
+    _FP_W_TYPE _t = (x);			\
+    r = _FP_W_TYPE_SIZE - 1;			\
+    if (_t > 0xffff) r -= 16;			\
+    if (_t > 0xffff) _t >>= 16;			\
+    if (_t > 0xff) r -= 8;			\
+    if (_t > 0xff) _t >>= 8;			\
+    if (_t & 0xf0) r -= 4;			\
+    if (_t & 0xf0) _t >>= 4;			\
+    if (_t & 0xc) r -= 2;			\
+    if (_t & 0xc) _t >>= 2;			\
+    if (_t & 0x2) r -= 1;			\
+  } while (0)
+#else /* not _FP_W_TYPE_SIZE < 64 */
+#define __FP_CLZ(r, x)				\
+  do {						\
+    _FP_W_TYPE _t = (x);			\
+    r = _FP_W_TYPE_SIZE - 1;			\
+    if (_t > 0xffffffff) r -= 32;		\
+    if (_t > 0xffffffff) _t >>= 32;		\
+    if (_t > 0xffff) r -= 16;			\
+    if (_t > 0xffff) _t >>= 16;			\
+    if (_t > 0xff) r -= 8;			\
+    if (_t > 0xff) _t >>= 8;			\
+    if (_t & 0xf0) r -= 4;			\
+    if (_t & 0xf0) _t >>= 4;			\
+    if (_t & 0xc) r -= 2;			\
+    if (_t & 0xc) _t >>= 2;			\
+    if (_t & 0x2) r -= 1;			\
+  } while (0)
+#endif /* not _FP_W_TYPE_SIZE < 64 */
+#endif /* ndef __FP_CLZ */
+
+#define _FP_DIV_HELP_imm(q, r, n, d)		\
+  do {						\
+    q = n / d, r = n % d;			\
+  } while (0)
+
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/single.h linux-2.2.14-pre7/arch/alpha/math-emu/single.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/single.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/single.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,66 @@
+/*
+ * Definitions for IEEE Single Precision
+ */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACBITS_S		24
+#define _FP_FRACXBITS_S		(_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
+#define _FP_WFRACBITS_S		(_FP_WORKBITS + _FP_FRACBITS_S)
+#define _FP_WFRACXBITS_S	(_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
+#define _FP_EXPBITS_S		8
+#define _FP_EXPBIAS_S		127
+#define _FP_EXPMAX_S		255
+#define _FP_QNANBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
+#define _FP_IMPLBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
+#define _FP_OVERFLOW_S		((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
+
+/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
+   chosen by the target machine.  */
+
+union _FP_UNION_S
+{
+  float flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+#else
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_S(X)		_FP_DECL(1,X)
+#define FP_UNPACK_RAW_S(X,val)	_FP_UNPACK_RAW_1(S,X,val)
+#define FP_PACK_RAW_S(val,X)	_FP_PACK_RAW_1(S,val,X)
+
+#define FP_UNPACK_S(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1(S,X,val);		\
+    _FP_UNPACK_CANONICAL(S,1,X);	\
+  } while (0)
+
+#define FP_PACK_S(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(S,1,X);		\
+    _FP_PACK_RAW_1(S,val,X);		\
+  } while (0)
+
+#define FP_NEG_S(R,X)		_FP_NEG(S,1,R,X)
+#define FP_ADD_S(R,X,Y)		_FP_ADD(S,1,R,X,Y)
+#define FP_SUB_S(R,X,Y)		_FP_SUB(S,1,R,X,Y)
+#define FP_MUL_S(R,X,Y)		_FP_MUL(S,1,R,X,Y)
+#define FP_DIV_S(R,X,Y)		_FP_DIV(S,1,R,X,Y)
+#define FP_SQRT_S(R,X)		_FP_SQRT(S,1,R,X)
+
+#define FP_CMP_S(r,X,Y,un)	_FP_CMP(S,1,r,X,Y,un)
+#define FP_CMP_EQ_S(r,X,Y)	_FP_CMP_EQ(S,1,r,X,Y)
+
+#define FP_TO_INT_S(r,X,rsz,rsg)  _FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_FROM_INT_S(X,r,rs,rt)  _FP_FROM_INT(S,1,X,r,rs,rt)
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/soft-fp.h linux-2.2.14-pre7/arch/alpha/math-emu/soft-fp.h
--- linux-2.2.14-pre6/arch/alpha/math-emu/soft-fp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/soft-fp.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,94 @@
+#ifndef SOFT_FP_H
+#define SOFT_FP_H
+
+#include "sfp-machine.h"
+
+#define _FP_WORKBITS		3
+#define _FP_WORK_LSB		((_FP_W_TYPE)1 << 3)
+#define _FP_WORK_ROUND		((_FP_W_TYPE)1 << 2)
+#define _FP_WORK_GUARD		((_FP_W_TYPE)1 << 1)
+#define _FP_WORK_STICKY		((_FP_W_TYPE)1 << 0)
+
+#ifndef FP_RND_NEAREST
+# define FP_RND_NEAREST		0
+# define FP_RND_ZERO		1
+# define FP_RND_PINF		2
+# define FP_RND_MINF		3
+#ifndef FP_ROUNDMODE
+# define FP_ROUNDMODE		FP_RND_NEAREST
+#endif
+#endif
+
+#define _FP_ROUND_NEAREST(wc, X)			\
+({  int __ret = EFLAG_INEXACT;				\
+    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);		\
+    else __ret = 0;					\
+    __ret;						\
+})
+
+#define _FP_ROUND_ZERO(wc, X)		0 /* XXX */
+
+#define _FP_ROUND_PINF(wc, X)				\
+({  int __ret = EFLAG_INEXACT;				\
+    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
+    else __ret = 0;					\
+    __ret;						\
+})
+
+#define _FP_ROUND_MINF(wc, X)				\
+({  int __ret = EFLAG_INEXACT;				\
+    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
+    else __ret = 0;					\
+    __ret;						\
+})
+
+#define _FP_ROUND(wc, X)			\
+({	int __ret = 0;				\
+	switch (FP_ROUNDMODE)			\
+	{					\
+	  case FP_RND_NEAREST:			\
+	    __ret |= _FP_ROUND_NEAREST(wc,X);	\
+	    break;				\
+	  case FP_RND_ZERO:			\
+	    __ret |= _FP_ROUND_ZERO(wc,X);	\
+	    break;				\
+	  case FP_RND_PINF:			\
+	    __ret |= _FP_ROUND_PINF(wc,X);	\
+	    break;				\
+	  case FP_RND_MINF:			\
+	    __ret |= _FP_ROUND_MINF(wc,X);	\
+	    break;				\
+	};					\
+	__ret;					\
+})
+
+#define FP_CLS_NORMAL		0
+#define FP_CLS_ZERO		1
+#define FP_CLS_INF		2
+#define FP_CLS_NAN		3
+
+#define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
+
+#include "op-1.h"
+#include "op-2.h"
+#include "op-4.h"
+#include "op-common.h"
+
+/* Sigh.  Silly things longlong.h needs.  */
+#define UWtype		_FP_W_TYPE
+#define W_TYPE_SIZE	_FP_W_TYPE_SIZE
+
+typedef int SItype __attribute__((mode(SI)));
+typedef int DItype __attribute__((mode(DI)));
+typedef unsigned int USItype __attribute__((mode(SI)));
+typedef unsigned int UDItype __attribute__((mode(DI)));
+#if _FP_W_TYPE_SIZE == 32
+typedef unsigned int UHWtype __attribute__((mode(HI)));
+#elif _FP_W_TYPE_SIZE == 64
+typedef USItype UHWtype;
+#endif
+
+#endif
diff -urN linux-2.2.14-pre6/arch/alpha/math-emu/udivmodti4.c linux-2.2.14-pre7/arch/alpha/math-emu/udivmodti4.c
--- linux-2.2.14-pre6/arch/alpha/math-emu/udivmodti4.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/alpha/math-emu/udivmodti4.c	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,191 @@
+/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */
+
+#include "soft-fp.h"
+
+#undef count_leading_zeros
+#define count_leading_zeros  __FP_CLZ
+
+void
+_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
+	       _FP_W_TYPE n1, _FP_W_TYPE n0,
+	       _FP_W_TYPE d1, _FP_W_TYPE d0)
+{
+  _FP_W_TYPE q0, q1, r0, r1;
+  _FP_I_TYPE b, bm;
+
+  if (d1 == 0)
+    {
+#if !UDIV_NEEDS_NORMALIZATION
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      r0 = n0;
+      r1 = 0;
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      _FP_W_TYPE n2;
+
+	      /* Normalize.  */
+
+	      b = _FP_W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      r0 = n0 >> bm;
+      r1 = 0;
+#endif /* UDIV_NEEDS_NORMALIZATION */
+    }
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  r0 = n0;
+	  r1 = n1;
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      r0 = n0;
+	      r1 = n1;
+	    }
+	  else
+	    {
+	      _FP_W_TYPE m1, m0, n2;
+
+	      /* Normalize.  */
+
+	      b = _FP_W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      sub_ddmmss (n1, n0, n1, n0, m1, m0);
+	      r0 = (n1 << b) | (n0 >> bm);
+	      r1 = n1 >> bm;
+	    }
+	}
+    }
+
+  q[0] = q0; q[1] = q1;
+  r[0] = r0, r[1] = r1;
+}
diff -urN linux-2.2.14-pre6/arch/ppc/common_defconfig linux-2.2.14-pre7/arch/ppc/common_defconfig
--- linux-2.2.14-pre6/arch/ppc/common_defconfig	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/common_defconfig	2003-08-15 15:09:03.000000000 -0700
@@ -252,7 +252,6 @@
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_EISA=y
@@ -271,6 +270,7 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SIS900 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
diff -urN linux-2.2.14-pre6/arch/ppc/defconfig linux-2.2.14-pre7/arch/ppc/defconfig
--- linux-2.2.14-pre6/arch/ppc/defconfig	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/defconfig	2003-08-15 15:09:03.000000000 -0700
@@ -252,7 +252,6 @@
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_EISA=y
@@ -271,6 +270,7 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SIS900 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
diff -urN linux-2.2.14-pre6/arch/ppc/gemini_defconfig linux-2.2.14-pre7/arch/ppc/gemini_defconfig
--- linux-2.2.14-pre6/arch/ppc/gemini_defconfig	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/gemini_defconfig	2003-08-15 15:09:03.000000000 -0700
@@ -230,7 +230,6 @@
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_EISA is not set
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/head.S linux-2.2.14-pre7/arch/ppc/kernel/head.S
--- linux-2.2.14-pre6/arch/ppc/kernel/head.S	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/head.S	2003-08-15 15:09:03.000000000 -0700
@@ -1836,8 +1836,6 @@
 	mr	r6,r28
 	mr	r7,r27
 	bl	identify_machine
-lis r20,0xc0000000@h
-stw	r20,0(r20)	
 	bl	MMU_init
 /*
  * Go back to running unmapped so we can load up new values
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/pmac_pic.c linux-2.2.14-pre7/arch/ppc/kernel/pmac_pic.c
--- linux-2.2.14-pre6/arch/ppc/kernel/pmac_pic.c	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/pmac_pic.c	2003-08-15 15:09:03.000000000 -0700
@@ -3,12 +3,14 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
+#include <linux/pci.h>
+#include <asm/pci-bridge.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/prom.h>
 #include "pmac_pic.h"
 
-/* pmac */struct pmac_irq_hw {
+struct pmac_irq_hw {
         unsigned int    flag;
         unsigned int    enable;
         unsigned int    ack;
@@ -31,6 +33,12 @@
 #define GATWICK_IRQ_POOL_SIZE        10
 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
 
+extern int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+                                      unsigned char offset, unsigned short *val);
+extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+                                      unsigned char offset, unsigned short val);
+
+
 static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
 {
         unsigned long bit = 1UL << (irq_nr & 0x1f);
@@ -108,7 +116,7 @@
 };
 
 struct hw_interrupt_type gatwick_pic = {
-	" GATWICK  ",
+        " PMAC-PI2 ",
 	NULL,
 	NULL,
 	NULL,
@@ -290,17 +298,67 @@
 	}
 }
 
+/*
+ * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
+ * card which includes an ohare chip that acts as a second interrupt
+ * controller.  If we find this second ohare, set it up and fix the
+ * interrupt value in the device tree for the ethernet chip.
+ */
+static void __init enable_second_ohare(void)
+{
+	unsigned char bus, devfn;
+	unsigned short cmd;
+        unsigned long addr;
+	int second_irq;
+	struct device_node *irqctrler = find_devices("pci106b,7");
+	struct device_node *ether;
+
+	if (irqctrler == NULL || irqctrler->n_addrs <= 0)
+		return;
+	addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
+	pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
+	max_irqs = 64;
+	if (pci_device_loc(irqctrler, &bus, &devfn) == 0) {
+		pmac_pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+		cmd &= ~PCI_COMMAND_IO;
+		pmac_pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+	}
+
+	second_irq = irqctrler->intrs[0].line;
+	printk(KERN_INFO "irq: secondary controller on irq %d\n", second_irq);
+	request_irq(second_irq, gatwick_action, SA_INTERRUPT,
+		    "interrupt cascade", 0 );
+
+	/* Fix interrupt for the modem/ethernet combo controller. The number
+	   in the device tree (27) is bogus (correct for the ethernet-only
+	   board but not the combo ethernet/modem board).
+	   The real interrupt is 28 on the second controller -> 28+32 = 60.
+	*/
+	ether = find_devices("pci1011,14");
+	if (ether && ether->n_intrs > 0) {
+		ether->intrs[0].line = 60;
+		printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
+		       ether->intrs[0].line);
+	}
+}
+
 __initfunc(void
 pmac_pic_init(void))
 {
         int i;
         struct device_node *irqctrler;
-        unsigned long addr;
-	int second_irq = -999;
+        volatile struct pmac_irq_hw *addr;
+	int second_irq;
 
-
-	/* G3 powermacs have 64 interrupts, G3 Series PowerBook have 128, 
-	   others have 32 */
+	/*
+	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
+	 * 1998 G3 Series PowerBooks have 128, 
+	 * other powermacs have 32.
+	 * The combo ethernet/modem card for the Powerstar powerbooks
+	 * (2400/3400/3500, ohare based) has a second ohare chip
+	 * effectively making a total of 64.
+	 */
 	max_irqs = max_real_irqs = 32;
 	irqctrler = find_devices("mac-io");
 	if (irqctrler)
@@ -317,24 +375,28 @@
 	/* get addresses of first controller */
 	if (irqctrler) {
 		if  (irqctrler->n_addrs > 0) {
-			addr = (unsigned long) 
-				ioremap(irqctrler->addrs[0].address, 0x40);
-			for (i = 0; i < 2; ++i)
-				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
-					(addr + (2 - i) * 0x10);
+			addr = ioremap(irqctrler->addrs[0].address, 0x40);
+			addr += 2;
+			for (i = 0; i < 2; ++i, --addr)
+				pmac_irq_hw[i] = addr;
 		}
 		
 		/* get addresses of second controller */
-		irqctrler = (irqctrler->next) ? irqctrler->next : NULL;
+		irqctrler = irqctrler->next;
 		if (irqctrler && irqctrler->n_addrs > 0) {
-			addr = (unsigned long) 
-				ioremap(irqctrler->addrs[0].address, 0x40);
-			for (i = 2; i < 4; ++i)
-				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
-					(addr + (4 - i) * 0x10);
+			addr = ioremap(irqctrler->addrs[0].address, 0x40);
+			addr += 2;
+			for (i = 2; i < 4; ++i, --addr)
+				pmac_irq_hw[i] = addr;
 		}
 	}
 
+	/* PowerBooks 3400 and 3500 can have a second controller in a second
+	   ohare chip, on the combo ethernet/modem card */
+	if (machine_is_compatible("AAPL,3400/2400")
+	     || machine_is_compatible("AAPL,3500"))
+		enable_second_ohare();
+
 	/* disable all interrupts in all controllers */
 	for (i = 0; i * 32 < max_irqs; ++i)
 		out_le32(&pmac_irq_hw[i]->enable, 0);
@@ -346,11 +408,11 @@
 			(int)second_irq);
 		if (device_is_compatible(irqctrler, "gatwick"))
 			pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
-		for ( i = max_real_irqs ; i < max_irqs ; i++ )
-			irq_desc[i].ctl = &gatwick_pic;
 		request_irq( second_irq, gatwick_action, SA_INTERRUPT,
-			     "gatwick cascade", 0 );
+			     "interrupt cascade", 0 );
 	}
+	for (i = max_real_irqs; i < max_irqs; i++)
+		irq_desc[i].ctl = &gatwick_pic;
 	printk("System has %d possible interrupts\n", max_irqs);
 	if (max_irqs != max_real_irqs)
 		printk(KERN_DEBUG "%d interrupts on main controller\n",
@@ -381,6 +443,7 @@
 	out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
 	if (max_real_irqs > 32)
 		out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
+	(void)in_le32(&pmac_irq_hw[0]->flag);
 	mb();
 }
 
@@ -392,6 +455,7 @@
 	out_le32(&pmac_irq_hw[0]->enable, 0);
 	if (max_real_irqs > 32)
 		out_le32(&pmac_irq_hw[1]->enable, 0);
+	(void)in_le32(&pmac_irq_hw[0]->flag);
 	mb();
 	for (i = 0; i < max_real_irqs; ++i)
 		if (test_bit(i, sleep_save_mask))
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/pmac_setup.c linux-2.2.14-pre7/arch/ppc/kernel/pmac_setup.c
--- linux-2.2.14-pre6/arch/ppc/kernel/pmac_setup.c	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/pmac_setup.c	2003-08-15 15:09:03.000000000 -0700
@@ -190,7 +190,7 @@
 	return len;
 }
 
-#ifdef CONFIG_SCSI
+#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD)
 /* Find the device number for the disk (if any) at target tgt
    on host adaptor host.
    XXX this really really should be in drivers/scsi/sd.c. */
@@ -217,7 +217,7 @@
             return MKDEV_SD(i);
     return 0;
 }
-#endif
+#endif /* SCSI and BLK_DEV_SD */
 
 /*
  * Dummy mksound function that does nothing.
@@ -434,7 +434,7 @@
 
 __initfunc(void find_boot_device(void))
 {
-#ifdef CONFIG_SCSI
+#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD)
 	if (boot_host != NULL) {
 		boot_dev = sd_find_target(boot_host, boot_target);
 		if (boot_dev != 0)
@@ -464,7 +464,7 @@
 		find_boot_device();
 		found_boot = 1;
 	}
-	if (dev == boot_dev) {
+	if (boot_dev == 0 || dev == boot_dev) {
 		ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
 		boot_dev = NODEV;
 		printk(" (root)");
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/ppc_ksyms.c linux-2.2.14-pre7/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.2.14-pre6/arch/ppc/kernel/ppc_ksyms.c	1999-10-19 17:14:00.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/ppc_ksyms.c	2003-08-15 15:09:03.000000000 -0700
@@ -198,6 +198,8 @@
 EXPORT_SYMBOL(find_compatible_devices);
 EXPORT_SYMBOL(find_path_device);
 EXPORT_SYMBOL(find_phandle);
+EXPORT_SYMBOL(device_is_compatible);
+EXPORT_SYMBOL(machine_is_compatible);
 EXPORT_SYMBOL(get_property);
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_device_loc);
@@ -214,7 +216,6 @@
 #endif /* CONFIG_PMAC */
 
 EXPORT_SYMBOL(abs);
-EXPORT_SYMBOL(device_is_compatible);
 
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
 EXPORT_SYMBOL_NOVERS(__lshrdi3);
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/process.c linux-2.2.14-pre7/arch/ppc/kernel/process.c
--- linux-2.2.14-pre6/arch/ppc/kernel/process.c	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/process.c	2003-08-15 15:09:03.000000000 -0700
@@ -186,6 +186,18 @@
 
 	prev->last_processor = prev->processor;
 	current_set[smp_processor_id()] = new;
+#ifdef CONFIG_GEMINI	
+	/*
+	 * Force a context change on every processor switch for 750's.
+	 * This prevents some corruption problems I was finding on the gemini.
+	 *   -- Cort
+	 */
+	if ( /*(new->processor != new->last_processor) &&*/ ((_get_PVR()>>16) == 8) )
+	{
+		init_new_context(new->mm);
+		get_mmu_context(new);
+	}
+#endif /* CONFIG_GEMINI */	
 #endif /* __SMP__ */
 	new_tss = &new->tss;
 	old_tss = &current->tss;
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/ptrace.c linux-2.2.14-pre7/arch/ppc/kernel/ptrace.c
--- linux-2.2.14-pre6/arch/ppc/kernel/ptrace.c	1999-06-04 13:30:47.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/ptrace.c	2003-08-15 15:09:03.000000000 -0700
@@ -26,7 +26,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -86,7 +86,6 @@
  * tables. NOTE! You should check that the long isn't on a page boundary,
  * and that it is in the task area before calling this: this routine does
  * no checking.
- *
  */
 static unsigned long get_long(struct task_struct * tsk, 
 	struct vm_area_struct * vma, unsigned long addr)
@@ -95,22 +94,31 @@
 	pmd_t * pgmiddle;
 	pte_t * pgtable;
 	unsigned long page;
+	int fault;
 
 repeat:
 	pgdir = pgd_offset(vma->vm_mm, addr);
 	if (pgd_none(*pgdir)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 0);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return 0;
 	}
 	if (pgd_bad(*pgdir)) {
 		printk("ptrace[1]: bad page directory %lx\n", pgd_val(*pgdir));
 		pgd_clear(pgdir);
 		return 0;
 	}
-	pgmiddle = pmd_offset(pgdir,addr);
+	pgmiddle = pmd_offset(pgdir, addr);
 	if (pmd_none(*pgmiddle)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 0);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return 0;
 	}
 	if (pmd_bad(*pgmiddle)) {
 		printk("ptrace[3]: bad pmd %lx\n", pmd_val(*pgmiddle));
@@ -119,8 +127,12 @@
 	}
 	pgtable = pte_offset(pgmiddle, addr);
 	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 0);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return 0;
 	}
 	page = pte_page(*pgtable);
 /* this is a hack for non-kernel-mapped video buffers and similar */
@@ -146,22 +158,31 @@
 	pmd_t *pgmiddle;
 	pte_t *pgtable;
 	unsigned long page;
-		
+	int fault;
+
 repeat:
 	pgdir = pgd_offset(vma->vm_mm, addr);
 	if (!pgd_present(*pgdir)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 1);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return;
 	}
 	if (pgd_bad(*pgdir)) {
 		printk("ptrace[2]: bad page directory %lx\n", pgd_val(*pgdir));
 		pgd_clear(pgdir);
 		return;
 	}
-	pgmiddle = pmd_offset(pgdir,addr);
+	pgmiddle = pmd_offset(pgdir, addr);
 	if (pmd_none(*pgmiddle)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 1);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return;
 	}
 	if (pmd_bad(*pgmiddle)) {
 		printk("ptrace[4]: bad pmd %lx\n", pmd_val(*pgmiddle));
@@ -170,13 +191,21 @@
 	}
 	pgtable = pte_offset(pgmiddle, addr);
 	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 1);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return;
 	}
 	page = pte_page(*pgtable);
 	if (!pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
+		fault = handle_mm_fault(tsk, vma, addr, 1);
+		if (fault > 0)
+			goto repeat;
+		if (fault < 0)
+			force_sig(SIGKILL, tsk);
+		return;
 	}
 /* this is a hack for non-kernel-mapped video buffers and similar */
 	if (MAP_NR(page) < max_mapnr) {
@@ -247,7 +276,7 @@
 		}
 		*result = low;
 	} else
-		*result = get_long(tsk, vma,addr);
+		*result = get_long(tsk, vma, addr);
 	return 0;
 }
 
@@ -299,7 +328,7 @@
 		put_long(tsk, vma,addr & ~(sizeof(long)-1),high);
 		put_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1),low);
 	} else
-		put_long(tsk, vma,addr,data);
+		put_long(tsk, vma, addr, data);
 	return 0;
 }
 
@@ -307,6 +336,7 @@
 {
 	struct task_struct *child;
 	int ret = -EPERM;
+	unsigned long flags;
 
 	lock_kernel();
 	if (request == PTRACE_TRACEME) {
@@ -318,34 +348,40 @@
 		ret = 0;
 		goto out;
 	}
-	if (pid == 1)		/* you may not mess with init */
-		goto out;
 	ret = -ESRCH;
-	if (!(child = find_task_by_pid(pid)))
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	read_unlock(&tasklist_lock);	/* FIXME!!! */
+	if (!child)
 		goto out;
 	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
 	if (request == PTRACE_ATTACH) {
 		if (child == current)
 			goto out;
 		if ((!child->dumpable ||
 		    (current->uid != child->euid) ||
-		    (current->uid != child->uid) ||
 		    (current->uid != child->suid) ||
+		    (current->uid != child->uid) ||
 	 	    (current->gid != child->egid) ||
-	 	    (current->gid != child->gid) ||
-		    (current->gid != child->sgid) ||
-		    (!cap_issubset(child->cap_permitted, current->cap_permitted)))
-		    && !capable(CAP_SYS_PTRACE))
+	 	    (current->gid != child->sgid) ||
+	 	    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out;
 		/* the same process cannot be attached many times */
 		if (child->flags & PF_PTRACED)
 			goto out;
 		child->flags |= PF_PTRACED;
+
+		write_lock_irqsave(&tasklist_lock, flags);
 		if (child->p_pptr != current) {
 			REMOVE_LINKS(child);
 			child->p_pptr = current;
 			SET_LINKS(child);
 		}
+		write_unlock_irqrestore(&tasklist_lock, flags);
+
 		send_sig(SIGSTOP, child, 1);
 		ret = 0;
 		goto out;
@@ -369,11 +405,8 @@
 			down(&child->mm->mmap_sem);
 			ret = read_long(child, addr, &tmp);
 			up(&child->mm->mmap_sem);
-			if (ret < 0)
-				goto out;
-			ret = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
-			if (!ret)
-				put_user(tmp, (unsigned long *) data);
+			if (ret >= 0)
+				ret = put_user(tmp,(unsigned long *) data);
 			goto out;
 		}
 
@@ -386,10 +419,6 @@
 				goto out;
 			}
 			
-			ret = verify_area(VERIFY_WRITE, (void *) data,
-					  sizeof(long));
-			if (ret)
-				goto out;
 			tmp = 0;  /* Default return condition */
 			addr = addr >> 2; /* temporary hack. */
 			if (addr < PT_FPR0) {
@@ -403,7 +432,7 @@
 			else
 				ret = -EIO;
 			if (!ret)
-				put_user(tmp,(unsigned long *) data);
+				ret = put_user(tmp, (unsigned long *) data);
 			goto out;
 		}
 
@@ -442,16 +471,16 @@
 		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 		case PTRACE_CONT: { /* restart after signal. */
 			ret = -EIO;
-			if ((unsigned long) data >= _NSIG)
+			if ((unsigned long) data > _NSIG)
 				goto out;
 			if (request == PTRACE_SYSCALL)
 				child->flags |= PF_TRACESYS;
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			wake_up_process(child);
 			/* make sure the single step bit is not set. */
 			clear_single_step(child);
+			wake_up_process(child);
 			ret = 0;
 			goto out;
 		}
@@ -465,38 +494,40 @@
 			ret = 0;
 			if (child->state == TASK_ZOMBIE) /* already dead */
 				goto out;
-			wake_up_process(child);
 			child->exit_code = SIGKILL;
 			/* make sure the single step bit is not set. */
 			clear_single_step(child);
+			wake_up_process(child);
 			goto out;
 		}
 
 		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
 			ret = -EIO;
-			if ((unsigned long) data >= _NSIG)
+			if ((unsigned long) data > _NSIG)
 				goto out;
 			child->flags &= ~PF_TRACESYS;
 			set_single_step(child);
-			wake_up_process(child);
 			child->exit_code = data;
 			/* give it a chance to run. */
+			wake_up_process(child);
 			ret = 0;
 			goto out;
 		}
 
 		case PTRACE_DETACH: { /* detach a process that was attached. */
 			ret = -EIO;
-			if ((unsigned long) data >= _NSIG)
+			if ((unsigned long) data > _NSIG)
 				goto out;
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
-			wake_up_process(child);
 			child->exit_code = data;
+			write_lock_irqsave(&tasklist_lock, flags);
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
 			SET_LINKS(child);
+			write_unlock_irqrestore(&tasklist_lock, flags);
 			/* make sure the single step bit is not set. */
 			clear_single_step(child);
+			wake_up_process(child);
 			ret = 0;
 			goto out;
 		}
@@ -512,10 +543,9 @@
 
 asmlinkage void syscall_trace(void)
 {
-	lock_kernel();
 	if ((current->flags & (PF_PTRACED|PF_TRACESYS))
 			!= (PF_PTRACED|PF_TRACESYS))
-		goto out;
+		return;
 	current->exit_code = SIGTRAP;
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
@@ -529,6 +559,4 @@
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
-out:
-	unlock_kernel();
 }
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/signal.c linux-2.2.14-pre7/arch/ppc/kernel/signal.c
--- linux-2.2.14-pre6/arch/ppc/kernel/signal.c	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/signal.c	2003-08-15 15:09:03.000000000 -0700
@@ -266,8 +266,8 @@
 
 	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto badframe;
-		if (regs->msr & MSR_FP)
-			giveup_fpu(current);
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
 	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
 	    || __copy_to_user(&frame->fp_regs, current->tss.fpr,
 			      ELF_NFPREG * sizeof(double))
@@ -471,6 +471,8 @@
 
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
+		setup_frame(regs, (struct sigregs *) frame, newsp);
+		return 1;
 	}
 
 	if (regs->trap == 0x0C00 /* System Call! */ &&
@@ -482,10 +484,7 @@
 		regs->result = 0;
 	}
 
-	if (newsp == frame)
-		return 0;		/* no signals delivered */
+	return 0;		/* no signals delivered */
 
-	setup_frame(regs, (struct sigregs *) frame, newsp);
-	return 1;
 }
 
diff -urN linux-2.2.14-pre6/arch/ppc/kernel/sleep.S linux-2.2.14-pre7/arch/ppc/kernel/sleep.S
--- linux-2.2.14-pre6/arch/ppc/kernel/sleep.S	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/ppc/kernel/sleep.S	2003-08-15 15:09:03.000000000 -0700
@@ -171,6 +171,11 @@
  */
 	
 wake_up:
+	/* Flash inval the instruction cache */
+	mfspr	r3,HID0
+	ori	r3,r3, HID0_ICFI
+	mtspr	HID0,r3
+	isync
 	/* Restore the HID0 register.  This turns on the L1 caches. */
 	subi	r1,r1,SL_PC
 	lwz	r3,SL_HID0(r1)
diff -urN linux-2.2.14-pre6/arch/sparc/Makefile linux-2.2.14-pre7/arch/sparc/Makefile
--- linux-2.2.14-pre6/arch/sparc/Makefile	1998-10-04 10:22:42.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.39 1998/09/16 12:31:31 jj Exp $
+# $Id: Makefile,v 1.39.2.1 1999/09/20 12:05:00 jj Exp $
 # sparc/Makefile
 #
 # Makefile for the architecture dependent flags and dependencies on the
@@ -62,10 +62,8 @@
 	-$(MAKE) -C arch/sparc/boot clean
 
 archmrproper:
-	-$(MAKE) -C arch/sparc/math-emu cleansymlinks
 
 archdep:
-	-$(MAKE) -C arch/sparc/math-emu symlinks
 
 check_asm:
 	$(MAKE) -C arch/sparc/kernel check_asm
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fabss.c linux-2.2.14-pre7/arch/sparc/math-emu/fabss.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fabss.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fabss.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,6 +0,0 @@
-int FABSS(unsigned long *rd, unsigned long *rs2)
-{
-	/* Clear the sign bit (high bit of word 0) */
-	rd[0] = rs2[0] & 0x7fffffffUL;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmpd.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmpd.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmpd.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmpd.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FCMPD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B);
-	long ret;
-	unsigned long *fsr = rd;
-	
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	FP_CMP_D(ret, B, A, 2);
-	if (ret == -1)
-		ret = 2;
-
-	*fsr = (*fsr & ~0xc00) | (ret << 10); 
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmped.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmped.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmped.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmped.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FCMPED(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B);
-	long ret;
-	unsigned long *fsr = rd;
-	
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	FP_CMP_D(ret, B, A, 2);
-	if (ret == -1)
-		ret = 2;
-
-	*fsr = (*fsr & ~0xc00) | (ret << 10); 
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmpeq.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmpeq.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmpeq.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmpeq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FCMPEQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B);
-	long ret;
-	unsigned long fsr;
-	
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_CMP_Q(ret, B, A, 3);
-	if (ret == -1) ret = 2;
-	fsr = *(unsigned long *)rd;
-	fsr &= ~0xc00; fsr |= (ret << 10);
-	*(unsigned long *)rd = fsr;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmpes.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmpes.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmpes.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmpes.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FCMPES(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B);
-	long ret;
-	unsigned long *fsr = rd;
-	
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	FP_CMP_S(ret, B, A, 1);
-	if (ret == -1)
-		ret = 2;
-
-	*fsr = (*fsr & ~0xc00) | (ret << 10); 
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmpq.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmpq.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmpq.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmpq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FCMPQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B);
-	long ret;
-	unsigned long fsr;
-	
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_CMP_Q(ret, B, A, 3);
-	if (ret == -1) ret = 2;
-	fsr = *(unsigned long *)rd;
-	fsr &= ~0xc00; fsr |= (ret << 10);
-	*(unsigned long *)rd = fsr;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fcmps.c linux-2.2.14-pre7/arch/sparc/math-emu/fcmps.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fcmps.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fcmps.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FCMPS(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B);
-	long ret;
-	unsigned long *fsr = rd;
-	
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	FP_CMP_S(ret, B, A, 1);
-	if (ret == -1)
-		ret = 2;
-
-	*fsr = (*fsr & ~0xc00) | (ret << 10); 
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fdmulq.c linux-2.2.14-pre7/arch/sparc/math-emu/fdmulq.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fdmulq.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fdmulq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FDMULQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(IN); FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-
-	__FP_UNPACK_D(IN, rs1);
-	FP_CONV(Q,D,4,2,A,IN);
-	__FP_UNPACK_D(IN, rs2);
-	FP_CONV(Q,D,4,2,B,IN);
-	FP_MUL_Q(R, A, B);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fdtoq.c linux-2.2.14-pre7/arch/sparc/math-emu/fdtoq.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fdtoq.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fdtoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FDTOQ(void *rd, void *rs2)
-{
-	FP_DECL_D(A); FP_DECL_Q(R);
-
-	__FP_UNPACK_D(A, rs2);
-	FP_CONV(Q,D,4,2,R,A);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fdtos.c linux-2.2.14-pre7/arch/sparc/math-emu/fdtos.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fdtos.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fdtos.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FDTOS(void *rd, void *rs2)
-{
-	FP_DECL_D(A); FP_DECL_S(R);
-
-	__FP_UNPACK_D(A, rs2);
-	FP_CONV(S,D,1,2,R,A);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fmovs.c linux-2.2.14-pre7/arch/sparc/math-emu/fmovs.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fmovs.c	1998-04-14 17:44:19.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fmovs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-int FMOVS(unsigned long *rd, unsigned long *rs2)
-{
-	rd[0] = rs2[0];
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fnegs.c linux-2.2.14-pre7/arch/sparc/math-emu/fnegs.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fnegs.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fnegs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,6 +0,0 @@
-int FNEGS(unsigned long *rd, unsigned long *rs2)
-{
- 	/* just change the sign bit */
-	rd[0] = rs2[0] ^ 0x80000000UL;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fqtod.c linux-2.2.14-pre7/arch/sparc/math-emu/fqtod.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fqtod.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fqtod.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FQTOD(void *rd, void *rs2)
-{
-	FP_DECL_Q(A); FP_DECL_D(R);
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_CONV(D,Q,2,4,R,A);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fqtos.c linux-2.2.14-pre7/arch/sparc/math-emu/fqtos.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fqtos.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fqtos.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "single.h"
-
-int FQTOS(void *rd, void *rs2)
-{
-	FP_DECL_Q(A); FP_DECL_S(R);
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_CONV(S,Q,1,4,R,A);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fsmuld.c linux-2.2.14-pre7/arch/sparc/math-emu/fsmuld.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fsmuld.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fsmuld.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FSMULD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(IN); FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-
-	__FP_UNPACK_S(IN, rs1);
-	FP_CONV(D,S,2,1,A,IN);
-	__FP_UNPACK_S(IN, rs2);
-	FP_CONV(D,S,2,1,B,IN);
-	FP_MUL_D(R, A, B);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fstod.c linux-2.2.14-pre7/arch/sparc/math-emu/fstod.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fstod.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fstod.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FSTOD(void *rd, void *rs2)
-{
-	FP_DECL_S(A); FP_DECL_D(R);
-
-	__FP_UNPACK_S(A, rs2);
-	FP_CONV(D,S,2,1,R,A);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/fstoq.c linux-2.2.14-pre7/arch/sparc/math-emu/fstoq.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/fstoq.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/fstoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "single.h"
-
-int FSTOQ(void *rd, void *rs2)
-{
-	FP_DECL_S(A); FP_DECL_Q(R);
-
-	__FP_UNPACK_S(A, rs2);
-	FP_CONV(Q,S,4,1,R,A);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/Makefile linux-2.2.14-pre7/arch/sparc/math-emu/Makefile
--- linux-2.2.14-pre6/arch/sparc/math-emu/Makefile	1998-04-14 17:44:19.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc/math-emu/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -8,19 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := math-emu.o
-O_OBJS   := math.o ashldi3.o fabss.o faddd.o faddq.o fadds.o 		\
-		fcmpd.o fcmped.o fcmpeq.o fcmpes.o fcmpq.o fcmps.o	\
-		fdivd.o fdivq.o fdivs.o fdmulq.o fdtoi.o fdtoq.o	\
-		fdtos.o fitoq.o fmovs.o fmuld.o fmulq.o fmuls.o		\
-		fnegs.o fqtod.o fqtoi.o fqtos.o fsmuld.o fsqrtd.o	\
-		fsqrtq.o fsqrts.o fstod.o fstoi.o fstoq.o fsubd.o 	\
-		fsubq.o	fsubs.o udivmodti4.o
-
-LINKS	 := double.h faddd.c faddq.c fadds.c fdivd.c fdivq.c fdivs.c	\
-		fdtoi.c fitoq.c fmuld.c fmulq.c fmuls.c fqtoi.c		\
-		fsqrtd.c fsqrtq.c fsqrts.c fstoi.c fsubd.c 		\
-		fsubq.c	fsubs.c op-1.h op-2.h op-4.h op-common.h quad.h	\
-		single.h soft-fp.h udivmodti4.c
+O_OBJS   := math.o ashldi3.o
 
 .S.s:
 	$(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s
@@ -28,10 +16,6 @@
 .S.o:
 	$(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
 
-include $(TOPDIR)/Rules.make
-
-symlinks:
-	ln -sf $(patsubst %,../../sparc64/math-emu/%,$(LINKS)) .
+CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
 
-cleansymlinks:
-	rm -f $(LINKS)
+include $(TOPDIR)/Rules.make
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/math.c linux-2.2.14-pre7/arch/sparc/math-emu/math.c
--- linux-2.2.14-pre6/arch/sparc/math-emu/math.c	1999-03-10 16:53:36.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/math.c	2003-08-15 15:09:03.000000000 -0700
@@ -1,26 +1,19 @@
-/* 
+/*
  * arch/sparc/math-emu/math.c
  *
  * Copyright (C) 1998 Peter Maydell (pmaydell@chiark.greenend.org.uk)
- * Based on the sparc64 code by Jakub Jelinek.
+ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  *
  * This is a good place to start if you're trying to understand the
- * emulation code, because it's pretty simple. What we do is 
+ * emulation code, because it's pretty simple. What we do is
  * essentially analyse the instruction to work out what the operation
  * is and which registers are involved. We then execute the appropriate
  * FXXXX function. [The floating point queue introduces a minor wrinkle;
  * see below...]
  * The fxxxxx.c files each emulate a single insn. They look relatively
  * simple because the complexity is hidden away in an unholy tangle
- * of preprocessor macros. 
- *
- * WARNING : don't look at the macro definitions unless you 
- * absolutely have to! They're extremely ugly, rather complicated
- * and a single line in an fxxxx.c file can expand to the equivalent 
- * of  30 lines or more of C. Of course, any error in those 30 lines 
- * is reported by the compiler as an error in the single line with the
- * macro usage...
- * Question: should we replace them with inline functions?
+ * of preprocessor macros.
  *
  * The first layer of macros is single.h, double.h, quad.h. Generally
  * these files define macros for working with floating point numbers
@@ -29,11 +22,11 @@
  * generic macros (in this case _FP_ADD(D,2,R,X,Y) where the number
  * of machine words required to store the given IEEE format is passed
  * as a parameter. [double.h and co check the number of bits in a word
- * and define FP_ADD_D & co appropriately]. 
+ * and define FP_ADD_D & co appropriately].
  * The generic macros are defined in op-common.h. This is where all
  * the grotty stuff like handling NaNs is coded. To handle the possible
  * word sizes macros in op-common.h use macros like _FP_FRAC_SLL_##wc()
- * where wc is the 'number of machine words' parameter (here 2). 
+ * where wc is the 'number of machine words' parameter (here 2).
  * These are defined in the third layer of macros: op-1.h, op-2.h
  * and op-4.h. These handle operations on floating point numbers composed
  * of 1,2 and 4 machine words respectively. [For example, on sparc64
@@ -41,7 +34,7 @@
  * constructs in op-1.h, but on sparc32 they use op-2.h definitions.]
  * soft-fp.h is on the same level as op-common.h, and defines some
  * macros which are independent of both word size and FP format.
- * Finally, sfp-machine.h is the machine dependent part of the 
+ * Finally, sfp-machine.h is the machine dependent part of the
  * code: it defines the word size and what type a word is. It also
  * defines how _FP_MUL_MEAT_t() maps to _FP_MUL_MEAT_n_* : op-n.h
  * provide several possible flavours of multiply algorithm, most
@@ -64,59 +57,11 @@
  * so we follow that practice...
  */
 
-/* WISHLIST:
- *
- * + Replace all the macros with inline functions. These should
- * have the same effect but be much easier to work with.
- *
- * + Emulate the IEEE exception flags. We don't currently do this
- * because a) it would require significant alterations to
- * the emulation macros [see the comments about _FP_NEG()
- * in op-common.c and note that we'd need to invent a convention
- * for passing in the flags to FXXXX fns and returning them] and 
- * b) SPARClinux doesn't let users access the flags anyway 
- * [contrast Solaris, which allows you to examine, clear or set
- * the flags, and request that exceptions cause SIGFPE 
- * [which you then set up a signal handler for, obviously...]].
- * Erm, (b) may quite possibly be garbage. %fsr is user-writable
- * so you don't need a syscall. There may or may not be library
- * support.
- *
- * + Emulation of FMULQ, FDIVQ, FSQRTQ, FDMULQ needs to be 
- * written!
- * 
- * + reindent code to conform to Linux kernel standard :->
- *
- * + work out whether all the compile-time warnings are bogus
- *
- * + check that conversion to/from integers works
- * 
- * + check with the SPARC architecture manual to see if we resolve
- * the implementation-dependent bits of the IEEE spec in the
- * same manner as the hardware.
- *
- * + more test cases for the test script always welcome!
- *
- * + illegal opcodes currently cause SIGFPEs. We should arrange
- * to tell the traps.c code to SIGILL instead. Currently,
- * everywhere that we return 0 should cause SIGILL, I think.
- * SIGFPE should only be caused if we set an IEEE exception bit
- * and the relevant trap bit is also set. (this means that 
- * traps.c should do this; also it should handle the case of
- * IEEE exception generated directly by the hardware.)
- * Should illegal_fp_register (which is a flavour of fp exception)
- * cause SIGFPE or  SIGILL?
- *
- * + the test script needs to be extended to handle the quadword
- * and comparison insns.
- *
- * + _FP_DIV_MEAT_2_udiv_64() appears to work but it should be
- * checked by somebody who understands the algorithm :->
- * 
- * + fpsave() saves the FP queue but fpload() doesn't reload it.
+/* TODO:
+ * fpsave() saves the FP queue but fpload() doesn't reload it.
  * Therefore when we context switch or change FPU ownership
  * we have to check to see if the queue had anything in it and
- * emulate it if it did. This is going to be a pain. 
+ * emulate it if it did. This is going to be a pain.
  */
 
 #include <linux/types.h>
@@ -124,71 +69,57 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 
+#include "sfp-util.h"
 #include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+#include "quad.h"
 
 #define FLOATFUNC(x) extern int x(void *,void *,void *)
 
-/* Current status: we don't properly emulate the difficult quadword
- * insns (MUL, DIV, SQRT).
- * There are also some ops involving the FP registers which we don't
- * emulate: the branch on FP condition flags and the load/store to
- * FP regs or FSR. I'm assuming that these will never generate traps
- * (not unreasonable if there's an FPU at all; comments in the NetBSD
- * kernel source agree on this point). If we wanted to allow
- * purely software-emulation of the FPU with FPU totally disabled
- * or non-existent, we'd have to emulate these as well. We'd also
- * need to alter the fp_disabled trap handler to call the math-emu
- * code appropriately. The structure of do_one_mathemu() is also
- * inappropriate for these ops (as it has no way to alter the pc, 
- * for a start) and it might be better to special-case them in do_mathemu().
- * Oh, and you'd need to alter the traps.c code so it didn't try to
- * fpsave() and fpload(). If there's genuinely no FPU then there's 
- * probably bits of kernel stuff that just won't work anyway...
- */
-
 /* The Vn labels indicate what version of the SPARC architecture gas thinks
- * each insn is. This is from the binutils source :-> 
+ * each insn is. This is from the binutils source :->
  */
 /* quadword instructions */
-FLOATFUNC(FSQRTQ);                                /* v8 NYI */
-FLOATFUNC(FADDQ);                                 /* v8 */
-FLOATFUNC(FSUBQ);                                 /* v8 */
-FLOATFUNC(FMULQ);                                 /* v8 NYI */
-FLOATFUNC(FDIVQ);                                 /* v8 NYI */
-FLOATFUNC(FDMULQ);                                /* v8 NYI */
-FLOATFUNC(FQTOS);                                 /* v8 */
-FLOATFUNC(FQTOD);                                 /* v8 */
-FLOATFUNC(FITOQ);                                 /* v8 */
-FLOATFUNC(FSTOQ);                                 /* v8 */
-FLOATFUNC(FDTOQ);                                 /* v8 */
-FLOATFUNC(FQTOI);                                 /* v8 */
-FLOATFUNC(FCMPQ);                                 /* v8 */
-FLOATFUNC(FCMPEQ);                                /* v8 */
+#define FSQRTQ	0x02b		/* v8 */
+#define FADDQ	0x043		/* v8 */
+#define FSUBQ	0x047		/* v8 */
+#define FMULQ	0x04b		/* v8 */
+#define FDIVQ	0x04f		/* v8 */
+#define FDMULQ	0x06e		/* v8 */
+#define FQTOS	0x0c7		/* v8 */
+#define FQTOD	0x0cb		/* v8 */
+#define FITOQ	0x0cc		/* v8 */
+#define FSTOQ	0x0cd		/* v8 */
+#define FDTOQ	0x0ce		/* v8 */
+#define FQTOI	0x0d3		/* v8 */
+#define FCMPQ	0x053		/* v8 */
+#define FCMPEQ	0x057		/* v8 */
 /* single/double instructions (subnormal): should all work */
-FLOATFUNC(FSQRTS);                                /* v7 */
-FLOATFUNC(FSQRTD);                                /* v7 */
-FLOATFUNC(FADDS);                                 /* v6 */
-FLOATFUNC(FADDD);                                 /* v6 */
-FLOATFUNC(FSUBS);                                 /* v6 */
-FLOATFUNC(FSUBD);                                 /* v6 */
-FLOATFUNC(FMULS);                                 /* v6 */
-FLOATFUNC(FMULD);                                 /* v6 */
-FLOATFUNC(FDIVS);                                 /* v6 */
-FLOATFUNC(FDIVD);                                 /* v6 */
-FLOATFUNC(FSMULD);                                /* v8 */
-FLOATFUNC(FDTOS);                                 /* v6 */
-FLOATFUNC(FSTOD);                                 /* v6 */
-FLOATFUNC(FSTOI);                                 /* v6 */
-FLOATFUNC(FDTOI);                                 /* v6 */
-FLOATFUNC(FABSS);                                 /* v6 */
-FLOATFUNC(FCMPS);                                 /* v6 */
-FLOATFUNC(FCMPES);                                /* v6 */
-FLOATFUNC(FCMPD);                                 /* v6 */
-FLOATFUNC(FCMPED);                                /* v6 */
-FLOATFUNC(FMOVS);                                 /* v6 */
-FLOATFUNC(FNEGS);                                 /* v6 */
-FLOATFUNC(FITOS);                                 /* v6 */
-FLOATFUNC(FITOD);                                 /* v6 */
+#define FSQRTS	0x029		/* v7 */
+#define FSQRTD	0x02a		/* v7 */
+#define FADDS	0x041		/* v6 */
+#define FADDD	0x042		/* v6 */
+#define FSUBS	0x045		/* v6 */
+#define FSUBD	0x046		/* v6 */
+#define FMULS	0x049		/* v6 */
+#define FMULD	0x04a		/* v6 */
+#define FDIVS	0x04d		/* v6 */
+#define FDIVD	0x04e		/* v6 */
+#define FSMULD	0x069		/* v6 */
+#define FDTOS	0x0c6		/* v6 */
+#define FSTOD	0x0c9		/* v6 */
+#define FSTOI	0x0d1		/* v6 */
+#define FDTOI	0x0d2		/* v6 */
+#define FABSS	0x009		/* v6 */
+#define FCMPS	0x051		/* v6 */
+#define FCMPES	0x055		/* v6 */
+#define FCMPD	0x052		/* v6 */
+#define FCMPED	0x056		/* v6 */
+#define FMOVS	0x001		/* v6 */
+#define FNEGS	0x005		/* v6 */
+#define FITOS	0x0c4		/* v6 */
+#define FITOD	0x0c8		/* v6 */
 
 #define FSR_TEM_SHIFT	23UL
 #define FSR_TEM_MASK	(0x1fUL << FSR_TEM_SHIFT)
@@ -197,7 +128,7 @@
 #define FSR_CEXC_SHIFT	0UL
 #define FSR_CEXC_MASK	(0x1fUL << FSR_CEXC_SHIFT)
 
-static int do_one_mathemu(u32 insn, unsigned long *fsr, unsigned long *fregs);   
+static int do_one_mathemu(u32 insn, unsigned long *fsr, unsigned long *fregs);
 
 /* Unlike the Sparc64 version (which has a struct fpustate), we
  * pass the taskstruct corresponding to the task which currently owns the
@@ -210,65 +141,65 @@
  */
 int do_mathemu(struct pt_regs *regs, struct task_struct *fpt)
 {
-   /* regs->pc isn't necessarily the PC at which the offending insn is sitting.
-    * The FPU maintains a queue of FPops which cause traps. 
-    * When it hits an instruction that requires that the trapped op succeeded
-    * (usually because it reads a reg. that the trapped op wrote) then it
-    * causes this exception. We need to emulate all the insns on the queue
-    * and then allow the op to proceed.
-    * This code should also handle the case where the trap was precise,
-    * in which case the queue length is zero and regs->pc points at the 
-    * single FPop to be emulated. (this case is untested, though :->) 
-    * You'll need this case if you want to be able to emulate all FPops
-    * because the FPU either doesn't exist or has been software-disabled.
-    * [The UltraSPARC makes FP a precise trap; this isn't as stupid as it 
-    * might sound because the Ultra does funky things with a superscalar
-    * architecture.]
-    */
-   
-   /* You wouldn't believe how often I typed 'ftp' when I meant 'fpt' :-> */
-
-   int i;
-   int retcode = 0;                               /* assume all succeed */
-   unsigned long insn;
-   
-#ifdef DEBUG_MATHEMU   
-   printk("In do_mathemu()... pc is %08lx\n", regs->pc);
-   printk("fpqdepth is %ld\n",fpt->tss.fpqdepth);
-   for (i = 0; i < fpt->tss.fpqdepth; i++)
-      printk("%d: %08lx at %08lx\n",i,fpt->tss.fpqueue[i].insn, (unsigned long)fpt->tss.fpqueue[i].insn_addr);
-#endif      
-
-   if (fpt->tss.fpqdepth == 0) {                   /* no queue, guilty insn is at regs->pc */
-#ifdef DEBUG_MATHEMU   
-      printk("precise trap at %08lx\n", regs->pc);
+	/* regs->pc isn't necessarily the PC at which the offending insn is sitting.
+	 * The FPU maintains a queue of FPops which cause traps.
+	 * When it hits an instruction that requires that the trapped op succeeded
+	 * (usually because it reads a reg. that the trapped op wrote) then it
+	 * causes this exception. We need to emulate all the insns on the queue
+	 * and then allow the op to proceed.
+	 * This code should also handle the case where the trap was precise,
+	 * in which case the queue length is zero and regs->pc points at the
+	 * single FPop to be emulated. (this case is untested, though :->)
+	 * You'll need this case if you want to be able to emulate all FPops
+	 * because the FPU either doesn't exist or has been software-disabled.
+	 * [The UltraSPARC makes FP a precise trap; this isn't as stupid as it
+	 * might sound because the Ultra does funky things with a superscalar
+	 * architecture.]
+	 */
+
+	/* You wouldn't believe how often I typed 'ftp' when I meant 'fpt' :-> */
+
+	int i;
+	int retcode = 0;                               /* assume all succeed */
+	unsigned long insn;
+
+#ifdef DEBUG_MATHEMU
+	printk("In do_mathemu()... pc is %08lx\n", regs->pc);
+	printk("fpqdepth is %ld\n", fpt->tss.fpqdepth);
+	for (i = 0; i < fpt->tss.fpqdepth; i++)
+		printk("%d: %08lx at %08lx\n", i, fpt->tss.fpqueue[i].insn,
+		       (unsigned long)fpt->tss.fpqueue[i].insn_addr);
+#endif
+
+	if (fpt->tss.fpqdepth == 0) {                   /* no queue, guilty insn is at regs->pc */
+#ifdef DEBUG_MATHEMU
+		printk("precise trap at %08lx\n", regs->pc);
 #endif
-      if (!get_user(insn, (u32 *)regs->pc)) {
-         retcode = do_one_mathemu(insn, &fpt->tss.fsr, fpt->tss.float_regs);
-         if (retcode) {
-            /* in this case we need to fix up PC & nPC */
-            regs->pc = regs->npc;
-            regs->npc += 4;
-         }
-      }
-      return retcode;
-   }
-
-   /* Normal case: need to empty the queue... */
-   for (i = 0; i < fpt->tss.fpqdepth; i++)
-   {
-      retcode = do_one_mathemu(fpt->tss.fpqueue[i].insn, &(fpt->tss.fsr), fpt->tss.float_regs);
-      if (!retcode)                               /* insn failed, no point doing any more */
-         break;
-   }
-   /* Now empty the queue and clear the queue_not_empty flag */
-   if(retcode)
-	   fpt->tss.fsr &= ~(0x3000 | FSR_CEXC_MASK);
-   else
-	   fpt->tss.fsr &= ~0x3000;
-   fpt->tss.fpqdepth = 0;
-   
-   return retcode;
+		if (!get_user(insn, (u32 *)regs->pc)) {
+			retcode = do_one_mathemu(insn, &fpt->tss.fsr, fpt->tss.float_regs);
+			if (retcode) {
+				/* in this case we need to fix up PC & nPC */
+				regs->pc = regs->npc;
+				regs->npc += 4;
+			}
+		}
+		return retcode;
+	}
+
+	/* Normal case: need to empty the queue... */
+	for (i = 0; i < fpt->tss.fpqdepth; i++) {
+		retcode = do_one_mathemu(fpt->tss.fpqueue[i].insn, &(fpt->tss.fsr), fpt->tss.float_regs);
+		if (!retcode)                               /* insn failed, no point doing any more */
+			break;
+	}
+	/* Now empty the queue and clear the queue_not_empty flag */
+	if(retcode)
+		fpt->tss.fsr &= ~(0x3000 | FSR_CEXC_MASK);
+	else
+		fpt->tss.fsr &= ~0x3000;
+	fpt->tss.fpqdepth = 0;
+
+	return retcode;
 }
 
 /* All routines returning an exception to raise should detect
@@ -279,7 +210,7 @@
  *
  * We return 0 if a SIGFPE should be sent, 1 otherwise.
  */
-static int record_exception(unsigned long *pfsr, int eflag)
+static inline int record_exception(unsigned long *pfsr, int eflag)
 {
 	unsigned long fsr = *pfsr;
 	int would_trap;
@@ -291,46 +222,36 @@
 	if(would_trap != 0) {
 		eflag &= ((fsr & FSR_TEM_MASK) >> FSR_TEM_SHIFT);
 		if((eflag & (eflag - 1)) != 0) {
-			if(eflag & EFLAG_INVALID)
-				eflag = EFLAG_INVALID;
-			else if(eflag & EFLAG_DIVZERO)
-				eflag = EFLAG_DIVZERO;
-			else if(eflag & EFLAG_INEXACT)
-				eflag = EFLAG_INEXACT;
+			if(eflag & FP_EX_INVALID)
+				eflag = FP_EX_INVALID;
+			else if(eflag & FP_EX_OVERFLOW)
+				eflag = FP_EX_OVERFLOW;
+			else if(eflag & FP_EX_UNDERFLOW)
+				eflag = FP_EX_UNDERFLOW;
+			else if(eflag & FP_EX_DIVZERO)
+				eflag = FP_EX_DIVZERO;
+			else if(eflag & FP_EX_INEXACT)
+				eflag = FP_EX_INEXACT;
 		}
 	}
 
-	/* Set CEXC, here are the rules:
+	/* Set CEXC, here is the rule:
 	 *
-	 * 1) In general all FPU ops will set one and only one
+	 *    In general all FPU ops will set one and only one
 	 *    bit in the CEXC field, this is always the case
 	 *    when the IEEE exception trap is enabled in TEM.
-	 *
-	 * 2) As a special case, if an overflow or underflow
-	 *    is being signalled, AND the trap is not enabled
-	 *    in TEM, then the inexact field shall also be set.
 	 */
 	fsr &= ~(FSR_CEXC_MASK);
-	if(would_trap ||
-	   (eflag & (EFLAG_OVERFLOW | EFLAG_UNDERFLOW)) == 0) {
-		fsr |= ((long)eflag << FSR_CEXC_SHIFT);
-	} else {
-		fsr |= (((long)eflag << FSR_CEXC_SHIFT) |
-			(EFLAG_INEXACT << FSR_CEXC_SHIFT));
-	}
+	fsr |= ((long)eflag << FSR_CEXC_SHIFT);
 
-	/* Set the AEXC field, rules are:
+	/* Set the AEXC field, rule is:
 	 *
-	 * 1) If a trap would not be generated, the
+	 *    If a trap would not be generated, the
 	 *    CEXC just generated is OR'd into the
 	 *    existing value of AEXC.
-	 *
-	 * 2) When a trap is generated, AEXC is cleared.
 	 */
 	if(would_trap == 0)
 		fsr |= ((long)eflag << FSR_AEXC_SHIFT);
-	else
-		fsr &= ~(FSR_AEXC_MASK);
 
 	/* If trapping, indicate fault trap type IEEE. */
 	if(would_trap != 0)
@@ -341,159 +262,258 @@
 	return (would_trap ? 0 : 1);
 }
 
-static int do_one_mathemu(u32 insn, unsigned long *fsr, unsigned long *fregs)
+typedef union {
+	u32 s;
+	u64 d;
+	u64 q[2];
+} *argp;
+
+static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs)
 {
-   /* Emulate the given insn, updating fsr and fregs appropriately. */
-   int type = 0; 
-   /* 01 is single, 10 is double, 11 is quad, 
-    * 000011 is rs1, 001100 is rs2, 110000 is rd (00 in rd is fcc)
-    * 111100000000 tells which ftt that may happen in 
-    * (this field not used on sparc32 code, as we can't 
-    * extract trap type info for ops on the FP queue) 
-    */
-   int freg, eflag;
-   int (*func)(void *,void *,void *) = NULL;
-   void *rs1 = NULL, *rs2 = NULL, *rd = NULL;   
+	/* Emulate the given insn, updating fsr and fregs appropriately. */
+	int type = 0;
+	/* r is rd, b is rs2 and a is rs1. The *u arg tells
+	   whether the argument should be packed/unpacked (0 - do not unpack/pack, 1 - unpack/pack)
+	   non-u args tells the size of the argument (0 - no argument, 1 - single, 2 - double, 3 - quad */
+#define TYPE(dummy, r, ru, b, bu, a, au) type = (au << 2) | (a << 0) | (bu << 5) | (b << 3) | (ru << 8) | (r << 6)
+	int freg;
+	argp rs1 = NULL, rs2 = NULL, rd = NULL;
+	FP_DECL_EX;
+	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+	FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
+	FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
+	int IR;
+	long fsr;
 
 #ifdef DEBUG_MATHEMU
-   printk("In do_mathemu(), emulating %08lx\n", insn);
-#endif   
-      
-   if ((insn & 0xc1f80000) == 0x81a00000) /* FPOP1 */ {
-      switch ((insn >> 5) & 0x1ff) {
-         /* QUAD - ftt == 3 */
-         case 0x001: type = 0x314; func = FMOVS; break;
-         case 0x005: type = 0x314; func = FNEGS; break;
-         case 0x009: type = 0x314; func = FABSS; break;
-         case 0x02b: type = 0x33c; func = FSQRTQ; break;
-         case 0x043: type = 0x33f; func = FADDQ; break;
-         case 0x047: type = 0x33f; func = FSUBQ; break;
-         case 0x04b: type = 0x33f; func = FMULQ; break;
-         case 0x04f: type = 0x33f; func = FDIVQ; break;
-         case 0x06e: type = 0x33a; func = FDMULQ; break;
-         case 0x0c7: type = 0x31c; func = FQTOS; break;
-         case 0x0cb: type = 0x32c; func = FQTOD; break;
-         case 0x0cc: type = 0x334; func = FITOQ; break;
-         case 0x0cd: type = 0x334; func = FSTOQ; break;
-         case 0x0ce: type = 0x338; func = FDTOQ; break;
-         case 0x0d3: type = 0x31c; func = FQTOI; break;
-            /* SUBNORMAL - ftt == 2 */
-         case 0x029: type = 0x214; func = FSQRTS; break;
-         case 0x02a: type = 0x228; func = FSQRTD; break;
-         case 0x041: type = 0x215; func = FADDS; break;
-         case 0x042: type = 0x22a; func = FADDD; break;
-         case 0x045: type = 0x215; func = FSUBS; break;
-         case 0x046: type = 0x22a; func = FSUBD; break;
-         case 0x049: type = 0x215; func = FMULS; break;
-         case 0x04a: type = 0x22a; func = FMULD; break;
-         case 0x04d: type = 0x215; func = FDIVS; break;
-         case 0x04e: type = 0x22a; func = FDIVD; break;
-         case 0x069: type = 0x225; func = FSMULD; break;
-         case 0x0c6: type = 0x218; func = FDTOS; break;
-         case 0x0c9: type = 0x224; func = FSTOD; break;
-         case 0x0d1: type = 0x214; func = FSTOI; break;
-         case 0x0d2: type = 0x218; func = FDTOI; break;
-         default: 
-#ifdef DEBUG_MATHEMU         
-         	printk("unknown FPop1: %03lx\n",(insn>>5)&0x1ff);
-#endif         
-      }
-   }
-   else if ((insn & 0xc1f80000) == 0x81a80000) /* FPOP2 */ {
-      switch ((insn >> 5) & 0x1ff) {
-         case 0x051: type = 0x305; func = FCMPS; break;
-         case 0x052: type = 0x30a; func = FCMPD; break;
-         case 0x053: type = 0x30f; func = FCMPQ; break;
-         case 0x055: type = 0x305; func = FCMPES; break;
-         case 0x056: type = 0x30a; func = FCMPED; break;
-         case 0x057: type = 0x30f; func = FCMPEQ; break;
-         default: 
-#ifdef DEBUG_MATHEMU         
-         	printk("unknown FPop2: %03lx\n",(insn>>5)&0x1ff);
-#endif         	
-      }
-   }
-   
-   if (!type) { /* oops, didn't recognise that FPop */
-      printk("attempt to emulate unrecognised FPop!\n");
-      return 0;
-   }
-   
-   /* Decode the registers to be used */
-   freg = (*fsr >> 14) & 0xf;
-
-   *fsr &= ~0x1c000;                              /* clear the traptype bits */
-    
-   freg = ((insn >> 14) & 0x1f);
-   switch (type & 0x3)                            /* is rs1 single, double or quad? */
-   {
-      case 3:
-         if (freg & 3)                            /* quadwords must have bits 4&5 of the */
-         {                                        /* encoded reg. number set to zero. */
-            *fsr |= (6 << 14);                  
-            return 0;                             /* simulate invalid_fp_register exception */
-         }
-         /* fall through */
-      case 2:
-         if (freg & 1)                            /* doublewords must have bit 5 zeroed */
-         {
-            *fsr |= (6 << 14);
-            return 0;
-         }
-   }
-   rs1 = (void *)&fregs[freg];
-   freg = (insn & 0x1f);
-   switch ((type >> 2) & 0x3)
-   {                                              /* same again for rs2 */
-      case 3:
-         if (freg & 3)                            /* quadwords must have bits 4&5 of the */
-         {                                        /* encoded reg. number set to zero. */
-            *fsr |= (6 << 14);                  
-            return 0;                             /* simulate invalid_fp_register exception */
-         }
-         /* fall through */
-      case 2:
-         if (freg & 1)                            /* doublewords must have bit 5 zeroed */
-         {
-            *fsr |= (6 << 14);
-            return 0;
-         }
-   }
-   rs2 = (void *)&fregs[freg];
-   freg = ((insn >> 25) & 0x1f);
-   switch ((type >> 4) & 0x3)                     /* and finally rd. This one's a bit different */
-   {
-      case 0:                                     /* dest is fcc. (this must be FCMPQ or FCMPEQ) */
-         if (freg)                                /* V8 has only one set of condition codes, so */
-         {                                        /* anything but 0 in the rd field is an error */
-            *fsr |= (6 << 14);                    /* (should probably flag as invalid opcode */
-            return 0;                             /* but SIGFPE will do :-> ) */
-         }
-         rd = (void *)(fsr);                      /* FCMPQ and FCMPEQ are special and only  */
-         break;                                   /* set bits they're supposed to :-> */
-      case 3:
-         if (freg & 3)                            /* quadwords must have bits 4&5 of the */
-         {                                        /* encoded reg. number set to zero. */
-            *fsr |= (6 << 14);
-            return 0;                             /* simulate invalid_fp_register exception */
-         }
-         /* fall through */
-      case 2:
-         if (freg & 1)                            /* doublewords must have bit 5 zeroed */
-         {
-            *fsr |= (6 << 14);
-            return 0;
-         }
-         /* fall through */
-      case 1:
-         rd = (void *)&fregs[freg];
-         break;
-   }
-#ifdef DEBUG_MATHEMU   
-   printk("executing insn...\n");
-#endif   
-   eflag = func(rd, rs2, rs1);                   /* do the Right Thing */
-   if(eflag == 0)
-	   return 1;                             /* success! */
-   return record_exception(fsr, eflag);
+	printk("In do_mathemu(), emulating %08lx\n", insn);
+#endif
+
+	if ((insn & 0xc1f80000) == 0x81a00000)	/* FPOP1 */ {
+		switch ((insn >> 5) & 0x1ff) {
+		case FSQRTQ: TYPE(3,3,1,3,1,0,0); break;
+		case FADDQ:
+		case FSUBQ:
+		case FMULQ:
+		case FDIVQ: TYPE(3,3,1,3,1,3,1); break;
+		case FDMULQ: TYPE(3,3,1,2,1,2,1); break;
+		case FQTOS: TYPE(3,1,1,3,1,0,0); break;
+		case FQTOD: TYPE(3,2,1,3,1,0,0); break;
+		case FITOQ: TYPE(3,3,1,1,0,0,0); break;
+		case FSTOQ: TYPE(3,3,1,1,1,0,0); break;
+		case FDTOQ: TYPE(3,3,1,2,1,0,0); break;
+		case FQTOI: TYPE(3,1,0,3,1,0,0); break;
+		case FSQRTS: TYPE(2,1,1,1,1,0,0); break;
+		case FSQRTD: TYPE(2,2,1,2,1,0,0); break;
+		case FADDD:
+		case FSUBD:
+		case FMULD:
+		case FDIVD: TYPE(2,2,1,2,1,2,1); break;
+		case FADDS:
+		case FSUBS:
+		case FMULS:
+		case FDIVS: TYPE(2,1,1,1,1,1,1); break;
+		case FSMULD: TYPE(2,2,1,1,1,1,1); break;
+		case FDTOS: TYPE(2,1,1,2,1,0,0); break;
+		case FSTOD: TYPE(2,2,1,1,1,0,0); break;
+		case FSTOI: TYPE(2,1,0,1,1,0,0); break;
+		case FDTOI: TYPE(2,1,0,2,1,0,0); break;
+		case FITOS: TYPE(2,1,1,1,0,0,0); break;
+		case FITOD: TYPE(2,2,1,1,0,0,0); break;
+		case FMOVS:
+		case FABSS:
+		case FNEGS: TYPE(2,1,0,1,0,0,0); break;
+		default:
+#ifdef DEBUG_MATHEMU
+			printk("unknown FPop1: %03lx\n",(insn>>5)&0x1ff);
+#endif
+		}
+	} else if ((insn & 0xc1f80000) == 0x81a80000)	/* FPOP2 */ {
+		switch ((insn >> 5) & 0x1ff) {
+		case FCMPS: TYPE(3,0,0,1,1,1,1); break;
+		case FCMPES: TYPE(3,0,0,1,1,1,1); break;
+		case FCMPD: TYPE(3,0,0,2,1,2,1); break;
+		case FCMPED: TYPE(3,0,0,2,1,2,1); break;
+		case FCMPQ: TYPE(3,0,0,3,1,3,1); break;
+		case FCMPEQ: TYPE(3,0,0,3,1,3,1); break;
+		default:
+#ifdef DEBUG_MATHEMU
+			printk("unknown FPop2: %03lx\n",(insn>>5)&0x1ff);
+#endif
+		}
+	}
+
+	if (!type) {	/* oops, didn't recognise that FPop */
+#ifdef DEBUG_MATHEMU
+		printk("attempt to emulate unrecognised FPop!\n");
+#endif
+		return 0;
+	}
+
+	/* Decode the registers to be used */
+	freg = (*pfsr >> 14) & 0xf;
+
+	*pfsr &= ~0x1c000;				/* clear the traptype bits */
+	
+	freg = ((insn >> 14) & 0x1f);
+	switch (type & 0x3) {				/* is rs1 single, double or quad? */
+	case 3:
+		if (freg & 3) {				/* quadwords must have bits 4&5 of the */
+							/* encoded reg. number set to zero. */
+			*pfsr |= (6 << 14);
+			return 0;			/* simulate invalid_fp_register exception */
+		}
+	/* fall through */
+	case 2:
+		if (freg & 1) {				/* doublewords must have bit 5 zeroed */
+			*pfsr |= (6 << 14);
+			return 0;
+		}
+	}
+	rs1 = (argp)&fregs[freg];
+	switch (type & 0x7) {
+	case 7: FP_UNPACK_QP (QA, rs1); break;
+	case 6: FP_UNPACK_DP (DA, rs1); break;
+	case 5: FP_UNPACK_SP (SA, rs1); break;
+	}
+	freg = (insn & 0x1f);
+	switch ((type >> 3) & 0x3) {			/* same again for rs2 */
+	case 3:
+		if (freg & 3) {				/* quadwords must have bits 4&5 of the */
+							/* encoded reg. number set to zero. */
+			*pfsr |= (6 << 14);
+			return 0;			/* simulate invalid_fp_register exception */
+		}
+	/* fall through */
+	case 2:
+		if (freg & 1) {				/* doublewords must have bit 5 zeroed */
+			*pfsr |= (6 << 14);
+			return 0;
+		}
+	}
+	rs2 = (argp)&fregs[freg];
+	switch ((type >> 3) & 0x7) {
+	case 7: FP_UNPACK_QP (QB, rs2); break;
+	case 6: FP_UNPACK_DP (DB, rs2); break;
+	case 5: FP_UNPACK_SP (SB, rs2); break;
+	}
+	freg = ((insn >> 25) & 0x1f);
+	switch ((type >> 6) & 0x3) {			/* and finally rd. This one's a bit different */
+	case 0:						/* dest is fcc. (this must be FCMPQ or FCMPEQ) */
+		if (freg) {				/* V8 has only one set of condition codes, so */
+							/* anything but 0 in the rd field is an error */
+			*pfsr |= (6 << 14);		/* (should probably flag as invalid opcode */
+			return 0;			/* but SIGFPE will do :-> ) */
+		}
+		break;
+	case 3:
+		if (freg & 3) {				/* quadwords must have bits 4&5 of the */
+							/* encoded reg. number set to zero. */
+			*pfsr |= (6 << 14);
+			return 0;			/* simulate invalid_fp_register exception */
+		}
+	/* fall through */
+	case 2:
+		if (freg & 1) {				/* doublewords must have bit 5 zeroed */
+			*pfsr |= (6 << 14);
+			return 0;
+		}
+	/* fall through */
+	case 1:
+		rd = (void *)&fregs[freg];
+		break;
+	}
+#ifdef DEBUG_MATHEMU
+	printk("executing insn...\n");
+#endif
+	/* do the Right Thing */
+	switch ((insn >> 5) & 0x1ff) {
+	/* + */
+	case FADDS: FP_ADD_S (SR, SA, SB); break;
+	case FADDD: FP_ADD_D (DR, DA, DB); break;
+	case FADDQ: FP_ADD_Q (QR, QA, QB); break;
+	/* - */
+	case FSUBS: FP_SUB_S (SR, SA, SB); break;
+	case FSUBD: FP_SUB_D (DR, DA, DB); break;
+	case FSUBQ: FP_SUB_Q (QR, QA, QB); break;
+	/* * */
+	case FMULS: FP_MUL_S (SR, SA, SB); break;
+	case FSMULD: FP_CONV (D, S, 2, 1, DA, SA);
+		     FP_CONV (D, S, 2, 1, DB, SB);
+	case FMULD: FP_MUL_D (DR, DA, DB); break;
+	case FDMULQ: FP_CONV (Q, D, 4, 2, QA, DA);
+		     FP_CONV (Q, D, 4, 2, QB, DB);
+	case FMULQ: FP_MUL_Q (QR, QA, QB); break;
+	/* / */
+	case FDIVS: FP_DIV_S (SR, SA, SB); break;
+	case FDIVD: FP_DIV_D (DR, DA, DB); break;
+	case FDIVQ: FP_DIV_Q (QR, QA, QB); break;
+	/* sqrt */
+	case FSQRTS: FP_SQRT_S (SR, SB); break;
+	case FSQRTD: FP_SQRT_D (DR, DB); break;
+	case FSQRTQ: FP_SQRT_Q (QR, QB); break;
+	/* mov */
+	case FMOVS: rd->s = rs2->s; break;
+	case FABSS: rd->s = rs2->s & 0x7fffffff; break;
+	case FNEGS: rd->s = rs2->s ^ 0x80000000; break;
+	/* float to int */
+	case FSTOI: FP_TO_INT_S (IR, SB, 32, 1); break;
+	case FDTOI: FP_TO_INT_D (IR, DB, 32, 1); break;
+	case FQTOI: FP_TO_INT_Q (IR, QB, 32, 1); break;
+	/* int to float */
+	case FITOS: IR = rs2->s; FP_FROM_INT_S (SR, IR, 32, int); break;
+	case FITOD: IR = rs2->s; FP_FROM_INT_D (DR, IR, 32, int); break;
+	case FITOQ: IR = rs2->s; FP_FROM_INT_Q (QR, IR, 32, int); break;
+	/* float to float */
+	case FSTOD: FP_CONV (D, S, 2, 1, DR, SB); break;
+	case FSTOQ: FP_CONV (Q, S, 4, 1, QR, SB); break;
+	case FDTOQ: FP_CONV (Q, D, 4, 2, QR, DB); break;
+	case FDTOS: FP_CONV (S, D, 1, 2, SR, DB); break;
+	case FQTOS: FP_CONV (S, Q, 1, 4, SR, QB); break;
+	case FQTOD: FP_CONV (D, Q, 2, 4, DR, QB); break;
+	/* comparison */
+	case FCMPS:
+	case FCMPES:
+		FP_CMP_S(IR, SB, SA, 3);
+		if (IR == 3 &&
+		    (((insn >> 5) & 0x1ff) == FCMPES ||
+		     FP_ISSIGNAN_S(SA) ||
+		     FP_ISSIGNAN_S(SB)))
+			FP_SET_EXCEPTION (FP_EX_INVALID);
+		break;
+	case FCMPD:
+	case FCMPED:
+		FP_CMP_D(IR, DB, DA, 3);
+		if (IR == 3 &&
+		    (((insn >> 5) & 0x1ff) == FCMPED ||
+		     FP_ISSIGNAN_D(DA) ||
+		     FP_ISSIGNAN_D(DB)))
+			FP_SET_EXCEPTION (FP_EX_INVALID);
+		break;
+	case FCMPQ:
+	case FCMPEQ:
+		FP_CMP_Q(IR, QB, QA, 3);
+		if (IR == 3 &&
+		    (((insn >> 5) & 0x1ff) == FCMPEQ ||
+		     FP_ISSIGNAN_Q(QA) ||
+		     FP_ISSIGNAN_Q(QB)))
+			FP_SET_EXCEPTION (FP_EX_INVALID);
+	}
+	if (!FP_INHIBIT_RESULTS) {
+		switch ((type >> 6) & 0x7) {
+		case 0: fsr = *pfsr;
+			if (IR == -1) IR = 2;
+			/* fcc is always fcc0 */
+			fsr &= ~0xc00; fsr |= (IR << 10); break;
+			*pfsr = fsr;
+			break;
+		case 1: rd->s = IR; break;
+		case 5: FP_PACK_SP (rd, SR); break;
+		case 6: FP_PACK_DP (rd, DR); break;
+		case 7: FP_PACK_QP (rd, QR); break;
+		}
+	}
+	if(_fex == 0)
+		return 1;				/* success! */
+	return record_exception(pfsr, _fex);
 }
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/sfp-machine.h linux-2.2.14-pre7/arch/sparc/math-emu/sfp-machine.h
--- linux-2.2.14-pre6/arch/sparc/math-emu/sfp-machine.h	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc/math-emu/sfp-machine.h	2003-08-15 15:09:03.000000000 -0700
@@ -1,6 +1,11 @@
-/* Machine-dependent software floating-point definitions.  Sparc version.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+/* Machine-dependent software floating-point definitions.
+   Sparc userland (_Q_*) version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -15,405 +20,186 @@
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-   Actually, this is a sparc (32bit) version, written based on the
-   i386 and sparc64 versions, by me, 
-   Peter Maydell (pmaydell@chiark.greenend.org.uk).
-   Comments are by and large also mine, although they may be inaccurate.
-
-   In picking out asm fragments I've gone with the lowest common
-   denominator, which also happens to be the hardware I have :->
-   That is, a SPARC without hardware multiply and divide.
- */
-
-
-/* basic word size definitions */
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
 #define _FP_W_TYPE_SIZE		32
 #define _FP_W_TYPE		unsigned long
 #define _FP_WS_TYPE		signed long
 #define _FP_I_TYPE		long
 
-/* You can optionally code some things like addition in asm. For
- * example, i386 defines __FP_FRAC_ADD_2 as asm. If you don't
- * then you get a fragment of C code [if you change an #ifdef 0
- * in op-2.h] or a call to add_ssaaaa (see below).
- * Good places to look for asm fragments to use are gcc and glibc.
- * gcc's longlong.h is useful.
- */
-
-/* We need to know how to multiply and divide. If the host word size
- * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which
- * codes the multiply with whatever gcc does to 'a * b'.
- * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm 
- * function that can multiply two 1W values and get a 2W result. 
- * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which
- * does bitshifting to avoid overflow.
- * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size
- * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or 
- * _FP_DIV_HELP_ldiv (see op-1.h).
- * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W).
- * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd
- * to do this.]
- * In general, 'n' is the number of words required to hold the type,
- * and 't' is either S, D or Q for single/double/quad.
- *           -- PMM
- */
-/* Example: SPARC64:
- * #define _FP_MUL_MEAT_S(R,X,Y)	_FP_MUL_MEAT_1_imm(S,R,X,Y)
- * #define _FP_MUL_MEAT_D(R,X,Y)	_FP_MUL_MEAT_1_wide(D,R,X,Y,umul_ppmm)
- * #define _FP_MUL_MEAT_Q(R,X,Y)	_FP_MUL_MEAT_2_wide(Q,R,X,Y,umul_ppmm)
- *
- * #define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
- * #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
- * #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv_64(Q,R,X,Y)
- *
- * Example: i386:
- * #define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(S,R,X,Y,_i386_mul_32_64)
- * #define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(D,R,X,Y,_i386_mul_32_64)
- *
- * #define _FP_DIV_MEAT_S(R,X,Y)   _FP_DIV_MEAT_1_udiv(S,R,X,Y,_i386_div_64_32)
- * #define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
- */
-#define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(D,R,X,Y,umul_ppmm)
-/* FIXME: This is not implemented, but should be soon */
-#define _FP_MUL_MEAT_Q(R,X,Y)   _FP_FRAC_SET_4(R, _FP_ZEROFRAC_4)
-#define _FP_DIV_MEAT_S(R,X,Y)   _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
-/* FIXME: This is not implemented, but should be soon */
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_FRAC_SET_4(R, _FP_ZEROFRAC_4)
-
-/* These macros define what NaN looks like. They're supposed to expand to 
- * a comma-separated set of 32bit unsigned ints that encode NaN.
- */
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
-#define _FP_NANFRAC_Q           _FP_QNANBIT_Q, 0, 0, 0
-
-/* On some architectures float-to-int conversions return a result
- * code.  On others (e.g. Sparc) they return 0
- */
-#define _FTOI_RESULT		0
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#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) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
 
-/* This macro appears to be called when both X and Y are NaNs, and 
- * has to choose one and copy it to R. i386 goes for the larger of the
- * two, sparc64 just picks Y. I don't understand this at all so I'll
- * go with sparc64 because it's shorter :->   -- PMM 
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y)				\
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
   do {								\
-    R##_s = Y##_s;						\
-    _FP_FRAC_COPY_##wc(R,Y);					\
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
     R##_c = FP_CLS_NAN;						\
   } while (0)
 
-#define _FP_CHOOSENAN_SQRT(fs, wc, R, X)			\
-  do {								\
-    	R##_s = 0;						\
-    	R##_c = FP_CLS_NAN;					\
-    	_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
-  } while (0)
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("addcc %r7,%8,%2
+	    addxcc %r5,%6,%1
+	    addx %r3,%4,%0"						\
+	   : "=r" ((USItype)(r2)),					\
+	     "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("subcc %r7,%8,%2
+	    subxcc %r5,%6,%1
+	    subx %r3,%4,%0"						\
+	   : "=r" ((USItype)(r2)),					\
+	     "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do {									\
+    /* We need to fool gcc,  as we need to pass more than 10		\
+       input/outputs.  */						\
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
+    __asm__ __volatile__ ("
+	    addcc %r8,%9,%1
+	    addxcc %r6,%7,%0
+	    addxcc %r4,%5,%%g2
+	    addx %r2,%3,%%g1"						\
+	   : "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x3)),					\
+	     "rI" ((USItype)(y3)),					\
+	     "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc", "g1", "g2");						\
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
+    r3 = _t1; r2 = _t2;							\
+  } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do {									\
+    /* We need to fool gcc,  as we need to pass more than 10		\
+       input/outputs.  */						\
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
+    __asm__ __volatile__ ("
+	    subcc %r8,%9,%1
+	    subxcc %r6,%7,%0
+	    subxcc %r4,%5,%%g2
+	    subx %r2,%3,%%g1"						\
+	   : "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x3)),					\
+	     "rI" ((USItype)(y3)),					\
+	     "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc", "g1", "g2");						\
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
+    r3 = _t1; r2 = _t2;							\
+  } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)					\
+  __asm__ ("addcc %3,%4,%3
+	    addxcc %2,%%g0,%2
+	    addxcc %1,%%g0,%1
+	    addx %0,%%g0,%0"						\
+	   : "=&r" ((USItype)(x3)),					\
+	     "=&r" ((USItype)(x2)),					\
+	     "=&r" ((USItype)(x1)),					\
+	     "=&r" ((USItype)(x0))					\
+	   : "rI" ((USItype)(i)),					\
+	     "0" ((USItype)(x3)),					\
+	     "1" ((USItype)(x2)),					\
+	     "2" ((USItype)(x1)),					\
+	     "3" ((USItype)(x0))					\
+	   : "cc")
 
-  
-#define __FP_UNPACK_DENORM(fs, wc, X)				\
-    {								\
-	_FP_I_TYPE _shift;					\
-	_FP_FRAC_CLZ_##wc(_shift, X);				\
-	_shift -= _FP_FRACXBITS_##fs;				\
-	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));		\
-	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;			\
-	X##_c = FP_CLS_NORMAL;					\
-    }
-
-#define __FP_UNPACK_RAW_1(fs, X, val)				\
-  do {								\
-    union _FP_UNION_##fs *_flo =				\
-    	(union _FP_UNION_##fs *)val;				\
-								\
-    X##_f = _flo->bits.frac;					\
-    X##_e = _flo->bits.exp;					\
-    X##_s = _flo->bits.sign;					\
-  } while (0)
-
-#define __FP_UNPACK_RAW_2(fs, X, val)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    X##_f0 = _flo->bits.frac0;				\
-    X##_f1 = _flo->bits.frac1;				\
-    X##_e  = _flo->bits.exp;				\
-    X##_s  = _flo->bits.sign;				\
-  } while (0)
-
-#define __FP_UNPACK_RAW_4(fs, X, val)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    X##_f[0] = _flo->bits.frac0;			\
-    X##_f[1] = _flo->bits.frac1;			\
-    X##_f[2] = _flo->bits.frac2;			\
-    X##_f[3] = _flo->bits.frac3;			\
-    X##_e  = _flo->bits.exp;				\
-    X##_s  = _flo->bits.sign;				\
-  } while (0)
-
-#define __FP_UNPACK_S(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_1(S,X,val);		\
-    _FP_UNPACK_CANONICAL(S,1,X);	\
-  } while (0)
-
-#define __FP_UNPACK_D(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_2(D,X,val);		\
-    _FP_UNPACK_CANONICAL(D,2,X);	\
-  } while (0)
-
-#define __FP_UNPACK_Q(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_4(Q,X,val);		\
-    _FP_UNPACK_CANONICAL(Q,4,X);	\
-  } while (0)
-
-#define __FP_PACK_RAW_1(fs, val, X)				\
-  do {								\
-    union _FP_UNION_##fs *_flo =				\
-    	(union _FP_UNION_##fs *)val;				\
-								\
-    _flo->bits.frac = X##_f;					\
-    _flo->bits.exp  = X##_e;					\
-    _flo->bits.sign = X##_s;					\
-  } while (0)
-  
-#define __FP_PACK_RAW_2(fs, val, X)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    _flo->bits.frac0 = X##_f0;				\
-    _flo->bits.frac1 = X##_f1;				\
-    _flo->bits.exp   = X##_e;				\
-    _flo->bits.sign  = X##_s;				\
-  } while (0)
-
-#define __FP_PACK_RAW_4(fs, val, X)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    _flo->bits.frac0 = X##_f[0];			\
-    _flo->bits.frac1 = X##_f[1];			\
-    _flo->bits.frac2 = X##_f[2];			\
-    _flo->bits.frac3 = X##_f[3];			\
-    _flo->bits.exp   = X##_e;				\
-    _flo->bits.sign  = X##_s;				\
-  } while (0)
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-/* We only actually write to the destination register
- * if exceptions signalled (if any) will not trap.
- */
-#ifdef __SMP__
-#define __FPU_TEM \
-	(((current->tss.fsr)>>23)&0x1f)
-#else
+#ifndef __SMP__
 extern struct task_struct *last_task_used_math;
-#define __FPU_TEM \
-	(((last_task_used_math->tss.fsr)>>23)&0x1f)
 #endif
-#define __FPU_TRAP_P(bits) \
-	((__FPU_TEM & (bits)) != 0)
-
-#define __FP_PACK_S(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(S,1,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_1(S,val,X);		\
-    __exc;					\
-})
-
-#define __FP_PACK_D(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(D,2,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_2(D,val,X);		\
-    __exc;					\
-})
-
-#define __FP_PACK_Q(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(Q,4,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_4(Q,val,X);		\
-    __exc;					\
-})
 
 /* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
 #ifdef __SMP__
 #define FP_ROUNDMODE	((current->tss.fsr >> 30) & 0x3)
 #else
 #define FP_ROUNDMODE	((last_task_used_math->tss.fsr >> 30) & 0x3)
 #endif
+#endif
 
-/* the asm fragments go here: all these are taken from glibc-2.0.5's stdlib/longlong.h */
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-/* add_ssaaaa is used in op-2.h and should be equivalent to
- * #define add_ssaaaa(sh,sl,ah,al,bh,bl) (sh = ah+bh+ (( sl = al+bl) < al))
- * add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
- * high_addend_2, low_addend_2) adds two UWtype integers, composed by
- * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
- * respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
- * (i.e. carry out) is not stored anywhere, and is lost.
- */
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-  __asm__ ("addcc %r4,%5,%1
-        addx %r2,%3,%0"                                                 \
-           : "=r" ((USItype)(sh)),                                      \
-             "=&r" ((USItype)(sl))                                      \
-           : "%rJ" ((USItype)(ah)),                                     \
-             "rI" ((USItype)(bh)),                                      \
-             "%rJ" ((USItype)(al)),                                     \
-             "rI" ((USItype)(bl))                                       \
-           : "cc")
-
-
-/* sub_ddmmss is used in op-2.h and udivmodti4.c and should be equivalent to
- * #define sub_ddmmss(sh, sl, ah, al, bh, bl) (sh = ah-bh - ((sl = al-bl) > al))
- * sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
- * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
- * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
- * LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
- * and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
- * and is lost.
- */
-
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-  __asm__ ("subcc %r4,%5,%1
-        subx %r2,%3,%0"                                                 \
-           : "=r" ((USItype)(sh)),                                      \
-             "=&r" ((USItype)(sl))                                      \
-           : "rJ" ((USItype)(ah)),                                      \
-             "rI" ((USItype)(bh)),                                      \
-             "rJ" ((USItype)(al)),                                      \
-             "rI" ((USItype)(bl))                                       \
-           : "cc")
-
-
-/* asm fragments for mul and div */	 
-/* umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
- * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
- * word product in HIGH_PROD and LOW_PROD.
- * These look ugly because the sun4/4c don't have umul/udiv/smul/sdiv in
- * hardware. 
- */
-#define umul_ppmm(w1, w0, u, v) \
-  __asm__ ("! Inlined umul_ppmm
-        wr      %%g0,%2,%%y     ! SPARC has 0-3 delay insn after a wr
-        sra     %3,31,%%g2      ! Don't move this insn
-        and     %2,%%g2,%%g2    ! Don't move this insn
-        andcc   %%g0,0,%%g1     ! Don't move this insn
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,%3,%%g1
-        mulscc  %%g1,0,%%g1
-        add     %%g1,%%g2,%0
-        rd      %%y,%1"                                                 \
-           : "=r" ((USItype)(w1)),                                      \
-             "=r" ((USItype)(w0))                                       \
-           : "%rI" ((USItype)(u)),                                      \
-             "r" ((USItype)(v))                                         \
-           : "%g1", "%g2", "cc")
-
-/* udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
- * denominator) divides a UDWtype, composed by the UWtype integers
- * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
- * in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
- * than DENOMINATOR for correct operation.  If, in addition, the most
- * significant bit of DENOMINATOR must be 1, then the pre-processor symbol
- * UDIV_NEEDS_NORMALIZATION is defined to 1.
- */
-
-#define udiv_qrnnd(q, r, n1, n0, d) \
-  __asm__ ("! Inlined udiv_qrnnd
-        mov     32,%%g1
-        subcc   %1,%2,%%g0
-1:      bcs     5f
-         addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
-        sub     %1,%2,%1        ! this kills msb of n
-        addx    %1,%1,%1        ! so this can't give carry
-        subcc   %%g1,1,%%g1
-2:      bne     1b
-         subcc  %1,%2,%%g0
-        bcs     3f
-         addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
-        b       3f
-         sub    %1,%2,%1        ! this kills msb of n
-4:      sub     %1,%2,%1
-5:      addxcc  %1,%1,%1
-        bcc     2b
-         subcc  %%g1,1,%%g1
-! Got carry from n.  Subtract next step to cancel this carry.
-        bne     4b
-         addcc  %0,%0,%0        ! shift n1n0 and a 0-bit in lsb
-        sub     %1,%2,%1
-3:      xnor    %0,0,%0
-        ! End of inline udiv_qrnnd"                                     \
-           : "=&r" ((USItype) (q)),                                     \
-             "=&r" ((USItype) (r))                                      \
-           : "r" ((USItype) (d)),                                       \
-             "1" ((USItype) (n1)),                                      \
-             "0" ((USItype) (n0)) : "%g1", "cc")
-
-#define UDIV_NEEDS_NORMALIZATION 0
+/* Exception flags. */
+#define FP_EX_INVALID		(1 << 4)
+#define FP_EX_OVERFLOW		(1 << 3)
+#define FP_EX_UNDERFLOW		(1 << 2)
+#define FP_EX_DIVZERO		(1 << 1)
+#define FP_EX_INEXACT		(1 << 0)
 
-#define abort()								\
-	return 0
+#define FP_HANDLE_EXCEPTIONS return _fex
 
-#ifdef __BIG_ENDIAN
-#define __BYTE_ORDER __BIG_ENDIAN
+#ifdef __SMP__
+#define FP_INHIBIT_RESULTS ((current->tss.fsr >> 23) & _fex)
 #else
-#define __BYTE_ORDER __LITTLE_ENDIAN
+#define FP_INHIBIT_RESULTS ((last_task_used_math->tss.fsr >> 23) & _fex)
 #endif
 
-/* Exception flags. */
-#define EFLAG_INVALID		(1 << 4)
-#define EFLAG_OVERFLOW		(1 << 3)
-#define EFLAG_UNDERFLOW		(1 << 2)
-#define EFLAG_DIVZERO		(1 << 1)
-#define EFLAG_INEXACT		(1 << 0)
+#endif
diff -urN linux-2.2.14-pre6/arch/sparc/math-emu/sfp-util.h linux-2.2.14-pre7/arch/sparc/math-emu/sfp-util.h
--- linux-2.2.14-pre6/arch/sparc/math-emu/sfp-util.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc/math-emu/sfp-util.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,115 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) 				\
+  __asm__ ("addcc %r4,%5,%1
+	addx %r2,%3,%0"							\
+	   : "=r" ((USItype)(sh)),					\
+	     "=&r" ((USItype)(sl))					\
+	   : "%rJ" ((USItype)(ah)),					\
+	     "rI" ((USItype)(bh)),					\
+	     "%rJ" ((USItype)(al)),					\
+	     "rI" ((USItype)(bl))					\
+	   : "cc")
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) 				\
+  __asm__ ("subcc %r4,%5,%1
+	subx %r2,%3,%0"							\
+	   : "=r" ((USItype)(sh)),					\
+	     "=&r" ((USItype)(sl))					\
+	   : "rJ" ((USItype)(ah)),					\
+	     "rI" ((USItype)(bh)),					\
+	     "rJ" ((USItype)(al)),					\
+	     "rI" ((USItype)(bl))					\
+	   : "cc")
+
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("! Inlined umul_ppmm
+	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr
+	sra	%3,31,%%g2	! Don't move this insn
+	and	%2,%%g2,%%g2	! Don't move this insn
+	andcc	%%g0,0,%%g1	! Don't move this insn
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,%3,%%g1
+	mulscc	%%g1,0,%%g1
+	add	%%g1,%%g2,%0
+	rd	%%y,%1"							\
+	   : "=r" ((USItype)(w1)),					\
+	     "=r" ((USItype)(w0))					\
+	   : "%rI" ((USItype)(u)),					\
+	     "r" ((USItype)(v))						\
+	   : "%g1", "%g2", "cc")
+
+/* It's quite necessary to add this much assembler for the sparc.
+   The default udiv_qrnnd (in C) is more than 10 times slower!  */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  __asm__ ("! Inlined udiv_qrnnd
+	mov	32,%%g1
+	subcc	%1,%2,%%g0
+1:	bcs	5f
+	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb
+	sub	%1,%2,%1	! this kills msb of n
+	addx	%1,%1,%1	! so this can't give carry
+	subcc	%%g1,1,%%g1
+2:	bne	1b
+	 subcc	%1,%2,%%g0
+	bcs	3f
+	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb
+	b	3f
+	 sub	%1,%2,%1	! this kills msb of n
+4:	sub	%1,%2,%1
+5:	addxcc	%1,%1,%1
+	bcc	2b
+	 subcc	%%g1,1,%%g1
+! Got carry from n.  Subtract next step to cancel this carry.
+	bne	4b
+	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb
+	sub	%1,%2,%1
+3:	xnor	%0,0,%0
+	! End of inline udiv_qrnnd"					\
+	   : "=&r" ((USItype)(q)),					\
+	     "=&r" ((USItype)(r))					\
+	   : "r" ((USItype)(d)),					\
+	     "1" ((USItype)(n1)),					\
+	     "0" ((USItype)(n0)) : "%g1", "cc")
+#define UDIV_NEEDS_NORMALIZATION 0
+
+#define abort()								\
+	return 0
+
+#ifdef __BIG_ENDIAN
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff -urN linux-2.2.14-pre6/arch/sparc64/kernel/ioctl32.c linux-2.2.14-pre7/arch/sparc64/kernel/ioctl32.c
--- linux-2.2.14-pre6/arch/sparc64/kernel/ioctl32.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/kernel/ioctl32.c	2003-08-15 15:09:03.000000000 -0700
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.62.2.7 1999/10/09 06:03:20 davem Exp $
+/* $Id: ioctl32.c,v 1.62.2.8 1999/11/16 23:59:31 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997  Jakub Jelinek  (jj@sunsite.mff.cuni.cz)
@@ -17,7 +17,6 @@
 #include <linux/if.h>
 #include <linux/malloc.h>
 #include <linux/hdreg.h>
-#include <linux/raid/md.h>
 #include <linux/kd.h>
 #include <linux/route.h>
 #include <linux/skbuff.h>
@@ -1998,23 +1997,23 @@
 	case BLKRASET:
 	
 	/* 0x09 */
-	case RAID_VERSION:
-	case GET_ARRAY_INFO:
-	case GET_DISK_INFO:
-	case CLEAR_ARRAY:
-	case ADD_NEW_DISK:
-	case HOT_REMOVE_DISK:
-	case SET_ARRAY_INFO:
-	case SET_DISK_INFO:
-	case WRITE_RAID_INFO:
-	case UNPROTECT_ARRAY:
-	case PROTECT_ARRAY:
-	case HOT_ADD_DISK:
-	case RUN_ARRAY:
-	case START_ARRAY:
-	case STOP_ARRAY:
-	case STOP_ARRAY_RO:
-	case RESTART_ARRAY_RW:
+	case /* RAID_VERSION */		_IOR (MD_MAJOR, 0x10, char[12]):
+	case /* GET_ARRAY_INFO */	_IOR (MD_MAJOR, 0x11, char[72]):
+	case /* GET_DISK_INFO */	_IOR (MD_MAJOR, 0x12, char[20]):
+	case /* CLEAR_ARRAY */		_IO (MD_MAJOR, 0x20):
+	case /* ADD_NEW_DISK */		_IOW (MD_MAJOR, 0x21, char[20]):
+	case /* HOT_REMOVE_DISK */	_IO (MD_MAJOR, 0x22):
+	case /* SET_ARRAY_INFO */	_IOW (MD_MAJOR, 0x23, char[72]):
+	case /* SET_DISK_INFO */	_IO (MD_MAJOR, 0x24):
+	case /* WRITE_RAID_INFO */	_IO (MD_MAJOR, 0x25):
+	case /* UNPROTECT_ARRAY */	_IO (MD_MAJOR, 0x26):
+	case /* PROTECT_ARRAY */	_IO (MD_MAJOR, 0x27):
+	case /* HOT_ADD_DISK */		_IO (MD_MAJOR, 0x28):
+	case /* RUN_ARRAY */		_IOW (MD_MAJOR, 0x30, char[12]):
+	case /* START_ARRAY */		_IO (MD_MAJOR, 0x31):
+	case /* STOP_ARRAY */		_IO (MD_MAJOR, 0x32):
+	case /* STOP_ARRAY_RO */	_IO (MD_MAJOR, 0x33):
+	case /* RESTART_ARRAY_RW */	_IO (MD_MAJOR, 0x34):
 
 	/* Big K */
 	case PIO_FONT:
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/double.h linux-2.2.14-pre7/arch/sparc64/math-emu/double.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/double.h	1998-04-14 17:44:21.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/double.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,129 +0,0 @@
-/*
- * Definitions for IEEE Double Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid.  Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-#define _FP_FRACTBITS_D		(2 * _FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_D		_FP_W_TYPE_SIZE
-#endif
-
-#define _FP_FRACBITS_D		53
-#define _FP_FRACXBITS_D		(_FP_FRACTBITS_D - _FP_FRACBITS_D)
-#define _FP_WFRACBITS_D		(_FP_WORKBITS + _FP_FRACBITS_D)
-#define _FP_WFRACXBITS_D	(_FP_FRACTBITS_D - _FP_WFRACBITS_D)
-#define _FP_EXPBITS_D		11
-#define _FP_EXPBIAS_D		1023
-#define _FP_EXPMAX_D		2047
-
-#define _FP_QNANBIT_D		\
-	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
-#define _FP_IMPLBIT_D		\
-	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
-#define _FP_OVERFLOW_D		\
-	((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_D
-{
-  double flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign  : 1;
-    unsigned exp   : _FP_EXPBITS_D;
-    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
-    unsigned frac0 : _FP_W_TYPE_SIZE;
-#else
-    unsigned frac0 : _FP_W_TYPE_SIZE;
-    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
-    unsigned exp   : _FP_EXPBITS_D;
-    unsigned sign  : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X)		_FP_DECL(2,X)
-#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_2(D,X,val)
-#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_2(D,val,X)
-
-#define FP_UNPACK_D(X,val)		\
-  do {					\
-    _FP_UNPACK_RAW_2(D,X,val);		\
-    _FP_UNPACK_CANONICAL(D,2,X);	\
-  } while (0)
-
-#define FP_PACK_D(val,X)		\
-  do {					\
-    _FP_PACK_CANONICAL(D,2,X);		\
-    _FP_PACK_RAW_2(D,val,X);		\
-  } while (0)
-
-#define FP_NEG_D(R,X)		_FP_NEG(D,2,R,X)
-#define FP_ADD_D(R,X,Y)		_FP_ADD(D,2,R,X,Y)
-#define FP_SUB_D(R,X,Y)		_FP_SUB(D,2,R,X,Y)
-#define FP_MUL_D(R,X,Y)		_FP_MUL(D,2,R,X,Y)
-#define FP_DIV_D(R,X,Y)		_FP_DIV(D,2,R,X,Y)
-#define FP_SQRT_D(R,X)		_FP_SQRT(D,2,R,X)
-
-#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,2,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,2,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,2,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,2,X,r,rs,rt)
-
-#else
-
-union _FP_UNION_D
-{
-  double flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign : 1;
-    unsigned exp  : _FP_EXPBITS_D;
-    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
-#else
-    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
-    unsigned exp  : _FP_EXPBITS_D;
-    unsigned sign : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X)		_FP_DECL(1,X)
-#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_1(D,X,val)
-#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_1(D,val,X)
-
-#define FP_UNPACK_D(X,val)		\
-  do {					\
-    _FP_UNPACK_RAW_1(D,X,val);		\
-    _FP_UNPACK_CANONICAL(D,1,X);	\
-  } while (0)
-
-#define FP_PACK_D(val,X)		\
-  do {					\
-    _FP_PACK_CANONICAL(D,1,X);		\
-    _FP_PACK_RAW_1(D,val,X);		\
-  } while (0)
-
-#define FP_NEG_D(R,X)		_FP_NEG(D,1,R,X)
-#define FP_ADD_D(R,X,Y)		_FP_ADD(D,1,R,X,Y)
-#define FP_SUB_D(R,X,Y)		_FP_SUB(D,1,R,X,Y)
-#define FP_MUL_D(R,X,Y)		_FP_MUL(D,1,R,X,Y)
-#define FP_DIV_D(R,X,Y)		_FP_DIV(D,1,R,X,Y)
-#define FP_SQRT_D(R,X)		_FP_SQRT(D,1,R,X)
-
-/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
-   the target machine.  */
-
-#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,1,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,1,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,1,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,1,X,r,rs,rt)
-
-#endif /* W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fabsq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fabsq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fabsq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fabsq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,6 +0,0 @@
-int FABSQ(unsigned long *rd, unsigned long *rs2)
-{
-	rd[0] = rs2[0] & 0x7fffffffffffffffUL;
-	rd[1] = rs2[1];
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/faddd.c linux-2.2.14-pre7/arch/sparc64/math-emu/faddd.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/faddd.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/faddd.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FADDD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	FP_ADD_D(R, A, B);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/faddq.c linux-2.2.14-pre7/arch/sparc64/math-emu/faddq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/faddq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/faddq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FADDQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_ADD_Q(R, A, B);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fadds.c linux-2.2.14-pre7/arch/sparc64/math-emu/fadds.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fadds.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fadds.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FADDS(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
-
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	FP_ADD_S(R, A, B);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fcmpeq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fcmpeq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fcmpeq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fcmpeq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FCMPEQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B);
-	long ret;
-	int fccno = ((long)rd) & 3;
-	unsigned long fsr;
-	
-	rd = (void *)(((long)rd)&~3);
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_CMP_Q(ret, B, A, 3);
-	if (ret == -1) ret = 2;
-	fsr = *(unsigned long *)rd;
-	switch (fccno) {
-	case 0: fsr &= ~0xc00; fsr |= (ret << 10); break;
-	case 1: fsr &= ~0x300000000UL; fsr |= (ret << 32); break;
-	case 2: fsr &= ~0xc00000000UL; fsr |= (ret << 34); break;
-	case 3: fsr &= ~0x3000000000UL; fsr |= (ret << 36); break;
-	}
-	*(unsigned long *)rd = fsr;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fcmpq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fcmpq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fcmpq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fcmpq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FCMPQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B);
-	long ret;
-	int fccno = ((long)rd) & 3;
-	unsigned long fsr;
-	
-	rd = (void *)(((long)rd)&~3);
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_CMP_Q(ret, B, A, 3);
-	if (ret == -1) ret = 2;
-	fsr = *(unsigned long *)rd;
-	switch (fccno) {
-	case 0: fsr &= ~0xc00; fsr |= (ret << 10); break;
-	case 1: fsr &= ~0x300000000UL; fsr |= (ret << 32); break;
-	case 2: fsr &= ~0xc00000000UL; fsr |= (ret << 34); break;
-	case 3: fsr &= ~0x3000000000UL; fsr |= (ret << 36); break;
-	}
-	*(unsigned long *)rd = fsr;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdivd.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdivd.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdivd.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdivd.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FDIVD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-	int ret = 0;
-
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	if(B_c == FP_CLS_ZERO &&
-	   A_c != FP_CLS_ZERO) {
-		ret |= EFLAG_DIVZERO;
-		if(__FPU_TRAP_P(EFLAG_DIVZERO))
-			return ret;
-	}
-	FP_DIV_D(R, A, B);
-	return (ret | __FP_PACK_D(rd, R));
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdivq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdivq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdivq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdivq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FDIVQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-	int ret;
-
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	if(B_c == FP_CLS_ZERO &&
-	   A_c != FP_CLS_ZERO) {
-		ret |= EFLAG_DIVZERO;
-		if(__FPU_TRAP_P(EFLAG_DIVZERO))
-			return ret;
-	}
-	FP_DIV_Q(R, A, B);
-	return (ret | __FP_PACK_Q(rd, R));
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdivs.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdivs.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdivs.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdivs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,20 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FDIVS(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
-	int ret = 0;
-
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	if(B_c == FP_CLS_ZERO &&
-	   A_c != FP_CLS_ZERO) {
-		ret |= EFLAG_DIVZERO;
-		if(__FPU_TRAP_P(EFLAG_DIVZERO))
-			return ret;
-	}
-	FP_DIV_S(R, A, B);
-	return (ret | __FP_PACK_S(rd, R));
-}
-
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdmulq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdmulq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdmulq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdmulq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FDMULQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(IN); FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-
-	__FP_UNPACK_D(IN, rs1);
-	FP_CONV(Q,D,2,1,A,IN);
-	__FP_UNPACK_D(IN, rs2);
-	FP_CONV(Q,D,2,1,B,IN);
-	FP_MUL_Q(R, A, B);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdtoi.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdtoi.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdtoi.c	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdtoi.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FDTOI(unsigned *rd, void *rs2)
-{
-	FP_DECL_D(A);
-	unsigned r;
-
-	__FP_UNPACK_D(A, rs2);
-	FP_TO_INT_D(r, A, 32, 1);
-	*rd = r;
-	return _FTOI_RESULT;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdtoq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdtoq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdtoq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdtoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FDTOQ(void *rd, void *rs2)
-{
-	FP_DECL_D(A); FP_DECL_Q(R);
-
-	__FP_UNPACK_D(A, rs2);
-	FP_CONV(Q,D,2,1,R,A);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdtos.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdtos.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdtos.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdtos.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FDTOS(void *rd, void *rs2)
-{
-	FP_DECL_D(A); FP_DECL_S(R);
-
-	__FP_UNPACK_D(A, rs2);
-	FP_CONV(S,D,1,1,R,A);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fdtox.c linux-2.2.14-pre7/arch/sparc64/math-emu/fdtox.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fdtox.c	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fdtox.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FDTOX(unsigned long *rd, void *rs2)
-{
-	FP_DECL_D(A);
-	unsigned long r;
-
-	__FP_UNPACK_D(A, rs2);
-	FP_TO_INT_D(r, A, 64, 1);
-	*rd = r;
-	return _FTOI_RESULT;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fitoq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fitoq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fitoq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fitoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FITOQ(void *rd, void *rs2)
-{
-	FP_DECL_Q(R);
-	int a = *(int *)rs2;
-
-	FP_FROM_INT_Q(R, a, 32, int);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fmovq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fmovq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fmovq.c	1998-01-12 15:15:44.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fmovq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,6 +0,0 @@
-int FMOVQ(unsigned long *rd, unsigned long *rs2)
-{
-	rd[0] = rs2[0];
-	rd[1] = rs2[1];
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fmuld.c linux-2.2.14-pre7/arch/sparc64/math-emu/fmuld.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fmuld.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fmuld.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FMULD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	FP_MUL_D(R, A, B);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fmulq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fmulq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fmulq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fmulq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FMULQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	FP_MUL_Q(R, A, B);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fmuls.c linux-2.2.14-pre7/arch/sparc64/math-emu/fmuls.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fmuls.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fmuls.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FMULS(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
-
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	FP_MUL_S(R, A, B);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fnegq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fnegq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fnegq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fnegq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,7 +0,0 @@
-int FNEGQ(unsigned long *rd, unsigned long *rs2)
-{
-	rd[0] = rs2[0] ^ 0x8000000000000000UL;
-	rd[1] = rs2[1];
-	return 0;
-}
-
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fqtod.c linux-2.2.14-pre7/arch/sparc64/math-emu/fqtod.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fqtod.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fqtod.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "double.h"
-
-int FQTOD(void *rd, void *rs2)
-{
-	FP_DECL_Q(A); FP_DECL_D(R);
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_CONV(D,Q,1,2,R,A);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fqtoi.c linux-2.2.14-pre7/arch/sparc64/math-emu/fqtoi.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fqtoi.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fqtoi.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FQTOI(unsigned *rd, void *rs2)
-{
-	FP_DECL_Q(A);
-	unsigned r;
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_TO_INT_Q(r, A, 32, 1);
-	*rd = r;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fqtos.c linux-2.2.14-pre7/arch/sparc64/math-emu/fqtos.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fqtos.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fqtos.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "single.h"
-
-int FQTOS(void *rd, void *rs2)
-{
-	FP_DECL_Q(A); FP_DECL_S(R);
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_CONV(S,Q,1,2,R,A);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fqtox.c linux-2.2.14-pre7/arch/sparc64/math-emu/fqtox.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fqtox.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fqtox.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FQTOX(unsigned long *rd, void *rs2)
-{
-	FP_DECL_Q(A);
-	unsigned long r;
-
-	__FP_UNPACK_Q(A, rs2);
-	FP_TO_INT_Q(r, A, 64, 1);
-	*rd = r;
-	return 0;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsmuld.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsmuld.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsmuld.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsmuld.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FSMULD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(IN); FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-
-	__FP_UNPACK_S(IN, rs1);
-	FP_CONV(D,S,1,1,A,IN);
-	__FP_UNPACK_S(IN, rs2);
-	FP_CONV(D,S,1,1,B,IN);
-	FP_MUL_D(R, A, B);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrtd.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrtd.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrtd.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrtd.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FSQRTD(void *rd, void *rs2)
-{
-	FP_DECL_D(A); FP_DECL_D(R);
-        
-	__FP_UNPACK_D(A, rs2);
-	FP_SQRT_D(R, A);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrtq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrtq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrtq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrtq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FSQRTQ(void *rd, void *rs2)
-{
-	FP_DECL_Q(A); FP_DECL_Q(R);
-        
-	__FP_UNPACK_Q(A, rs2);
-	FP_SQRT_Q(R, A);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrts.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrts.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsqrts.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsqrts.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FSQRTS(void *rd, void *rs2)
-{
-	FP_DECL_S(A); FP_DECL_S(R);
-        
-	__FP_UNPACK_S(A, rs2);
-	FP_SQRT_S(R, A);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fstod.c linux-2.2.14-pre7/arch/sparc64/math-emu/fstod.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fstod.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fstod.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-int FSTOD(void *rd, void *rs2)
-{
-	FP_DECL_S(A); FP_DECL_D(R);
-
-	__FP_UNPACK_S(A, rs2);
-	FP_CONV(D,S,1,1,R,A);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fstoi.c linux-2.2.14-pre7/arch/sparc64/math-emu/fstoi.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fstoi.c	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fstoi.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FSTOI(unsigned *rd, void *rs2)
-{
-	FP_DECL_S(A);
-	unsigned r;
-
-	__FP_UNPACK_S(A, rs2);
-	FP_TO_INT_S(r, A, 32, 1);
-	*rd = r;
-	return _FTOI_RESULT;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fstoq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fstoq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fstoq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fstoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,12 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-#include "single.h"
-
-int FSTOQ(void *rd, void *rs2)
-{
-	FP_DECL_S(A); FP_DECL_Q(R);
-
-	__FP_UNPACK_S(A, rs2);
-	FP_CONV(Q,S,2,1,R,A);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fstox.c linux-2.2.14-pre7/arch/sparc64/math-emu/fstox.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fstox.c	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fstox.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FSTOX(unsigned long *rd, void *rs2)
-{
-	FP_DECL_S(A);
-	unsigned long r;
-
-	__FP_UNPACK_S(A, rs2);
-	FP_TO_INT_S(r, A, 64, 1);
-	*rd = r;
-	return _FTOI_RESULT;
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsubd.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsubd.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsubd.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsubd.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,14 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-
-int FSUBD(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
-
-	__FP_UNPACK_D(A, rs1);
-	__FP_UNPACK_D(B, rs2);
-	if (B_c != FP_CLS_NAN)
-		B_s ^= 1;
-	FP_ADD_D(R, A, B);
-	return __FP_PACK_D(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsubq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsubq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsubq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsubq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,14 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FSUBQ(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
-
-	__FP_UNPACK_Q(A, rs1);
-	__FP_UNPACK_Q(B, rs2);
-	if (B_c != FP_CLS_NAN)
-		B_s ^= 1;
-	FP_ADD_Q(R, A, B);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fsubs.c linux-2.2.14-pre7/arch/sparc64/math-emu/fsubs.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fsubs.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fsubs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,14 +0,0 @@
-#include "soft-fp.h"
-#include "single.h"
-
-int FSUBS(void *rd, void *rs2, void *rs1)
-{
-	FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
-
-	__FP_UNPACK_S(A, rs1);
-	__FP_UNPACK_S(B, rs2);
-	if (B_c != FP_CLS_NAN)
-		B_s ^= 1;
-	FP_ADD_S(R, A, B);
-	return __FP_PACK_S(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/fxtoq.c linux-2.2.14-pre7/arch/sparc64/math-emu/fxtoq.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/fxtoq.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/fxtoq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-#include "soft-fp.h"
-#include "quad.h"
-
-int FXTOQ(void *rd, void *rs2)
-{
-	FP_DECL_Q(R);
-	long a = *(long *)rs2;
-
-	FP_FROM_INT_Q(R, a, 64, long);
-	return __FP_PACK_Q(rd, R);
-}
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/Makefile linux-2.2.14-pre7/arch/sparc64/math-emu/Makefile
--- linux-2.2.14-pre6/arch/sparc64/math-emu/Makefile	1998-10-27 09:52:20.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -8,12 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := math-emu.o
-O_OBJS   := math.o fabsq.o faddq.o fdivq.o fdmulq.o fitoq.o 		\
-		fmovq.o fmulq.o fnegq.o fqtoi.o fqtox.o fsubq.o		\
-		fxtoq.o fdtoq.o fstoq.o fqtos.o fqtod.o fsqrtq.o	\
-		fcmpq.o fcmpeq.o udivmodti4.o				\
-		fsqrts.o fsqrtd.o fadds.o faddd.o fsubs.o fsubd.o	\
-		fmuls.o fmuld.o fdivs.o fdivd.o fsmuld.o		\
-		fstoi.o fdtoi.o fstox.o fdtox.o fstod.o fdtos.o
+O_OBJS   := math.o
+CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/math.c linux-2.2.14-pre7/arch/sparc64/math-emu/math.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/math.c	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/math.c	2003-08-15 15:09:03.000000000 -0700
@@ -1,7 +1,7 @@
-/* $Id: math.c,v 1.7 1999/02/10 14:16:26 davem Exp $
+/* $Id: math.c,v 1.7.2.1 1999/09/20 12:05:52 jj Exp $
  * arch/sparc64/math-emu/math.c
  *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997,1999 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  *
  * Emulation routines originate from soft-fp package, which is part
@@ -15,47 +15,63 @@
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 
+#include "sfp-util.h"
 #include "soft-fp.h"
-
-#define FLOATFUNC(x) extern int x(void *,void *,void *);
-
-FLOATFUNC(FMOVQ)
-FLOATFUNC(FNEGQ)
-FLOATFUNC(FABSQ)
-FLOATFUNC(FSQRTQ)
-FLOATFUNC(FADDQ)
-FLOATFUNC(FSUBQ)
-FLOATFUNC(FMULQ)
-FLOATFUNC(FDIVQ)
-FLOATFUNC(FDMULQ)
-FLOATFUNC(FQTOX)
-FLOATFUNC(FXTOQ)
-FLOATFUNC(FQTOS)
-FLOATFUNC(FQTOD)
-FLOATFUNC(FITOQ)
-FLOATFUNC(FSTOQ)
-FLOATFUNC(FDTOQ)
-FLOATFUNC(FQTOI)
-FLOATFUNC(FCMPQ)
-FLOATFUNC(FCMPEQ)
-
-FLOATFUNC(FSQRTS)
-FLOATFUNC(FSQRTD)
-FLOATFUNC(FADDS)
-FLOATFUNC(FADDD)
-FLOATFUNC(FSUBS)
-FLOATFUNC(FSUBD)
-FLOATFUNC(FMULS)
-FLOATFUNC(FMULD)
-FLOATFUNC(FDIVS)
-FLOATFUNC(FDIVD)
-FLOATFUNC(FSMULD)
-FLOATFUNC(FSTOX)
-FLOATFUNC(FDTOX)
-FLOATFUNC(FDTOS)
-FLOATFUNC(FSTOD)
-FLOATFUNC(FSTOI)
-FLOATFUNC(FDTOI)
+#include "single.h"
+#include "double.h"
+#include "quad.h"
+
+/* QUAD - ftt == 3 */
+#define FMOVQ	0x003
+#define FNEGQ	0x007
+#define FABSQ	0x00b
+#define FSQRTQ	0x02b
+#define FADDQ	0x043
+#define FSUBQ	0x047
+#define FMULQ	0x04b
+#define FDIVQ	0x04f
+#define FDMULQ	0x06e
+#define FQTOX	0x083
+#define FXTOQ	0x08c
+#define FQTOS	0x0c7
+#define FQTOD	0x0cb
+#define FITOQ	0x0cc
+#define FSTOQ	0x0cd
+#define FDTOQ	0x0ce
+#define FQTOI	0x0d3
+/* SUBNORMAL - ftt == 2 */
+#define FSQRTS	0x029
+#define FSQRTD	0x02a
+#define FADDS	0x041
+#define FADDD	0x042
+#define FSUBS	0x045
+#define FSUBD	0x046
+#define FMULS	0x049
+#define FMULD	0x04a
+#define FDIVS	0x04d
+#define FDIVD	0x04e
+#define FSMULD	0x069
+#define FSTOX	0x081
+#define FDTOX	0x082
+#define FDTOS	0x0c6
+#define FSTOD	0x0c9
+#define FSTOI	0x0d1
+#define FDTOI	0x0d2
+/* FPOP2 */
+#define FCMPQ	0x053
+#define FCMPEQ	0x057
+#define FMOVQ0	0x003
+#define FMOVQ1	0x043
+#define FMOVQ2	0x083
+#define FMOVQ3	0x0c3
+#define FMOVQI	0x103
+#define FMOVQX	0x183
+#define FMOVQZ	0x027
+#define FMOVQLE	0x047
+#define FMOVQLZ 0x067
+#define FMOVQNZ	0x0a7
+#define FMOVQGZ	0x0c7
+#define FMOVQGE 0x0e7
 
 #define FSR_TEM_SHIFT	23UL
 #define FSR_TEM_MASK	(0x1fUL << FSR_TEM_SHIFT)
@@ -72,7 +88,7 @@
  *
  * We return 0 if a SIGFPE should be sent, 1 otherwise.
  */
-static int record_exception(struct pt_regs *regs, int eflag)
+static inline int record_exception(struct pt_regs *regs, int eflag)
 {
 	u64 fsr = current->tss.xfsr[0];
 	int would_trap;
@@ -84,46 +100,36 @@
 	if(would_trap != 0) {
 		eflag &= ((fsr & FSR_TEM_MASK) >> FSR_TEM_SHIFT);
 		if((eflag & (eflag - 1)) != 0) {
-			if(eflag & EFLAG_INVALID)
-				eflag = EFLAG_INVALID;
-			else if(eflag & EFLAG_DIVZERO)
-				eflag = EFLAG_DIVZERO;
-			else if(eflag & EFLAG_INEXACT)
-				eflag = EFLAG_INEXACT;
+			if(eflag & FP_EX_INVALID)
+				eflag = FP_EX_INVALID;
+			else if(eflag & FP_EX_OVERFLOW)
+				eflag = FP_EX_OVERFLOW;
+			else if(eflag & FP_EX_UNDERFLOW)
+				eflag = FP_EX_UNDERFLOW;
+			else if(eflag & FP_EX_DIVZERO)
+				eflag = FP_EX_DIVZERO;
+			else if(eflag & FP_EX_INEXACT)
+				eflag = FP_EX_INEXACT;
 		}
 	}
 
-	/* Set CEXC, here are the rules:
+	/* Set CEXC, here is the rule:
 	 *
-	 * 1) In general all FPU ops will set one and only one
+	 *    In general all FPU ops will set one and only one
 	 *    bit in the CEXC field, this is always the case
 	 *    when the IEEE exception trap is enabled in TEM.
-	 *
-	 * 2) As a special case, if an overflow or underflow
-	 *    is being signalled, AND the trap is not enabled
-	 *    in TEM, then the inexact field shall also be set.
 	 */
 	fsr &= ~(FSR_CEXC_MASK);
-	if(would_trap ||
-	   (eflag & (EFLAG_OVERFLOW | EFLAG_UNDERFLOW)) == 0) {
-		fsr |= ((long)eflag << FSR_CEXC_SHIFT);
-	} else {
-		fsr |= (((long)eflag << FSR_CEXC_SHIFT) |
-			(EFLAG_INEXACT << FSR_CEXC_SHIFT));
-	}
+	fsr |= ((long)eflag << FSR_CEXC_SHIFT);
 
-	/* Set the AEXC field, rules are:
+	/* Set the AEXC field, rule is:
 	 *
-	 * 1) If a trap would not be generated, the
+	 *    If a trap would not be generated, the
 	 *    CEXC just generated is OR'd into the
 	 *    existing value of AEXC.
-	 *
-	 * 2) When a trap is generated, AEXC is cleared.
 	 */
 	if(would_trap == 0)
 		fsr |= ((long)eflag << FSR_AEXC_SHIFT);
-	else
-		fsr &= ~(FSR_AEXC_MASK);
 
 	/* If trapping, indicate fault trap type IEEE. */
 	if(would_trap != 0)
@@ -142,18 +148,31 @@
 	return (would_trap ? 0 : 1);
 }
 
+typedef union {
+	u32 s;
+	u64 d;
+	u64 q[2];
+} *argp;
+
 int do_mathemu(struct pt_regs *regs, struct fpustate *f)
 {
 	unsigned long pc = regs->tpc;
 	unsigned long tstate = regs->tstate;
 	u32 insn = 0;
-	int type = 0; /* 01 is single, 10 is double, 11 is quad, 
-			 000011 is rs1, 001100 is rs2, 110000 is rd (00 in rd is fcc)
-			 111100000000 tells which ftt may that happen in */
+	int type = 0;
+	/* ftt tells which ftt it may happen in, r is rd, b is rs2 and a is rs1. The *u arg tells
+	   whether the argument should be packed/unpacked (0 - do not unpack/pack, 1 - unpack/pack)
+	   non-u args tells the size of the argument (0 - no argument, 1 - single, 2 - double, 3 - quad */
+#define TYPE(ftt, r, ru, b, bu, a, au) type = (au << 2) | (a << 0) | (bu << 5) | (b << 3) | (ru << 8) | (r << 6) | (ftt << 9)
 	int freg;
 	static u64 zero[2] = { 0L, 0L };
 	int flags;
-	int (*func)(void *,void *,void *) = NULL;
+	FP_DECL_EX;
+	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+	FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
+	FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
+	int IR;
+	long XR, xfsr;
 
 	if(tstate & TSTATE_PRIV)
 		die_if_kernel("FPQuad from kernel", regs);
@@ -163,55 +182,145 @@
 		if ((insn & 0xc1f80000) == 0x81a00000) /* FPOP1 */ {
 			switch ((insn >> 5) & 0x1ff) {
 			/* QUAD - ftt == 3 */
-			case 0x003: type = 0x33c; func = FMOVQ; break;
-			case 0x007: type = 0x33c; func = FNEGQ; break;
-			case 0x00b: type = 0x33c; func = FABSQ; break;
-			case 0x02b: type = 0x33c; func = FSQRTQ; break;
-			case 0x043: type = 0x33f; func = FADDQ; break;
-			case 0x047: type = 0x33f; func = FSUBQ; break;
-			case 0x04b: type = 0x33f; func = FMULQ; break;
-			case 0x04f: type = 0x33f; func = FDIVQ; break;
-			case 0x06e: type = 0x33a; func = FDMULQ; break;
-			case 0x083: type = 0x32c; func = FQTOX; break;
-			case 0x08c: type = 0x338; func = FXTOQ; break;
-			case 0x0c7: type = 0x31c; func = FQTOS; break;
-			case 0x0cb: type = 0x32c; func = FQTOD; break;
-			case 0x0cc: type = 0x334; func = FITOQ; break;
-			case 0x0cd: type = 0x334; func = FSTOQ; break;
-			case 0x0ce: type = 0x338; func = FDTOQ; break;
-			case 0x0d3: type = 0x31c; func = FQTOI; break;
+			case FMOVQ:
+			case FNEGQ:
+			case FABSQ: TYPE(3,3,0,3,0,0,0); break;
+			case FSQRTQ: TYPE(3,3,1,3,1,0,0); break;
+			case FADDQ:
+			case FSUBQ:
+			case FMULQ:
+			case FDIVQ: TYPE(3,3,1,3,1,3,1); break;
+			case FDMULQ: TYPE(3,3,1,2,1,2,1); break;
+			case FQTOX: TYPE(3,2,0,3,1,0,0); break;
+			case FXTOQ: TYPE(3,3,1,2,0,0,0); break;
+			case FQTOS: TYPE(3,1,1,3,1,0,0); break;
+			case FQTOD: TYPE(3,2,1,3,1,0,0); break;
+			case FITOQ: TYPE(3,3,1,1,0,0,0); break;
+			case FSTOQ: TYPE(3,3,1,1,1,0,0); break;
+			case FDTOQ: TYPE(3,3,1,2,1,0,0); break;
+			case FQTOI: TYPE(3,1,0,3,1,0,0); break;
 			/* SUBNORMAL - ftt == 2 */
-			case 0x029: type = 0x214; func = FSQRTS; break;
-			case 0x02a: type = 0x228; func = FSQRTD; break;
-			case 0x041: type = 0x215; func = FADDS; break;
-			case 0x042: type = 0x22a; func = FADDD; break;
-			case 0x045: type = 0x215; func = FSUBS; break;
-			case 0x046: type = 0x22a; func = FSUBD; break;
-			case 0x049: type = 0x215; func = FMULS; break;
-			case 0x04a: type = 0x22a; func = FMULD; break;
-			case 0x04d: type = 0x215; func = FDIVS; break;
-			case 0x04e: type = 0x22a; func = FDIVD; break;
-			case 0x069: type = 0x225; func = FSMULD; break;
-			case 0x081: type = 0x224; func = FSTOX; break;
-			case 0x082: type = 0x228; func = FDTOX; break;
-			case 0x0c6: type = 0x218; func = FDTOS; break;
-			case 0x0c9: type = 0x224; func = FSTOD; break;
-			case 0x0d1: type = 0x214; func = FSTOI; break;
-			case 0x0d2: type = 0x218; func = FDTOI; break;
+			case FSQRTS: TYPE(2,1,1,1,1,0,0); break;
+			case FSQRTD: TYPE(2,2,1,2,1,0,0); break;
+			case FADDD:
+			case FSUBD:
+			case FMULD:
+			case FDIVD: TYPE(2,2,1,2,1,2,1); break;
+			case FADDS:
+			case FSUBS:
+			case FMULS:
+			case FDIVS: TYPE(2,1,1,1,1,1,1); break;
+			case FSMULD: TYPE(2,2,1,1,1,1,1); break;
+			case FSTOX: TYPE(2,2,0,1,1,0,0); break;
+			case FDTOX: TYPE(2,2,0,2,1,0,0); break;
+			case FDTOS: TYPE(2,1,1,2,1,0,0); break;
+			case FSTOD: TYPE(2,2,1,1,1,0,0); break;
+			case FSTOI: TYPE(2,1,0,1,1,0,0); break;
+			case FDTOI: TYPE(2,1,0,2,1,0,0); break;
 			}
 		}
 		else if ((insn & 0xc1f80000) == 0x81a80000) /* FPOP2 */ {
+			IR = 2;
 			switch ((insn >> 5) & 0x1ff) {
-			case 0x053: type = 0x30f; func = FCMPQ; break;
-			case 0x057: type = 0x30f; func = FCMPEQ; break;
+			case FCMPQ: TYPE(3,0,0,3,1,3,1); break;
+			case FCMPEQ: TYPE(3,0,0,3,1,3,1); break;
+			/* Now the conditional fmovq support */
+			case FMOVQ0:
+			case FMOVQ1:
+			case FMOVQ2:
+			case FMOVQ3:
+				/* fmovq %fccX, %fY, %fZ */
+				if (!((insn >> 11) & 3))
+					XR = current->tss.xfsr[0] >> 10;
+				else
+					XR = current->tss.xfsr[0] >> (30 + ((insn >> 10) & 0x6));
+				XR &= 3;
+				IR = 0;
+				switch ((insn >> 14) & 0x7) {
+				/* case 0: IR = 0; break; */			/* Never */
+				case 1: if (XR) IR = 1; break;			/* Not Equal */
+				case 2: if (XR == 1 || XR == 2) IR = 1; break;	/* Less or Greater */
+				case 3: if (XR & 1) IR = 1; break;		/* Unordered or Less */
+				case 4: if (XR == 1) IR = 1; break;		/* Less */
+				case 5: if (XR & 2) IR = 1; break;		/* Unordered or Greater */
+				case 6: if (XR == 2) IR = 1; break;		/* Greater */
+				case 7: if (XR == 3) IR = 1; break;		/* Unordered */
+				}
+				if ((insn >> 14) & 8)
+					IR ^= 1;
+				break;
+			case FMOVQI:
+			case FMOVQX:
+				/* fmovq %[ix]cc, %fY, %fZ */
+				XR = regs->tstate >> 32;
+				if ((insn >> 5) & 0x80)
+					XR >>= 4;
+				XR &= 0xf;
+				IR = 0;
+				freg = ((XR >> 2) ^ XR) & 2;
+				switch ((insn >> 14) & 0x7) {
+				/* case 0: IR = 0; break; */			/* Never */
+				case 1: if (XR & 4) IR = 1; break;		/* Equal */
+				case 2: if ((XR & 4) || freg) IR = 1; break;	/* Less or Equal */
+				case 3: if (freg) IR = 1; break;		/* Less */
+				case 4: if (XR & 5) IR = 1; break;		/* Less or Equal Unsigned */
+				case 5: if (XR & 1) IR = 1; break;		/* Carry Set */
+				case 6: if (XR & 8) IR = 1; break;		/* Negative */
+				case 7: if (XR & 2) IR = 1; break;		/* Overflow Set */
+				}
+				if ((insn >> 14) & 8)
+					IR ^= 1;
+				break;
+			case FMOVQZ:
+			case FMOVQLE:
+			case FMOVQLZ:
+			case FMOVQNZ:
+			case FMOVQGZ:
+			case FMOVQGE:
+				freg = (insn >> 14) & 0x1f;
+				if (!freg)
+					XR = 0;
+				else if (freg < 16)
+					XR = regs->u_regs[freg];
+				else if (current->tss.flags & SPARC_FLAG_32BIT) {
+					struct reg_window32 *win32;
+					flushw_user ();
+					win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+					get_user(XR, &win32->locals[freg - 16]);
+				} else {
+					struct reg_window *win;
+					flushw_user ();
+					win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+					get_user(XR, &win->locals[freg - 16]);
+				}
+				IR = 0;
+				switch ((insn >> 10) & 3) {
+				case 1: if (!XR) IR = 1; break;			/* Register Zero */
+				case 2: if (XR <= 0) IR = 1; break;		/* Register Less Than or Equal to Zero */
+				case 3: if (XR < 0) IR = 1; break;		/* Register Less Than Zero */
+				}
+				if ((insn >> 10) & 4)
+					IR ^= 1;
+				break;
+			}
+			if (IR == 0) {
+				/* The fmov test was false. Do a nop instead */
+				current->tss.xfsr[0] &= ~(FSR_CEXC_MASK);
+				regs->tpc = regs->tnpc;
+				regs->tnpc += 4;
+				return 1;
+			} else if (IR == 1) {
+				/* Change the instruction into plain fmovq */
+				insn = (insn & 0x3e00001f) | 0x81a00060;
+				TYPE(3,3,0,3,0,0,0); 
 			}
 		}
 	}
 	if (type) {
-		void *rs1 = NULL, *rs2 = NULL, *rd = NULL;
+		argp rs1 = NULL, rs2 = NULL, rd = NULL;
 		
 		freg = (current->tss.xfsr[0] >> 14) & 0xf;
-		if (freg != (type >> 8))
+		if (freg != (type >> 9))
 			goto err;
 		current->tss.xfsr[0] &= ~0x1c000;
 		freg = ((insn >> 14) & 0x1f);
@@ -221,34 +330,43 @@
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
-		case 1: rs1 = (void *)&f->regs[freg]; 
+		case 1: rs1 = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
 			if (!(current->tss.fpsaved[0] & flags))
-				rs1 = (void *)&zero;
+				rs1 = (argp)&zero;
 			break;
 		}
+		switch (type & 0x7) {
+		case 7: FP_UNPACK_QP (QA, rs1); break;
+		case 6: FP_UNPACK_DP (DA, rs1); break;
+		case 5: FP_UNPACK_SP (SA, rs1); break;
+		}
 		freg = (insn & 0x1f);
-		switch ((type >> 2) & 0x3) {
+		switch ((type >> 3) & 0x3) {
 		case 3: if (freg & 2) {
 				current->tss.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
-		case 1: rs2 = (void *)&f->regs[freg];
+		case 1: rs2 = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
 			if (!(current->tss.fpsaved[0] & flags))
-				rs2 = (void *)&zero;
+				rs2 = (argp)&zero;
 			break;
 		}
+		switch ((type >> 3) & 0x7) {
+		case 7: FP_UNPACK_QP (QB, rs2); break;
+		case 6: FP_UNPACK_DP (DB, rs2); break;
+		case 5: FP_UNPACK_SP (SB, rs2); break;
+		}
 		freg = ((insn >> 25) & 0x1f);
-		switch ((type >> 4) & 0x3) {
-		case 0: rd = (void *)(((long)&current->tss.xfsr[0]) | (freg & 3)); break;
+		switch ((type >> 6) & 0x3) {
 		case 3: if (freg & 2) {
 				current->tss.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
-		case 1: rd = (void *)&f->regs[freg];
+		case 1: rd = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
 			if (!(current->tss.fpsaved[0] & FPRS_FEF)) {
 				current->tss.fpsaved[0] = FPRS_FEF;
@@ -263,9 +381,85 @@
 			current->tss.fpsaved[0] |= flags;
 			break;
 		}
-		flags = func(rd, rs2, rs1);
-		if(flags != 0)
-			return record_exception(regs, flags);
+		switch ((insn >> 5) & 0x1ff) {
+		/* + */
+		case FADDS: FP_ADD_S (SR, SA, SB); break;
+		case FADDD: FP_ADD_D (DR, DA, DB); break;
+		case FADDQ: FP_ADD_Q (QR, QA, QB); break;
+		/* - */
+		case FSUBS: FP_SUB_S (SR, SA, SB); break;
+		case FSUBD: FP_SUB_D (DR, DA, DB); break;
+		case FSUBQ: FP_SUB_Q (QR, QA, QB); break;
+		/* * */
+		case FMULS: FP_MUL_S (SR, SA, SB); break;
+		case FSMULD: FP_CONV (D, S, 1, 1, DA, SA);
+			     FP_CONV (D, S, 1, 1, DB, SB);
+		case FMULD: FP_MUL_D (DR, DA, DB); break;
+		case FDMULQ: FP_CONV (Q, D, 2, 1, QA, DA);
+			     FP_CONV (Q, D, 2, 1, QB, DB);
+		case FMULQ: FP_MUL_Q (QR, QA, QB); break;
+		/* / */
+		case FDIVS: FP_DIV_S (SR, SA, SB); break;
+		case FDIVD: FP_DIV_D (DR, DA, DB); break;
+		case FDIVQ: FP_DIV_Q (QR, QA, QB); break;
+		/* sqrt */
+		case FSQRTS: FP_SQRT_S (SR, SB); break;
+		case FSQRTD: FP_SQRT_D (DR, DB); break;
+		case FSQRTQ: FP_SQRT_Q (QR, QB); break;
+		/* mov */
+		case FMOVQ: rd->q[0] = rs2->q[0]; rd->q[1] = rs2->q[1]; break;
+		case FABSQ: rd->q[0] = rs2->q[0] & 0x7fffffffffffffffUL; rd->q[1] = rs2->q[1]; break;
+		case FNEGQ: rd->q[0] = rs2->q[0] ^ 0x8000000000000000UL; rd->q[1] = rs2->q[1]; break;
+		/* float to int */
+		case FSTOI: FP_TO_INT_S (IR, SB, 32, 1); break;
+		case FDTOI: FP_TO_INT_D (IR, DB, 32, 1); break;
+		case FQTOI: FP_TO_INT_Q (IR, QB, 32, 1); break;
+		case FSTOX: FP_TO_INT_S (XR, SB, 64, 1); break;
+		case FDTOX: FP_TO_INT_D (XR, DB, 64, 1); break;
+		case FQTOX: FP_TO_INT_Q (XR, QB, 64, 1); break;
+		/* int to float */
+		case FITOQ: IR = rs2->s; FP_FROM_INT_Q (QR, IR, 32, int); break;
+		case FXTOQ: XR = rs2->d; FP_FROM_INT_Q (QR, XR, 64, long); break;
+		/* float to float */
+		case FSTOD: FP_CONV (D, S, 1, 1, DR, SB); break;
+		case FSTOQ: FP_CONV (Q, S, 2, 1, QR, SB); break;
+		case FDTOQ: FP_CONV (Q, D, 2, 1, QR, DB); break;
+		case FDTOS: FP_CONV (S, D, 1, 1, SR, DB); break;
+		case FQTOS: FP_CONV (S, Q, 1, 2, SR, QB); break;
+		case FQTOD: FP_CONV (D, Q, 1, 2, DR, QB); break;
+		/* comparison */
+		case FCMPQ:
+		case FCMPEQ:
+			FP_CMP_Q(XR, QB, QA, 3);
+			if (XR == 3 &&
+			    (((insn >> 5) & 0x1ff) == FCMPEQ ||
+			     FP_ISSIGNAN_Q(QA) ||
+			     FP_ISSIGNAN_Q(QB)))
+				FP_SET_EXCEPTION (FP_EX_INVALID);
+		}
+		if (!FP_INHIBIT_RESULTS) {
+			switch ((type >> 6) & 0x7) {
+			case 0: xfsr = current->tss.xfsr[0];
+				if (XR == -1) XR = 2;
+				switch (freg & 3) {
+				/* fcc0, 1, 2, 3 */
+				case 0: xfsr &= ~0xc00; xfsr |= (XR << 10); break;
+				case 1: xfsr &= ~0x300000000UL; xfsr |= (XR << 32); break;
+				case 2: xfsr &= ~0xc00000000UL; xfsr |= (XR << 34); break;
+				case 3: xfsr &= ~0x3000000000UL; xfsr |= (XR << 36); break;
+				}
+				current->tss.xfsr[0] = xfsr;
+				break;
+			case 1: rd->s = IR; break;
+			case 2: rd->d = XR; break;
+			case 5: FP_PACK_SP (rd, SR); break;
+			case 6: FP_PACK_DP (rd, DR); break;
+			case 7: FP_PACK_QP (rd, QR); break;
+			}
+		}
+
+		if(_fex != 0)
+			return record_exception(regs, _fex);
 
 		/* Success and no exceptions detected. */
 		current->tss.xfsr[0] &= ~(FSR_CEXC_MASK);
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/op-1.h linux-2.2.14-pre7/arch/sparc64/math-emu/op-1.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/op-1.h	1998-01-12 15:15:44.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/op-1.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,245 +0,0 @@
-/*
- * Basic one-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
-#define _FP_FRAC_COPY_1(D,S)	(D##_f = S##_f)
-#define _FP_FRAC_SET_1(X,I)	(X##_f = I)
-#define _FP_FRAC_HIGH_1(X)	(X##_f)
-#define _FP_FRAC_LOW_1(X)	(X##_f)
-#define _FP_FRAC_WORD_1(X,w)	(X##_f)
-
-#define _FP_FRAC_ADDI_1(X,I)	(X##_f += I)
-#define _FP_FRAC_SLL_1(X,N)			\
-  do {						\
-    if (__builtin_constant_p(N) && (N) == 1)	\
-      X##_f += X##_f;				\
-    else					\
-      X##_f <<= (N);				\
-  } while (0)
-#define _FP_FRAC_SRL_1(X,N)	(X##_f >>= N)
-
-/* Right shift with sticky-lsb.  */
-#define _FP_FRAC_SRS_1(X,N,sz)	__FP_FRAC_SRS_1(X##_f, N, sz)
-
-#define __FP_FRAC_SRS_1(X,N,sz)						\
-   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1		\
-		     ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
-
-#define _FP_FRAC_ADD_1(R,X,Y)	(R##_f = X##_f + Y##_f)
-#define _FP_FRAC_SUB_1(R,X,Y)	(R##_f = X##_f - Y##_f)
-#define _FP_FRAC_CLZ_1(z, X)	__FP_CLZ(z, X##_f)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
-#define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
-#define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
-#define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
-#define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
-
-#define _FP_ZEROFRAC_1		0
-#define _FP_MINFRAC_1		1
-
-/*
- * Unpack the raw bits of a native fp value.  Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_1(fs, X, val)				\
-  do {								\
-    union _FP_UNION_##fs _flo; _flo.flt = (val);		\
-								\
-    X##_f = _flo.bits.frac;					\
-    X##_e = _flo.bits.exp;					\
-    X##_s = _flo.bits.sign;					\
-  } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_1(fs, val, X)				\
-  do {								\
-    union _FP_UNION_##fs _flo;					\
-								\
-    _flo.bits.frac = X##_f;					\
-    _flo.bits.exp  = X##_e;					\
-    _flo.bits.sign = X##_s;					\
-								\
-    (val) = _flo.flt;						\
-  } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
-   multiplication immediately.  */
-
-#define _FP_MUL_MEAT_1_imm(fs, R, X, Y)					\
-  do {									\
-    R##_f = X##_f * Y##_f;						\
-    /* Normalize since we know where the msb of the multiplicands	\
-       were (bit B), we know that the msb of the of the product is	\
-       at either 2B or 2B-1.  */					\
-    _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
-  } while (0)
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
-
-#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit)				\
-  do {									\
-    _FP_W_TYPE _Z_f0, _Z_f1;						\
-    doit(_Z_f1, _Z_f0, X##_f, Y##_f);					\
-    /* Normalize since we know where the msb of the multiplicands	\
-       were (bit B), we know that the msb of the of the product is	\
-       at either 2B or 2B-1.  */					\
-    _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
-    R##_f = _Z_f0;							\
-  } while (0)
-
-/* Finally, a simple widening multiply algorithm.  What fun!  */
-
-#define _FP_MUL_MEAT_1_hard(fs, R, X, Y)				\
-  do {									\
-    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;		\
-									\
-    /* split the words in half */					\
-    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);					\
-    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
-    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);					\
-    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
-									\
-    /* multiply the pieces */						\
-    _z_f0 = _xl * _yl;							\
-    _a_f0 = _xh * _yl;							\
-    _a_f1 = _xl * _yh;							\
-    _z_f1 = _xh * _yh;							\
-									\
-    /* reassemble into two full words */				\
-    if ((_a_f0 += _a_f1) < _a_f1)					\
-      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
-    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);				\
-    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);				\
-    _FP_FRAC_ADD_2(_z, _z, _a);						\
-									\
-    /* normalize */							\
-    _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs);	\
-    R##_f = _z_f0;							\
-  } while (0)
-
-
-/*
- * Division algorithms:
- */
-
-/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
-   division immediately.  Give this macro either _FP_DIV_HELP_imm for
-   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
-   choose will depend on what the compiler does with divrem4.  */
-
-#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)		\
-  do {							\
-    _FP_W_TYPE _q, _r;					\
-    X##_f <<= (X##_f < Y##_f				\
-	       ? R##_e--, _FP_WFRACBITS_##fs		\
-	       : _FP_WFRACBITS_##fs - 1);		\
-    doit(_q, _r, X##_f, Y##_f);				\
-    R##_f = _q | (_r != 0);				\
-  } while (0)
-
-/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
-   that may be useful in this situation.  This first is for a primitive
-   that requires normalization, the second for one that does not.  Look
-   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
-
-#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)				\
-  do {									\
-    _FP_W_TYPE _nh, _nl, _q, _r;					\
-									\
-    /* Normalize Y -- i.e. make the most significant bit set.  */	\
-    Y##_f <<= _FP_WFRACXBITS_##fs - 1;					\
-									\
-    /* Shift X op correspondingly high, that is, up one full word.  */	\
-    if (X##_f <= Y##_f)							\
-      {									\
-	_nl = 0;							\
-	_nh = X##_f;							\
-      }									\
-    else								\
-      {									\
-	R##_e++;							\
-	_nl = X##_f << (_FP_W_TYPE_SIZE-1);				\
-	_nh = X##_f >> 1;						\
-      }									\
-    									\
-    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);				\
-    R##_f = _q | (_r != 0);						\
-  } while (0)
-
-#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)		\
-  do {							\
-    _FP_W_TYPE _nh, _nl, _q, _r;			\
-    if (X##_f < Y##_f)					\
-      {							\
-	R##_e--;					\
-	_nl = X##_f << _FP_WFRACBITS_##fs;		\
-	_nh = X##_f >> _FP_WFRACXBITS_##fs;		\
-      }							\
-    else						\
-      {							\
-	_nl = X##_f << (_FP_WFRACBITS_##fs - 1);	\
-	_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);	\
-      }							\
-    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);		\
-    R##_f = _q | (_r != 0);				\
-  } while (0)
-  
-  
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
- 
-#define _FP_SQRT_MEAT_1(R, S, T, X, q)			\
-  do {							\
-    while (q)						\
-      {							\
-        T##_f = S##_f + q;				\
-        if (T##_f <= X##_f)				\
-          {						\
-            S##_f = T##_f + q;				\
-            X##_f -= T##_f;				\
-            R##_f += q;					\
-          }						\
-        _FP_FRAC_SLL_1(X, 1);				\
-        q >>= 1;					\
-      }							\
-  } while (0)
-
-/*
- * Assembly/disassembly for converting to/from integral types.  
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)	(r = X##_f)
-#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)	(X##_f = r)
-
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S)				\
-  do {									\
-    D##_f = S##_f;							\
-    if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs)			\
-      _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs),	\
-		     _FP_WFRACBITS_##sfs);				\
-    else								\
-      D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs;		\
-  } while (0)
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/op-2.h linux-2.2.14-pre7/arch/sparc64/math-emu/op-2.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/op-2.h	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/op-2.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,433 +0,0 @@
-/*
- * Basic two-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_2(X)	_FP_W_TYPE X##_f0, X##_f1
-#define _FP_FRAC_COPY_2(D,S)	(D##_f0 = S##_f0, D##_f1 = S##_f1)
-#define _FP_FRAC_SET_2(X,I)	__FP_FRAC_SET_2(X, I)
-#define _FP_FRAC_HIGH_2(X)	(X##_f1)
-#define _FP_FRAC_LOW_2(X)	(X##_f0)
-#define _FP_FRAC_WORD_2(X,w)	(X##_f##w)
-
-#define _FP_FRAC_SLL_2(X,N)						\
-  do {									\
-    if ((N) < _FP_W_TYPE_SIZE)						\
-      {									\
-        if (__builtin_constant_p(N) && (N) == 1) 			\
-          {								\
-            X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0);	\
-            X##_f0 += X##_f0;						\
-          }								\
-        else								\
-          {								\
-	    X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N));	\
-	    X##_f0 <<= (N);						\
-	  }								\
-      }									\
-    else								\
-      {									\
-	X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);			\
-	X##_f0 = 0;							\
-      }									\
-  } while (0)
-
-#define _FP_FRAC_SRL_2(X,N)						\
-  do {									\
-    if ((N) < _FP_W_TYPE_SIZE)						\
-      {									\
-	X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N));	\
-	X##_f1 >>= (N);							\
-      }									\
-    else								\
-      {									\
-	X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);			\
-	X##_f1 = 0;							\
-      }									\
-  } while (0)
-
-/* Right shift with sticky-lsb.  */
-#define _FP_FRAC_SRS_2(X,N,sz)						\
-  do {									\
-    if ((N) < _FP_W_TYPE_SIZE)						\
-      {									\
-	X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) |	\
-		  (__builtin_constant_p(N) && (N) == 1			\
-		   ? X##_f0 & 1						\
-		   : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0));	\
-	X##_f1 >>= (N);							\
-      }									\
-    else								\
-      {									\
-	X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |			\
-	          (((X##_f1 << (sz - (N))) | X##_f0) != 0));		\
-	X##_f1 = 0;							\
-      }									\
-  } while (0)
-
-#define _FP_FRAC_ADDI_2(X,I) \
-  __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
-
-#define _FP_FRAC_ADD_2(R,X,Y) \
-  __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_SUB_2(R,X,Y) \
-  __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_CLZ_2(R,X)	\
-  do {				\
-    if (X##_f1)			\
-      __FP_CLZ(R,X##_f1);	\
-    else 			\
-    {				\
-      __FP_CLZ(R,X##_f0);	\
-      R += _FP_W_TYPE_SIZE;	\
-    }				\
-  } while(0)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_2(X)	((_FP_WS_TYPE)X##_f1 < 0)
-#define _FP_FRAC_ZEROP_2(X)	((X##_f1 | X##_f0) == 0)
-#define _FP_FRAC_OVERP_2(fs,X)	(X##_f1 & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
-#define _FP_FRAC_GT_2(X, Y)	\
-  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
-#define _FP_FRAC_GE_2(X, Y)	\
-  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
-
-#define _FP_ZEROFRAC_2		0, 0
-#define _FP_MINFRAC_2		0, 1
-
-/*
- * Internals 
- */
-
-#define __FP_FRAC_SET_2(X,I1,I0)	(X##_f0 = I0, X##_f1 = I1)
-
-#define __FP_CLZ_2(R, xh, xl)	\
-  do {				\
-    if (xh)			\
-      __FP_CLZ(R,xl);		\
-    else 			\
-    {				\
-      __FP_CLZ(R,xl);		\
-      R += _FP_W_TYPE_SIZE;	\
-    }				\
-  } while(0)
-
-#if 0
-
-#ifndef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i) \
-  (xh += ((xl += i) < i))
-#endif
-#ifndef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
-  (rh = xh + yh + ((rl = xl + yl) < xl))
-#endif
-#ifndef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
-  (rh = xh - yh - ((rl = xl - yl) > xl))
-#endif
-
-#else
-
-#undef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i)	add_ssaaaa(xh, xl, xh, xl, 0, i)
-#undef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2			add_ssaaaa
-#undef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2			sub_ddmmss
-
-#endif
-
-/*
- * Unpack the raw bits of a native fp value.  Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_2(fs, X, val)			\
-  do {							\
-    union _FP_UNION_##fs _flo; _flo.flt = (val);	\
-							\
-    X##_f0 = _flo.bits.frac0;				\
-    X##_f1 = _flo.bits.frac1;				\
-    X##_e  = _flo.bits.exp;				\
-    X##_s  = _flo.bits.sign;				\
-  } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_2(fs, val, X)			\
-  do {							\
-    union _FP_UNION_##fs _flo;				\
-							\
-    _flo.bits.frac0 = X##_f0;				\
-    _flo.bits.frac1 = X##_f1;				\
-    _flo.bits.exp   = X##_e;				\
-    _flo.bits.sign  = X##_s;				\
-							\
-    (val) = _flo.flt;					\
-  } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
-
-#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit)				\
-  do {									\
-    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	\
-									\
-    doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
-    doit(_b_f1, _b_f0, X##_f0, Y##_f1);					\
-    doit(_c_f1, _c_f0, X##_f1, Y##_f0);					\
-    doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
-									\
-    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
-		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),	\
-		    0, _b_f1, _b_f0, 0,					\
-		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
-		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));	\
-    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
-		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),	\
-		    0, _c_f1, _c_f0, 0,					\
-		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
-		    _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));	\
-									\
-    /* Normalize since we know where the msb of the multiplicands	\
-       were (bit B), we know that the msb of the of the product is	\
-       at either 2B or 2B-1.  */					\
-    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);	\
-    R##_f0 = _FP_FRAC_WORD_4(_z,0);					\
-    R##_f1 = _FP_FRAC_WORD_4(_z,1);					\
-  } while (0)
-
-/* This next macro appears to be totally broken. Fortunately nowhere
- * seems to use it :-> The problem is that we define _z[4] but
- * then use it in _FP_FRAC_SRS_4, which will attempt to access
- * _z_f[n] which will cause an error. The fix probably involves 
- * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 
- */
-#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y)					\
-  do {									\
-    _FP_W_TYPE _x[2], _y[2], _z[4];					\
-    _x[0] = X##_f0; _x[1] = X##_f1;					\
-    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
-									\
-    mpn_mul_n(_z, _x, _y, 2);						\
-									\
-    /* Normalize since we know where the msb of the multiplicands	\
-       were (bit B), we know that the msb of the of the product is	\
-       at either 2B or 2B-1.  */					\
-    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs);	\
-    R##_f0 = _z[0];							\
-    R##_f1 = _z[1];							\
-  } while (0)
-
-
-/*
- * Division algorithms:
- * This seems to be giving me difficulties -- PMM 
- * Look, NetBSD seems to be able to comment algorithms. Can't you?
- * I've thrown printks at the problem.
- * This now appears to work, but I still don't really know why.
- * Also, I don't think the result is properly normalised...
- */
-
-#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y)				\
-  do {									\
-    extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],	\
-			       _FP_W_TYPE n1, _FP_W_TYPE n0,		\
-			       _FP_W_TYPE d1, _FP_W_TYPE d0);		\
-    _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0;		\
-    _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0;				\
-    _FP_W_TYPE _rmem[2], _qmem[2];					\
-    /* I think this check is to ensure that the result is normalised.   \
-     * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in         \
-     * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y.      \
-     * In this case we tweak things. (this is based on comments in      \
-     * the NetBSD FPU emulation code. )                                 \
-     * We know X,Y are normalised because we ensure this as part of     \
-     * the unpacking process. -- PMM                                    \
-     */									\
-    if (_FP_FRAC_GT_2(X, Y))						\
-      {									\
-/*	R##_e++; */							\
-	_n_f3 = X##_f1 >> 1;						\
-	_n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1;		\
-	_n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1);			\
-	_n_f0 = 0;							\
-      }									\
-    else								\
-      {									\
-	R##_e--;							\
-	_n_f3 = X##_f1;							\
-	_n_f2 = X##_f0;							\
-	_n_f1 = _n_f0 = 0;						\
-      }									\
-									\
-    /* Normalize, i.e. make the most significant bit of the 		\
-       denominator set.  CHANGED: - 1 to nothing -- PMM */		\
-    _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */);			\
-									\
-    /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4 	\
-       primitive snagged from libgcc2.c.  */				\
-									\
-    _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1);		\
-    _q_f1 = _qmem[0];							\
-    umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0);				\
-    _r_f1 = _rmem[0];							\
-    _r_f0 = _n_f1;							\
-    if (_FP_FRAC_GT_2(_m, _r))						\
-      {									\
-	_q_f1--;							\
-	_FP_FRAC_ADD_2(_r, _r, Y);					\
-	if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
-	  {								\
-	    _q_f1--;							\
-	    _FP_FRAC_ADD_2(_r, _r, Y);					\
-	  }								\
-      }									\
-    _FP_FRAC_SUB_2(_r, _r, _m);						\
-									\
-    _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1);		\
-    _q_f0 = _qmem[0];							\
-    umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0);				\
-    _r_f1 = _rmem[0];							\
-    _r_f0 = _n_f0;							\
-    if (_FP_FRAC_GT_2(_m, _r))						\
-      {									\
-	_q_f0--;							\
-	_FP_FRAC_ADD_2(_r, _r, Y);					\
-	if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
-	  {								\
-	    _q_f0--;							\
-	    _FP_FRAC_ADD_2(_r, _r, Y);					\
-	  }								\
-      }									\
-    _FP_FRAC_SUB_2(_r, _r, _m);						\
-									\
-    R##_f1 = _q_f1;							\
-    R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0);				\
-    /* adjust so answer is normalized again. I'm not sure what the 	\
-     * final sz param should be. In practice it's never used since      \
-     * N is 1 which is always going to be < _FP_W_TYPE_SIZE...		\
-     */									\
-    /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs);	*/			\
-  } while (0)
-
-
-#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y)					\
-  do {									\
-    _FP_W_TYPE _x[4], _y[2], _z[4];					\
-    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
-    _x[0] = _x[3] = 0;							\
-    if (_FP_FRAC_GT_2(X, Y))						\
-      {									\
-	R##_e++;							\
-	_x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) |	\
-		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
-			    (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE)));	\
-	_x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE);		\
-      }									\
-    else								\
-      {									\
-	_x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) |		\
-		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
-			    (_FP_WFRACBITS - _FP_W_TYPE_SIZE)));	\
-	_x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE);		\
-      }									\
-									\
-    (void) mpn_divrem (_z, 0, _x, 4, _y, 2);				\
-    R##_f1 = _z[1];							\
-    R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0);				\
-  } while (0)
-
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
- 
-#define _FP_SQRT_MEAT_2(R, S, T, X, q)			\
-  do {							\
-    while (q)						\
-      {							\
-        T##_f1 = S##_f1 + q;				\
-        if (T##_f1 <= X##_f1)				\
-          {						\
-            S##_f1 = T##_f1 + q;			\
-            X##_f1 -= T##_f1;				\
-            R##_f1 += q;				\
-          }						\
-        _FP_FRAC_SLL_2(X, 1);				\
-        q >>= 1;					\
-      }							\
-    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
-    while (q)						\
-      {							\
-        T##_f0 = S##_f0 + q;				\
-        T##_f1 = S##_f1;				\
-        if (T##_f1 < X##_f1 || 				\
-            (T##_f1 == X##_f1 && T##_f0 < X##_f0))	\
-          {						\
-            S##_f0 = T##_f0 + q;			\
-            if (((_FP_WS_TYPE)T##_f0) < 0 &&		\
-                ((_FP_WS_TYPE)S##_f0) >= 0)		\
-              S##_f1++;					\
-            _FP_FRAC_SUB_2(X, X, T);			\
-            R##_f0 += q;				\
-          }						\
-        _FP_FRAC_SLL_2(X, 1);				\
-        q >>= 1;					\
-      }							\
-  } while (0)
-
-
-/*
- * Assembly/disassembly for converting to/from integral types.  
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_2(r, X, rsize)	\
-  do {						\
-    if (rsize <= _FP_W_TYPE_SIZE)		\
-      r = X##_f0;				\
-    else					\
-      {						\
-	r = X##_f1;				\
-	r <<= _FP_W_TYPE_SIZE;			\
-	r += X##_f0;				\
-      }						\
-  } while (0)
-
-#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)				\
-  do {									\
-    X##_f0 = r;								\
-    X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);	\
-  } while (0)
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S)				\
-  do {									\
-    _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),	\
-		   _FP_WFRACBITS_##sfs);				\
-    D##_f = S##_f0;							\
-  } while (0)
-
-#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S)				\
-  do {									\
-    D##_f0 = S##_f;							\
-    D##_f1 = 0;								\
-    _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));	\
-  } while (0)
-
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/op-4.h linux-2.2.14-pre7/arch/sparc64/math-emu/op-4.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/op-4.h	1998-04-14 17:44:21.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/op-4.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,297 +0,0 @@
-/*
- * Basic four-word fraction declaration and manipulation.
- *
- * When adding quadword support for 32 bit machines, we need
- * to be a little careful as double multiply uses some of these
- * macros: (in op-2.h)
- * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
- * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
- * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
- * _FP_FRAC_DECL_4: it appears to be broken and is not used 
- * anywhere anyway. )
- *
- * I've now fixed all the macros that were here from the sparc64 code.
- * [*none* of the shift macros were correct!] -- PMM 02/1998
- * 
- * The only quadword stuff that remains to be coded is: 
- * 1) the conversion to/from ints, which requires 
- * that we check (in op-common.h) that the following do the right thing
- * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
- * 2) multiply, divide and sqrt, which require:
- * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q),
- * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to
- * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h.
- * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for
- * these; they are used nowhere else. ]
- */
-
-#define _FP_FRAC_DECL_4(X)	_FP_W_TYPE X##_f[4]
-#define _FP_FRAC_COPY_4(D,S)			\
-  (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1],	\
-   D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
-/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
- * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
- * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
- * which just assigns the In values to the array X##_f[]. 
- * This is why the number of parameters doesn't appear to match
- * at first glance...      -- PMM 
- */
-#define _FP_FRAC_SET_4(X,I)	__FP_FRAC_SET_4(X, I)
-#define _FP_FRAC_HIGH_4(X)	(X##_f[3])
-#define _FP_FRAC_LOW_4(X)	(X##_f[0])
-#define _FP_FRAC_WORD_4(X,w)	(X##_f[w])
-
-#define _FP_FRAC_SLL_4(X,N)						\
-  do {									\
-    _FP_I_TYPE _up, _down, _skip, _i;					\
-    _skip = (N) / _FP_W_TYPE_SIZE;					\
-    _up = (N) % _FP_W_TYPE_SIZE;					\
-    _down = _FP_W_TYPE_SIZE - _up;					\
-    for (_i = 3; _i > _skip; --_i)					\
-      X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down;	\
-/* bugfixed: was X##_f[_i] <<= _up;  -- PMM 02/1998 */                  \
-    X##_f[_i] = X##_f[0] << _up; 	                                \
-    for (--_i; _i >= 0; --_i)						\
-      X##_f[_i] = 0;							\
-  } while (0)
-
-/* This one was broken too */
-#define _FP_FRAC_SRL_4(X,N)						\
-  do {									\
-    _FP_I_TYPE _up, _down, _skip, _i;					\
-    _skip = (N) / _FP_W_TYPE_SIZE;					\
-    _down = (N) % _FP_W_TYPE_SIZE;					\
-    _up = _FP_W_TYPE_SIZE - _down;					\
-    for (_i = 0; _i < 3-_skip; ++_i)					\
-      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up;	\
-    X##_f[_i] = X##_f[3] >> _down;			         	\
-    for (++_i; _i < 4; ++_i)						\
-      X##_f[_i] = 0;							\
-  } while (0)
-
-
-/* Right shift with sticky-lsb. 
- * What this actually means is that we do a standard right-shift,
- * but that if any of the bits that fall off the right hand side
- * were one then we always set the LSbit.
- */
-#define _FP_FRAC_SRS_4(X,N,size)					\
-  do {									\
-    _FP_I_TYPE _up, _down, _skip, _i;					\
-    _FP_W_TYPE _s;							\
-    _skip = (N) / _FP_W_TYPE_SIZE;					\
-    _down = (N) % _FP_W_TYPE_SIZE;					\
-    _up = _FP_W_TYPE_SIZE - _down;					\
-    for (_s = _i = 0; _i < _skip; ++_i)					\
-      _s |= X##_f[_i];							\
-    _s |= X##_f[_i] << _up;						\
-/* s is now != 0 if we want to set the LSbit */                         \
-    for (_i = 0; _i < 3-_skip; ++_i)					\
-      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up;	\
-    X##_f[_i] = X##_f[3] >> _down;					\
-    for (++_i; _i < 4; ++_i)						\
-      X##_f[_i] = 0;							\
-    /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
-    X##_f[0] |= (_s != 0);                                              \
-  } while (0)
-
-#define _FP_FRAC_ADD_4(R,X,Y)						\
-  __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
-		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
-		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_SUB_4(R,X,Y)                                           \
-  __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
-		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
-		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_ADDI_4(X,I)                                            \
-  __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
-
-#define _FP_ZEROFRAC_4  0,0,0,0
-#define _FP_MINFRAC_4   0,0,0,1
-
-#define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
-#define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
-#define _FP_FRAC_OVERP_4(fs,X)  (X##_f[0] & _FP_OVERFLOW_##fs)
-
-#define _FP_FRAC_EQ_4(X,Y)                              \
- (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]          \
-  && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
-
-#define _FP_FRAC_GT_4(X,Y)                              \
- (X##_f[3] > Y##_f[3] ||                                \
-  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
-   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
-    (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0])       \
-   ))                                                   \
-  ))                                                    \
- )
-
-#define _FP_FRAC_GE_4(X,Y)                              \
- (X##_f[3] > Y##_f[3] ||                                \
-  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
-   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
-    (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0])      \
-   ))                                                   \
-  ))                                                    \
- )
-
-
-#define _FP_FRAC_CLZ_4(R,X)             \
-  do {                                  \
-    if (X##_f[3])                       \
-    {                                   \
-        __FP_CLZ(R,X##_f[3]);           \
-    }                                   \
-    else if (X##_f[2])                  \
-    {                                   \
-        __FP_CLZ(R,X##_f[2]);           \
-        R += _FP_W_TYPE_SIZE;           \
-    }                                   \
-    else if (X##_f[1])                  \
-    {                                   \
-        __FP_CLZ(R,X##_f[2]);           \
-        R += _FP_W_TYPE_SIZE*2;         \
-    }                                   \
-    else                                \
-    {                                   \
-        __FP_CLZ(R,X##_f[0]);           \
-        R += _FP_W_TYPE_SIZE*3;         \
-    }                                   \
-  } while(0)
-
-
-#define _FP_UNPACK_RAW_4(fs, X, val)                            \
-  do {                                                          \
-    union _FP_UNION_##fs _flo; _flo.flt = (val);        	\
-    X##_f[0] = _flo.bits.frac0;                                 \
-    X##_f[1] = _flo.bits.frac1;                                 \
-    X##_f[2] = _flo.bits.frac2;                                 \
-    X##_f[3] = _flo.bits.frac3;                                 \
-    X##_e  = _flo.bits.exp;                                     \
-    X##_s  = _flo.bits.sign;                                    \
-  } while (0)
-
-#define _FP_PACK_RAW_4(fs, val, X)                              \
-  do {                                                          \
-    union _FP_UNION_##fs _flo;					\
-    _flo.bits.frac0 = X##_f[0];                                 \
-    _flo.bits.frac1 = X##_f[1];                                 \
-    _flo.bits.frac2 = X##_f[2];                                 \
-    _flo.bits.frac3 = X##_f[3];                                 \
-    _flo.bits.exp   = X##_e;                                    \
-    _flo.bits.sign  = X##_s;                                    \
-    (val) = _flo.flt;                                   	\
-  } while (0)
-
-
-/*
- * Internals 
- */
-
-#define __FP_FRAC_SET_4(X,I3,I2,I1,I0)					\
-  (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
-
-#ifndef __FP_FRAC_ADD_4
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
-  (r0 = x0 + y0,							\
-   r1 = x1 + y1 + (r0 < x0),						\
-   r2 = x2 + y2 + (r1 < x1),						\
-   r3 = x3 + y3 + (r2 < x2))
-#endif
-
-#ifndef __FP_FRAC_SUB_4
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
-  (r0 = x0 - y0,                                                        \
-   r1 = x1 - y1 - (r0 > x0),                                            \
-   r2 = x2 - y2 - (r1 > x1),                                            \
-   r3 = x3 - y3 - (r2 > x2))
-#endif
-
-#ifndef __FP_FRAC_ADDI_4
-/* I always wanted to be a lisp programmer :-> */
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                 \
-  (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2)))
-#endif
-
-/* Convert FP values between word sizes. This appears to be more
- * complicated than I'd have expected it to be, so these might be
- * wrong... These macros are in any case somewhat bogus because they
- * use information about what various FRAC_n variables look like 
- * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
- * the ones in op-2.h and op-1.h. 
- */
-#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
-                        _FP_WFRACBITS_##sfs);                           \
-     D##_f = S##_f[0];                                                   \
-  } while (0)
-
-#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
-                        _FP_WFRACBITS_##sfs);                           \
-     D##_f0 = S##_f[0];                                                  \
-     D##_f1 = S##_f[1];                                                  \
-  } while (0)
-
-/* Assembly/disassembly for converting to/from integral types.  
- * No shifting or overflow handled here.
- */
-/* Put the FP value X into r, which is an integer of size rsize. */
-#define _FP_FRAC_ASSEMBLE_4(r, X, rsize)                                \
-  do {                                                                  \
-    if (rsize <= _FP_W_TYPE_SIZE)                                       \
-      r = X##_f[0];                                                     \
-    else if (rsize <= 2*_FP_W_TYPE_SIZE)                                \
-    {                                                                   \
-      r = X##_f[1];                                                     \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[0];                                                    \
-    }                                                                   \
-    else                                                                \
-    {                                                                   \
-      /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
-      /* and int == 4words as a single case.                         */ \
-      r = X##_f[3];                                                     \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[2];                                                    \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[1];                                                    \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[0];                                                    \
-    }                                                                   \
-  } while (0)
-
-/* "No disassemble Number Five!" */
-/* move an integer of size rsize into X's fractional part. We rely on
- * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
- * having to mask the values we store into it.
- */
-#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize)                             \
-  do {                                                                  \
-    X##_f[0] = r;                                                       \
-    X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);   \
-    X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
-    X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
-  } while (0);
-
-#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     D##_f[0] = S##_f;                                                  \
-     D##_f[1] = D##_f[2] = D##_f[3] = 0;                                \
-     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
-   } while (0)
-
-#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     D##_f[0] = S##_f0;                                                 \
-     D##_f[1] = S##_f1;                                                 \
-     D##_f[2] = D##_f[3] = 0;                                           \
-     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
-   } while (0)
-
-/* FIXME! This has to be written */
-#define _FP_SQRT_MEAT_4(R, S, T, X, q)
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/op-common.h linux-2.2.14-pre7/arch/sparc64/math-emu/op-common.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/op-common.h	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/op-common.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,726 +0,0 @@
-#define _FP_DECL(wc, X)			\
-  _FP_I_TYPE X##_c, X##_s, X##_e, X##_r=0;	\
-  _FP_FRAC_DECL_##wc(X)
-
-/*
- * Finish truely unpacking a native fp value by classifying the kind
- * of fp value and normalizing both the exponent and the fraction.
- */
-
-#ifndef _FP_UNPACK_CANONICAL
-#define _FP_UNPACK_CANONICAL(fs, wc, X)					\
-do {									\
-  switch (X##_e)							\
-  {									\
-  default:								\
-    _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs;				\
-    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
-    X##_e -= _FP_EXPBIAS_##fs;						\
-    X##_c = FP_CLS_NORMAL;						\
-    break;								\
-									\
-  case 0:								\
-    if (_FP_FRAC_ZEROP_##wc(X))						\
-      X##_c = FP_CLS_ZERO;						\
-    else								\
-      /* A denormalized number.  */					\
-      __FP_UNPACK_DENORM(fs, wc, X);					\
-    break;								\
-									\
-  case _FP_EXPMAX_##fs:							\
-    if (_FP_FRAC_ZEROP_##wc(X))						\
-      X##_c = FP_CLS_INF;						\
-    else								\
-      /* We don't differentiate between signaling and quiet nans.  */	\
-      X##_c = FP_CLS_NAN;						\
-    break;								\
-  }									\
-} while (0)
-#endif /* _FP_UNPACK_CANONICAL */
-
-
-/*
- * Before packing the bits back into the native fp result, take care
- * of such mundane things as rounding and overflow.  Also, for some
- * kinds of fp values, the original parts may not have been fully
- * extracted -- but that is ok, we can regenerate them now.
- */
-
-#ifndef _FP_PACK_CANONICAL
-#define _FP_PACK_CANONICAL(fs, wc, X)				\
-({int __pk__ret = X##_r;					\
-  switch (X##_c)						\
-  {								\
-  case FP_CLS_NORMAL:						\
-    X##_e += _FP_EXPBIAS_##fs;					\
-    if (X##_e > 0)						\
-      {								\
-	__pk__ret |= _FP_ROUND(wc, X);				\
-	if (_FP_FRAC_OVERP_##wc(fs, X))				\
-	  {							\
-	    _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));		\
-	    X##_e++;						\
-	  }							\
-	else							\
-	  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
-	if (X##_e >= _FP_EXPMAX_##fs)				\
-	  {							\
-	    /* overflow to infinity */				\
-	    X##_e = _FP_EXPMAX_##fs;				\
-	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
-            __pk__ret |= EFLAG_OVERFLOW;			\
-	  }							\
-      }								\
-    else							\
-      {								\
-	/* we've got a denormalized number */			\
-	X##_e = -X##_e + 1;					\
-	if (X##_e <= _FP_WFRACBITS_##fs)			\
-	  {							\
-	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
-	    __pk__ret |= _FP_ROUND(wc, X);			\
-	    _FP_FRAC_SLL_##wc(X, 1);				\
-	    if (_FP_FRAC_OVERP_##wc(fs, X))			\
-	      {							\
-	        X##_e = 1;					\
-	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
-	      }							\
-	    else						\
-	      {							\
-		X##_e = 0;					\
-		_FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1);		\
-                __pk__ret |= EFLAG_UNDERFLOW;			\
-	      }							\
-	  }							\
-	else							\
-	  {							\
-	    /* underflow to zero */				\
-	    X##_e = 0;						\
-	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
-            __pk__ret |= EFLAG_UNDERFLOW;			\
-	  }							\
-      }								\
-    break;							\
-								\
-  case FP_CLS_ZERO:						\
-    X##_e = 0;							\
-    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
-    break;							\
-								\
-  case FP_CLS_INF:						\
-    X##_e = _FP_EXPMAX_##fs;					\
-    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
-    break;							\
-								\
-  case FP_CLS_NAN:						\
-    X##_e = _FP_EXPMAX_##fs;					\
-    if (!_FP_KEEPNANFRACP)					\
-      {								\
-	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
-	X##_s = 0;						\
-      }								\
-    else							\
-      _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs;		\
-    break;							\
-  }								\
-  __pk__ret;							\
-})
-#endif /* _FP_PACK_CANONICAL */
-
-/*
- * Main addition routine.  The input values should be cooked.
- */
-#ifndef _FP_ADD
-#define _FP_ADD(fs, wc, R, X, Y)					     \
-do {									     \
-  /* Propagate any flags that may have been set during unpacking */	     \
-  R##_r |= (X##_r | Y##_r);						     \
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))				     \
-  {									     \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):			     \
-    {									     \
-      /* shift the smaller number so that its exponent matches the larger */ \
-      _FP_I_TYPE diff = X##_e - Y##_e;					     \
-									     \
-      if (diff < 0)							     \
-	{								     \
-	  diff = -diff;							     \
-	  if (diff <= _FP_WFRACBITS_##fs)				     \
-	    _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);		     \
-	  else if (!_FP_FRAC_ZEROP_##wc(X)) {				     \
-	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			     \
-	    R_r |= EFLAG_INEXACT;					     \
-	  }								     \
-	  else								     \
-	    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			     \
-	  R##_e = Y##_e;						     \
-	}								     \
-      else								     \
-	{								     \
-	  if (diff > 0)							     \
-	    {								     \
-	      if (diff <= _FP_WFRACBITS_##fs)				     \
-	        _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);		     \
-	      else if (!_FP_FRAC_ZEROP_##wc(Y))	{			     \
-	        _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			     \
-	         R_r |= EFLAG_INEXACT;					     \
-	      }								     \
-	      else							     \
-	        _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc);		     \
-	    }								     \
-	  R##_e = X##_e;						     \
-	}								     \
-									     \
-      R##_c = FP_CLS_NORMAL;						     \
-									     \
-      if (X##_s == Y##_s)						     \
-	{								     \
-	  R##_s = X##_s;						     \
-	  _FP_FRAC_ADD_##wc(R, X, Y);					     \
-	  if (_FP_FRAC_OVERP_##wc(fs, R))				     \
-	    {								     \
-	      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);		     \
-	      R##_e++;							     \
-	    }								     \
-	}								     \
-      else								     \
-	{								     \
-	  R##_s = X##_s;						     \
-	  _FP_FRAC_SUB_##wc(R, X, Y);					     \
-	  if (_FP_FRAC_ZEROP_##wc(R))					     \
-	    {								     \
-	      /* return an exact zero */				     \
-	      if (FP_ROUNDMODE == FP_RND_MINF)				     \
-		R##_s |= Y##_s;						     \
-	      else							     \
-		R##_s &= Y##_s;						     \
-	      R##_c = FP_CLS_ZERO;					     \
-	    }								     \
-	  else								     \
-	    {								     \
-	      if (_FP_FRAC_NEGP_##wc(R))				     \
-		{							     \
-		  _FP_FRAC_SUB_##wc(R, Y, X);				     \
-		  R##_s = Y##_s;					     \
-		}							     \
-									     \
-	      /* renormalize after subtraction */			     \
-	      _FP_FRAC_CLZ_##wc(diff, R);				     \
-	      diff -= _FP_WFRACXBITS_##fs;				     \
-	      if (diff)							     \
-		{							     \
-		  R##_e -= diff;					     \
-		  _FP_FRAC_SLL_##wc(R, diff);				     \
-		}							     \
-	    }								     \
-	}								     \
-      break;								     \
-    }									     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):				     \
-    _FP_CHOOSENAN(fs, wc, R, X, Y);					     \
-    break;								     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):			     \
-    R##_e = X##_e;							     \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):			     \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):				     \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):				     \
-    _FP_FRAC_COPY_##wc(R, X);						     \
-    R##_s = X##_s;							     \
-    R##_c = X##_c;							     \
-    break;								     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):			     \
-    R##_e = Y##_e;							     \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):			     \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):				     \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):				     \
-    _FP_FRAC_COPY_##wc(R, Y);						     \
-    R##_s = Y##_s;							     \
-    R##_c = Y##_c;							     \
-    break;								     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):				     \
-    if (X##_s != Y##_s)							     \
-      {									     \
-	/* +INF + -INF => NAN */					     \
-	_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);				     \
-	R##_s = X##_s ^ Y##_s;						     \
-	R##_c = FP_CLS_NAN;						     \
-	R##_r |= EFLAG_INVALID;						     \
-	break;								     \
-      }									     \
-    /* FALLTHRU */							     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):			     \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):				     \
-    R##_s = X##_s;							     \
-    R##_c = FP_CLS_INF;							     \
-    break;								     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):			     \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):				     \
-    R##_s = Y##_s;							     \
-    R##_c = FP_CLS_INF;							     \
-    break;								     \
-									     \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):			     \
-    /* make sure the sign is correct */					     \
-    if (FP_ROUNDMODE == FP_RND_MINF)					     \
-      R##_s = X##_s | Y##_s;						     \
-    else								     \
-      R##_s = X##_s & Y##_s;						     \
-    R##_c = FP_CLS_ZERO;						     \
-    break;								     \
-									     \
-  default:								     \
-    abort();								     \
-  }									     \
-} while (0)
-#endif /* _FP_ADD */
-
-
-/*
- * Main negation routine.  FIXME -- when we care about setting exception
- * bits reliably, this will not do.  We should examine all of the fp classes.
- */
-#ifndef _FP_NEG
-#define _FP_NEG(fs, wc, R, X)		\
-  do {					\
-    R##_r |= X##_r;			\
-    _FP_FRAC_COPY_##wc(R, X);		\
-    R##_c = X##_c;			\
-    R##_e = X##_e;			\
-    R##_s = 1 ^ X##_s;			\
-  } while (0)
-#endif /* _FP_NEG */
-
-
-/*
- * Main multiplication routine.  The input values should be cooked.
- */
-#ifndef _FP_MUL
-#define _FP_MUL(fs, wc, R, X, Y)			\
-do {							\
-  /* Propagate any flags that may have been set during unpacking */	     \
-  R##_r |= (X##_r | Y##_r);						     \
-  R##_s = X##_s ^ Y##_s;				\
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
-  {							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
-    R##_c = FP_CLS_NORMAL;				\
-    R##_e = X##_e + Y##_e + 1;				\
-							\
-    _FP_MUL_MEAT_##fs(R,X,Y);				\
-							\
-    if (_FP_FRAC_OVERP_##wc(fs, R))			\
-      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
-    else						\
-      R##_e--;						\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
-    _FP_CHOOSENAN(fs, wc, R, X, Y);			\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
-    R##_s = X##_s;					\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
-    _FP_FRAC_COPY_##wc(R, X);				\
-    R##_c = X##_c;					\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
-    R##_s = Y##_s;					\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
-    _FP_FRAC_COPY_##wc(R, Y);				\
-    R##_c = Y##_c;					\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
-    R##_c = FP_CLS_NAN;					\
-    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
-    break;						\
-							\
-  default:						\
-    abort();						\
-  }							\
-} while (0)
-#endif /* _FP_MUL */
-
-
-/*
- * Main division routine.  The input values should be cooked.
- */
-#ifndef _FP_DIV
-#define _FP_DIV(fs, wc, R, X, Y)			\
-do {							\
-  /* Propagate any flags that may have been set during unpacking */	     \
-  R##_r |= (X##_r | Y##_r);						     \
-  R##_s = X##_s ^ Y##_s;				\
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
-  {							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
-    R##_c = FP_CLS_NORMAL;				\
-    R##_e = X##_e - Y##_e;				\
-							\
-    _FP_DIV_MEAT_##fs(R,X,Y);				\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
-    _FP_CHOOSENAN(fs, wc, R, X, Y);			\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
-    R##_s = X##_s;					\
-    _FP_FRAC_COPY_##wc(R, X);				\
-    R##_c = X##_c;					\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
-    R##_s = Y##_s;					\
-    _FP_FRAC_COPY_##wc(R, Y);				\
-    R##_c = Y##_c;					\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
-    R##_c = FP_CLS_ZERO;				\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
-    R##_c = FP_CLS_INF;					\
-    break;						\
-							\
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
-    R##_c = FP_CLS_NAN;					\
-    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
-    break;						\
-							\
-  default:						\
-    abort();						\
-  }							\
-} while (0)
-#endif _FP_DIV
-
-
-/*
- * Main differential comparison routine.  The inputs should be raw not
- * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
- */
-#ifndef _FP_CMP
-#define _FP_CMP(fs, wc, ret, X, Y, un)					\
-  do {									\
-    /* NANs are unordered */						\
-    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
-	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
-      {									\
-	ret = un;							\
-      }									\
-    /* Deal with infinities */						\
-    else if (X##_c == FP_CLS_INF) {					\
-	if(Y##_c == FP_CLS_INF) {					\
-	    ret = Y##_s - X##_s;					\
-	}								\
-	else {								\
-	    ret = X##_s ? -1 : 1; 					\
-	}								\
-    }									\
-    else if(Y##_c == FP_CLS_INF) {					\
-	ret = Y##_s ? 1 : -1;						\
-    }									\
-    else								\
-      {									\
-	int __is_zero_x;						\
-	int __is_zero_y;						\
-									\
-	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
-	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
-									\
-	if (__is_zero_x && __is_zero_y)					\
-		ret = 0;						\
-	else if (__is_zero_x)						\
-		ret = Y##_s ? 1 : -1;					\
-	else if (__is_zero_y)						\
-		ret = X##_s ? -1 : 1;					\
-	else if (X##_s != Y##_s)					\
-	  ret = X##_s ? -1 : 1;						\
-	else if (X##_e > Y##_e)						\
-	  ret = X##_s ? -1 : 1;						\
-	else if (X##_e < Y##_e)						\
-	  ret = X##_s ? 1 : -1;						\
-	else if (_FP_FRAC_GT_##wc(X, Y))				\
-	  ret = X##_s ? -1 : 1;						\
-	else if (_FP_FRAC_GT_##wc(Y, X))				\
-	  ret = X##_s ? 1 : -1;						\
-	else								\
-	  ret = 0;							\
-      }									\
-  } while (0)
-#endif /* _FP_CMP */
-
-
-/* Simplification for strict equality.  */
-
-#ifndef _FP_CMP_EQ
-#define _FP_CMP_EQ(fs, wc, ret, X, Y)					  \
-  do {									  \
-    /* NANs are unordered */						  \
-    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		  \
-	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	  \
-      {									  \
-	ret = 1;							  \
-      }									  \
-    else								  \
-      {									  \
-	ret = !(X##_e == Y##_e						  \
-		&& _FP_FRAC_EQ_##wc(X, Y)				  \
-		&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
-      }									  \
-  } while (0)
-#endif /* _FP_CMP_EQ */
-
-/*
- * Main square root routine.  The input value should be cooked.
- */
-#ifndef _FP_SQRT
-#define _FP_SQRT(fs, wc, R, X)						\
-do {									\
-    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
-    _FP_W_TYPE q;							\
-    R##_r |= X##_r;							\
-    switch (X##_c)							\
-    {									\
-    case FP_CLS_NAN:							\
-        _FP_CHOOSENAN_SQRT(fs, wc, R, X);			        \
-    	break;								\
-    case FP_CLS_INF:							\
-    	if (X##_s)							\
-    	  {								\
-    	    R##_s = 0;							\
-	    R##_c = FP_CLS_NAN; /* sNAN */				\
-    	  }								\
-    	else								\
-    	  {								\
-    	    R##_s = 0;							\
-    	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
-    	  }								\
-    	break;								\
-    case FP_CLS_ZERO:							\
-	R##_s = X##_s;							\
-    	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
-	break;								\
-    case FP_CLS_NORMAL:							\
-    	R##_s = 0;							\
-        if (X##_s)							\
-          {								\
-	    R##_c = FP_CLS_NAN; /* sNAN */				\
-	    break;							\
-          }								\
-    	R##_c = FP_CLS_NORMAL;						\
-        if (X##_e & 1)							\
-          _FP_FRAC_SLL_##wc(X, 1);					\
-        R##_e = X##_e >> 1;						\
-        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
-        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
-        q = _FP_OVERFLOW_##fs;						\
-        _FP_FRAC_SLL_##wc(X, 1);					\
-        _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
-        _FP_FRAC_SRL_##wc(R, 1);					\
-    }									\
-  } while (0)
-#endif /* FP_SQRT */
-
-/*
- * Convert from FP to integer
- */
-
-/* "When a NaN, infinity, large positive argument >= 2147483648.0, or 
- * large negative argument <= -2147483649.0 is converted to an integer,
- * the invalid_current bit...should be set and fp_exception_IEEE_754 should
- * be raised. If the floating point invalid trap is disabled, no trap occurs
- * and a numerical result is generated: if the sign bit of the operand
- * is 0, the result is 2147483647; if the sign bit of the operand is 1,
- * the result is -2147483648."
- * Similarly for conversion to extended ints, except that the boundaries
- * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
- * -2^63 for s=1.
- * -- SPARC Architecture Manual V9, Appendix B, which specifies how
- * SPARCs resolve implementation dependencies in the IEEE-754 spec.
- * I don't believe that the code below follows this. I'm not even sure
- * it's right! 
- * It doesn't cope with needing to convert to an n bit integer when there
- * is no n bit integer type. Fortunately gcc provides long long so this
- * isn't a problem for sparc32.
- * I have, however, fixed its NaN handling to conform as above.
- *         -- PMM 02/1998
- * NB: rsigned is not 'is r declared signed?' but 'should the value stored
- * in r be signed or unsigned?'. r is always(?) declared unsigned.
- * Comments below are mine, BTW -- PMM 
- */
-#ifndef _FP_TO_INT
-#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)		\
-  do {								\
-    switch (X##_c)						\
-      {								\
-      case FP_CLS_NORMAL:					\
-	if (X##_e < 0)						\
-	  {							\
-	  /* case FP_CLS_NAN: see above! */			\
-	  case FP_CLS_ZERO:					\
-	    r = 0;						\
-	  }							\
-	else if (X##_e >= rsize - (rsigned != 0))		\
-	  {	/* overflow */					\
-	  case FP_CLS_NAN:                                      \
-          case FP_CLS_INF:					\
-	    if (rsigned)					\
-	      {							\
-		r = 1;						\
-		r <<= rsize - 1;				\
-		r -= 1 - X##_s;					\
-	      }							\
-	    else						\
-	      {							\
-		r = 0;						\
-		if (!X##_s)					\
-		  r = ~r;					\
-	      }							\
-	  }							\
-	else							\
-	  {							\
-	    if (_FP_W_TYPE_SIZE*wc < rsize)			\
-	      {							\
-		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);		\
-		r <<= X##_e - _FP_WFRACBITS_##fs;		\
-	      }							\
-	    else						\
-	      {							\
-		if (X##_e >= _FP_WFRACBITS_##fs)		\
-		  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1)); \
-		else						\
-		  _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
-		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);		\
-	      }							\
-	    if (rsigned && X##_s)				\
-	      r = -r;						\
-	  }							\
-	break;							\
-      }								\
-  } while (0)
-
-#endif /* _FP_TO_INT */
-
-#ifndef _FP_FROM_INT
-#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
-  do {									\
-    if (r)								\
-      {									\
-	X##_c = FP_CLS_NORMAL;						\
-									\
-	if ((X##_s = (r < 0)))						\
-	  r = -r;							\
-	/* Note that `r' is now considered unsigned, so we don't have	\
-	   to worry about the single signed overflow case.  */		\
-									\
-	if (rsize <= _FP_W_TYPE_SIZE)					\
-	  __FP_CLZ(X##_e, r);						\
-	else								\
-	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), 	\
-		     (_FP_W_TYPE)r);					\
-	if (rsize < _FP_W_TYPE_SIZE)					\
-		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
-	X##_e = rsize - X##_e - 1;					\
-									\
-	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)	\
-	  __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);	\
-	r &= ~((_FP_W_TYPE)1 << X##_e);					\
-	_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);	\
-	_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));		\
-      }									\
-    else								\
-      {									\
-	X##_c = FP_CLS_ZERO, X##_s = 0;					\
-      }									\
-  } while (0)
-#endif /* FP_FROM_INT */
-
-#ifndef FP_CONV
-#define FP_CONV(dfs,sfs,dwc,swc,D,S)			\
-  do {							\
-    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);	\
-    D##_e = S##_e;					\
-    D##_c = S##_c;					\
-    D##_s = S##_s;					\
-    D##_r |= S##_r;					\
-  } while (0)
-#endif FP_CONV
-
-/*
- * Helper primitives.
- */
-
-/* Count leading zeros in a word.  */
-
-#ifndef __FP_CLZ
-#if _FP_W_TYPE_SIZE < 64
-/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
-#define __FP_CLZ(r, x)				\
-  do {						\
-    _FP_W_TYPE _t = (x);			\
-    r = _FP_W_TYPE_SIZE - 1;			\
-    if (_t > 0xffff) r -= 16;			\
-    if (_t > 0xffff) _t >>= 16;			\
-    if (_t > 0xff) r -= 8;			\
-    if (_t > 0xff) _t >>= 8;			\
-    if (_t & 0xf0) r -= 4;			\
-    if (_t & 0xf0) _t >>= 4;			\
-    if (_t & 0xc) r -= 2;			\
-    if (_t & 0xc) _t >>= 2;			\
-    if (_t & 0x2) r -= 1;			\
-  } while (0)
-#else /* not _FP_W_TYPE_SIZE < 64 */
-#define __FP_CLZ(r, x)				\
-  do {						\
-    _FP_W_TYPE _t = (x);			\
-    r = _FP_W_TYPE_SIZE - 1;			\
-    if (_t > 0xffffffff) r -= 32;		\
-    if (_t > 0xffffffff) _t >>= 32;		\
-    if (_t > 0xffff) r -= 16;			\
-    if (_t > 0xffff) _t >>= 16;			\
-    if (_t > 0xff) r -= 8;			\
-    if (_t > 0xff) _t >>= 8;			\
-    if (_t & 0xf0) r -= 4;			\
-    if (_t & 0xf0) _t >>= 4;			\
-    if (_t & 0xc) r -= 2;			\
-    if (_t & 0xc) _t >>= 2;			\
-    if (_t & 0x2) r -= 1;			\
-  } while (0)
-#endif /* not _FP_W_TYPE_SIZE < 64 */
-#endif /* ndef __FP_CLZ */
-
-#define _FP_DIV_HELP_imm(q, r, n, d)		\
-  do {						\
-    q = n / d, r = n % d;			\
-  } while (0)
-
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/quad.h linux-2.2.14-pre7/arch/sparc64/math-emu/quad.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/quad.h	1998-04-14 17:44:21.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/quad.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,138 +0,0 @@
-/*
- * Definitions for IEEE Quad Precision
- */
-#if _FP_W_TYPE_SIZE < 32
-/* It appears to be traditional to abuse 16bitters in these header files... */
-#error "Here's a nickel, kid. Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-/* This is all terribly experimental and I don't know if it'll work properly -- PMM 02/1998 */
-#define _FP_FRACTBITS_Q         (4*_FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_Q		(2*_FP_W_TYPE_SIZE)
-#endif
-
-#define _FP_FRACBITS_Q		113
-#define _FP_FRACXBITS_Q		(_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
-#define _FP_WFRACBITS_Q		(_FP_WORKBITS + _FP_FRACBITS_Q)
-#define _FP_WFRACXBITS_Q	(_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
-#define _FP_EXPBITS_Q		15
-#define _FP_EXPBIAS_Q		16383
-#define _FP_EXPMAX_Q		32767
-
-#define _FP_QNANBIT_Q		\
-	((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
-#define _FP_IMPLBIT_Q		\
-	((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
-#define _FP_OVERFLOW_Q		\
-	((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_Q
-{
-   long double flt;
-   struct 
-   {
-#if __BYTE_ORDER == __BIG_ENDIAN
-      unsigned sign : 1;
-      unsigned exp : _FP_EXPBITS_Q;
-      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
-      unsigned long frac2 : _FP_W_TYPE_SIZE;
-      unsigned long frac1 : _FP_W_TYPE_SIZE;
-      unsigned long frac0 : _FP_W_TYPE_SIZE;
-#else
-      unsigned long frac0 : _FP_W_TYPE_SIZE;
-      unsigned long frac1 : _FP_W_TYPE_SIZE;
-      unsigned long frac2 : _FP_W_TYPE_SIZE;
-      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
-      unsigned exp : _FP_EXPBITS_Q;
-      unsigned sign : 1;
-#endif /* not bigendian */
-   } bits __attribute__((packed));
-};
-
-
-#define FP_DECL_Q(X)		_FP_DECL(4,X)
-#define FP_UNPACK_RAW_Q(X,val)	_FP_UNPACK_RAW_4(Q,X,val)
-#define FP_PACK_RAW_Q(val,X)	_FP_PACK_RAW_4(Q,val,X)
-
-#define FP_UNPACK_Q(X,val)		\
-  do {					\
-    _FP_UNPACK_RAW_4(Q,X,val);		\
-    _FP_UNPACK_CANONICAL(Q,4,X);	\
-  } while (0)
-
-#define FP_PACK_Q(val,X)		\
-  do {					\
-    _FP_PACK_CANONICAL(Q,4,X);		\
-    _FP_PACK_RAW_4(Q,val,X);		\
-  } while (0)
-
-#define FP_NEG_Q(R,X)		_FP_NEG(Q,4,R,X)
-#define FP_ADD_Q(R,X,Y)		_FP_ADD(Q,4,R,X,Y)
-/* single.h and double.h define FP_SUB_t this way too. However, _FP_SUB is
- * never defined in op-common.h! Fortunately nobody seems to use the FP_SUB_t 
- * macros: I suggest a combination of FP_NEG and FP_ADD :-> -- PMM 02/1998
- */
-#define FP_SUB_Q(R,X,Y)		_FP_SUB(Q,4,R,X,Y)
-#define FP_MUL_Q(R,X,Y)		_FP_MUL(Q,4,R,X,Y)
-#define FP_DIV_Q(R,X,Y)		_FP_DIV(Q,4,R,X,Y)
-#define FP_SQRT_Q(R,X)		_FP_SQRT(Q,4,R,X)
-
-#define FP_CMP_Q(r,X,Y,un)	_FP_CMP(Q,4,r,X,Y,un)
-#define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,4,r,X,Y)
-
-#define FP_TO_INT_Q(r,X,rsz,rsg)  _FP_TO_INT(Q,4,r,X,rsz,rsg)
-#define FP_FROM_INT_Q(X,r,rs,rt)  _FP_FROM_INT(Q,4,X,r,rs,rt)
-
-#else   /* not _FP_W_TYPE_SIZE < 64 */
-union _FP_UNION_Q
-{
-  long double flt /* __attribute__((mode(TF))) */ ;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign  : 1;
-    unsigned exp   : _FP_EXPBITS_Q;
-    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
-    unsigned long frac0 : _FP_W_TYPE_SIZE;
-#else
-    unsigned long frac0 : _FP_W_TYPE_SIZE;
-    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
-    unsigned exp   : _FP_EXPBITS_Q;
-    unsigned sign  : 1;
-#endif
-  } bits;
-};
-
-#define FP_DECL_Q(X)		_FP_DECL(2,X)
-#define FP_UNPACK_RAW_Q(X,val)	_FP_UNPACK_RAW_2(Q,X,val)
-#define FP_PACK_RAW_Q(val,X)	_FP_PACK_RAW_2(Q,val,X)
-
-#define FP_UNPACK_Q(X,val)		\
-  do {					\
-    _FP_UNPACK_RAW_2(Q,X,val);		\
-    _FP_UNPACK_CANONICAL(Q,2,X);	\
-  } while (0)
-
-#define FP_PACK_Q(val,X)		\
-  do {					\
-    _FP_PACK_CANONICAL(Q,2,X);		\
-    _FP_PACK_RAW_2(Q,val,X);		\
-  } while (0)
-
-#define FP_NEG_Q(R,X)		_FP_NEG(Q,2,R,X)
-#define FP_ADD_Q(R,X,Y)		_FP_ADD(Q,2,R,X,Y)
-#define FP_SUB_Q(R,X,Y)		_FP_SUB(Q,2,R,X,Y)
-#define FP_MUL_Q(R,X,Y)		_FP_MUL(Q,2,R,X,Y)
-#define FP_DIV_Q(R,X,Y)		_FP_DIV(Q,2,R,X,Y)
-#define FP_SQRT_Q(R,X)		_FP_SQRT(Q,2,R,X)
-
-#define FP_CMP_Q(r,X,Y,un)	_FP_CMP(Q,2,r,X,Y,un)
-#define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,2,r,X,Y)
-
-#define FP_TO_INT_Q(r,X,rsz,rsg)  _FP_TO_INT(Q,2,r,X,rsz,rsg)
-#define FP_FROM_INT_Q(X,r,rs,rt)  _FP_FROM_INT(Q,2,X,r,rs,rt)
-
-#endif /* not _FP_W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/sfp-machine.h linux-2.2.14-pre7/arch/sparc64/math-emu/sfp-machine.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/sfp-machine.h	1999-08-09 12:04:57.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/sfp-machine.h	2003-08-15 15:09:03.000000000 -0700
@@ -1,6 +1,10 @@
-/* Machine-dependent software floating-point definitions.  Sparc64 version.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+/* Machine-dependent software floating-point definitions.
+   Sparc64 kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz) and
+		  David S. Miller (davem@redhat.com).
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -17,253 +21,71 @@
    not, write to the Free Software Foundation, Inc.,
    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
 #define _FP_W_TYPE_SIZE		64
 #define _FP_W_TYPE		unsigned long
 #define _FP_WS_TYPE		signed long
 #define _FP_I_TYPE		long
 
-#define _FP_MUL_MEAT_S(R,X,Y)	_FP_MUL_MEAT_1_imm(S,R,X,Y)
-#define _FP_MUL_MEAT_D(R,X,Y)	_FP_MUL_MEAT_1_wide(D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)	_FP_MUL_MEAT_2_wide(Q,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
 
 #define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
 #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv_64(Q,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
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-
-/* On some architectures float-to-int conversions return a result
- * code.  On others (e.g. Sparc) they return 0
- */
-#define _FTOI_RESULT		0
+#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
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
 
 #define _FP_KEEPNANFRACP 1
-#define _FP_CHOOSENAN(fs, wc, R, X, Y)				\
-  do {								\
-    R##_s = Y##_s;						\
-    _FP_FRAC_COPY_##wc(R,Y);					\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define _FP_CHOOSENAN_SQRT(fs, wc, R, X)			\
-  do {								\
-    	R##_s = 0;						\
-    	R##_c = FP_CLS_NAN;					\
-    	_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
-  } while (0)
-
-
-#define __FP_UNPACK_DENORM(fs, wc, X)				\
-    {								\
-	_FP_I_TYPE _shift;					\
-	_FP_FRAC_CLZ_##wc(_shift, X);				\
-	_shift -= _FP_FRACXBITS_##fs;				\
-	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));		\
-	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;			\
-	X##_c = FP_CLS_NORMAL;					\
-    }
-
-
-#define __FP_UNPACK_RAW_1(fs, X, val)				\
-  do {								\
-    union _FP_UNION_##fs *_flo =				\
-    	(union _FP_UNION_##fs *)val;				\
-								\
-    X##_f = _flo->bits.frac;					\
-    X##_e = _flo->bits.exp;					\
-    X##_s = _flo->bits.sign;					\
-  } while (0)
-
-#define __FP_UNPACK_RAW_2(fs, X, val)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    X##_f0 = _flo->bits.frac0;				\
-    X##_f1 = _flo->bits.frac1;				\
-    X##_e  = _flo->bits.exp;				\
-    X##_s  = _flo->bits.sign;				\
-  } while (0)
-
-#define __FP_UNPACK_S(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_1(S,X,val);		\
-    _FP_UNPACK_CANONICAL(S,1,X);	\
-  } while (0)
 
-#define __FP_UNPACK_D(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_1(D,X,val);		\
-    _FP_UNPACK_CANONICAL(D,1,X);	\
-  } while (0)
-
-#define __FP_UNPACK_Q(X,val)		\
-  do {					\
-    __FP_UNPACK_RAW_2(Q,X,val);		\
-    _FP_UNPACK_CANONICAL(Q,2,X);	\
-  } while (0)
-
-#define __FP_PACK_RAW_1(fs, val, X)				\
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
   do {								\
-    union _FP_UNION_##fs *_flo =				\
-    	(union _FP_UNION_##fs *)val;				\
-								\
-    _flo->bits.frac = X##_f;					\
-    _flo->bits.exp  = X##_e;					\
-    _flo->bits.sign = X##_s;					\
-  } while (0)
-  
-#define __FP_PACK_RAW_2(fs, val, X)			\
-  do {							\
-    union _FP_UNION_##fs *_flo =			\
-    	(union _FP_UNION_##fs *)val;			\
-							\
-    _flo->bits.frac0 = X##_f0;				\
-    _flo->bits.frac1 = X##_f1;				\
-    _flo->bits.exp   = X##_e;				\
-    _flo->bits.sign  = X##_s;				\
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
   } while (0)
 
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-/* We only actually write to the destination register
- * if exceptions signalled (if any) will not trap.
- */
-#define __FPU_TEM \
-	(((current->tss.xfsr[0])>>23)&0x1f)
-#define __FPU_TRAP_P(bits) \
-	((__FPU_TEM & (bits)) != 0)
-
-#define __FP_PACK_S(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(S,1,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_1(S,val,X);		\
-    __exc;					\
-})
-
-#define __FP_PACK_D(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(D,1,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_1(D,val,X);		\
-    __exc;					\
-})
-
-#define __FP_PACK_Q(val,X)			\
-({  int __exc = _FP_PACK_CANONICAL(Q,2,X);	\
-    if(!__exc || !__FPU_TRAP_P(__exc))		\
-        __FP_PACK_RAW_2(Q,val,X);		\
-    __exc;					\
-})
-
 /* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
 #define FP_ROUNDMODE	((current->tss.xfsr[0] >> 30) & 0x3)
+#endif
 
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) 						\
-  __asm__ ("addcc %4,%5,%1
-  	    add %2,%3,%0
-  	    bcs,a,pn %%xcc, 1f
-  	    add %0, 1, %0
-  	    1:"										\
-	   : "=r" ((UDItype)(sh)),				      			\
-	     "=&r" ((UDItype)(sl))				      			\
-	   : "r" ((UDItype)(ah)),				     			\
-	     "r" ((UDItype)(bh)),				      			\
-	     "r" ((UDItype)(al)),				     			\
-	     "r" ((UDItype)(bl))				       			\
-	   : "cc")
-	   
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) 						\
-  __asm__ ("subcc %4,%5,%1
-  	    sub %2,%3,%0
-  	    bcs,a,pn %%xcc, 1f
-  	    sub %0, 1, %0
-  	    1:"										\
-	   : "=r" ((UDItype)(sh)),				      			\
-	     "=&r" ((UDItype)(sl))				      			\
-	   : "r" ((UDItype)(ah)),				     			\
-	     "r" ((UDItype)(bh)),				      			\
-	     "r" ((UDItype)(al)),				     			\
-	     "r" ((UDItype)(bl))				       			\
-	   : "cc")
-	   
-#define umul_ppmm(wh, wl, u, v) 							\
-  do {											\
-	  __asm__ ("mulx %2,%3,%1
-  		    srlx %2,32,%%g1
-	  	    srl %3,0,%%g2
-  		    mulx %%g1,%%g2,%%g3
-  		    srlx %3,32,%%g1
-  		    srl %2,0,%%g2
-  		    mulx %%g1,%%g2,%%g2
-  		    srlx %2,32,%%g1
-  		    add %%g2,%%g3,%%g3
-  		    srlx %3,32,%%g2
-  		    mulx %%g1,%%g2,%%g1
-  		    srlx %%g3,32,%%g2
-  		    add %%g1,%%g2,%0"							\
-	   : "=r" ((UDItype)(wh)),				      			\
-	     "=&r" ((UDItype)(wl))				      			\
-	   : "r" ((UDItype)(u)),				     			\
-	     "r" ((UDItype)(v))				      				\
-	   : "g1", "g2", "g3", "cc");							\
-  } while (0)
-  
-#define udiv_qrnnd(q, r, n1, n0, d) 							\
-  do {                                                                  		\
-    UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m;                     		\
-    __d1 = (d >> 32);                                           			\
-    __d0 = (USItype)d;                                            			\
-                                                                        		\
-    __r1 = (n1) % __d1;                                                 		\
-    __q1 = (n1) / __d1;                                                 		\
-    __m = (UWtype) __q1 * __d0;                                         		\
-    __r1 = (__r1 << 32) | (n0 >> 32);                          				\
-    if (__r1 < __m)                                                     		\
-      {                                                                 		\
-        __q1--, __r1 += (d);                                            		\
-        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */		\
-          if (__r1 < __m)                                               		\
-            __q1--, __r1 += (d);                                        		\
-      }                                                                 		\
-    __r1 -= __m;                                                        		\
-                                                                        		\
-    __r0 = __r1 % __d1;                                                 		\
-    __q0 = __r1 / __d1;                                                 		\
-    __m = (UWtype) __q0 * __d0;                                         		\
-    __r0 = (__r0 << 32) | ((USItype)n0);                           			\
-    if (__r0 < __m)                                                     		\
-      {                                                                 		\
-        __q0--, __r0 += (d);                                            		\
-        if (__r0 >= (d))                                                		\
-          if (__r0 < __m)                                               		\
-            __q0--, __r0 += (d);                                        		\
-      }                                                                 		\
-    __r0 -= __m;                                                        		\
-                                                                        		\
-    (q) = (UWtype) (__q1 << 32)  | __q0;                                		\
-    (r) = __r0;                                                         		\
-  } while (0)
+/* Exception flags. */
+#define FP_EX_INVALID		(1 << 4)
+#define FP_EX_OVERFLOW		(1 << 3)
+#define FP_EX_UNDERFLOW		(1 << 2)
+#define FP_EX_DIVZERO		(1 << 1)
+#define FP_EX_INEXACT		(1 << 0)
 
-#define UDIV_NEEDS_NORMALIZATION 1  
+#define FP_HANDLE_EXCEPTIONS return _fex
 
-#define abort()										\
-	return 0
+#define FP_INHIBIT_RESULTS ((current->tss.xfsr[0] >> 23) & _fex)
 
-#ifdef __BIG_ENDIAN
-#define __BYTE_ORDER __BIG_ENDIAN
-#else
-#define __BYTE_ORDER __LITTLE_ENDIAN
 #endif
-
-/* Exception flags. */
-#define EFLAG_INVALID		(1 << 4)
-#define EFLAG_OVERFLOW		(1 << 3)
-#define EFLAG_UNDERFLOW		(1 << 2)
-#define EFLAG_DIVZERO		(1 << 1)
-#define EFLAG_INEXACT		(1 << 0)
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/sfp-util.h linux-2.2.14-pre7/arch/sparc64/math-emu/sfp-util.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/sfp-util.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/sfp-util.h	2003-08-15 15:09:03.000000000 -0700
@@ -0,0 +1,120 @@
+/* $Id: sfp-util.h,v 1.3.2.1 1999/09/20 12:06:23 jj Exp $
+ * arch/sparc64/math-emu/sfp-util.h
+ *
+ * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) 						\
+  __asm__ ("addcc %4,%5,%1
+  	    add %2,%3,%0
+  	    bcs,a,pn %%xcc, 1f
+  	    add %0, 1, %0
+  	    1:"										\
+	   : "=r" ((UDItype)(sh)),				      			\
+	     "=&r" ((UDItype)(sl))				      			\
+	   : "r" ((UDItype)(ah)),				     			\
+	     "r" ((UDItype)(bh)),				      			\
+	     "r" ((UDItype)(al)),				     			\
+	     "r" ((UDItype)(bl))				       			\
+	   : "cc")
+	   
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) 						\
+  __asm__ ("subcc %4,%5,%1
+  	    sub %2,%3,%0
+  	    bcs,a,pn %%xcc, 1f
+  	    sub %0, 1, %0
+  	    1:"										\
+	   : "=r" ((UDItype)(sh)),				      			\
+	     "=&r" ((UDItype)(sl))				      			\
+	   : "r" ((UDItype)(ah)),				     			\
+	     "r" ((UDItype)(bh)),				      			\
+	     "r" ((UDItype)(al)),				     			\
+	     "r" ((UDItype)(bl))				       			\
+	   : "cc")
+
+#define umul_ppmm(wh, wl, u, v)								\
+  do {											\
+	  UDItype tmp1, tmp2, tmp3, tmp4;						\
+	  __asm__ __volatile__ (							\
+		   "srl %7,0,%3
+		    mulx %3,%6,%1
+		    srlx %6,32,%2
+		    mulx %2,%3,%4
+		    sllx %4,32,%5
+		    srl %6,0,%3
+		    sub %1,%5,%5
+		    srlx %5,32,%5
+		    addcc %4,%5,%4
+		    srlx %7,32,%5
+		    mulx %3,%5,%3
+		    mulx %2,%5,%5
+		    sethi %%hi(0x80000000),%2
+		    addcc %4,%3,%4
+		    srlx %4,32,%4
+		    add %2,%2,%2
+		    movcc %%xcc,%%g0,%2
+		    addcc %5,%4,%5
+		    sllx %3,32,%3
+		    add %1,%3,%1
+		    add %5,%2,%0"							\
+	   : "=r" ((UDItype)(wh)),							\
+	     "=&r" ((UDItype)(wl)),							\
+	     "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)			\
+	   : "r" ((UDItype)(u)),							\
+	     "r" ((UDItype)(v))								\
+	   : "cc");									\
+  } while (0)
+  
+#define udiv_qrnnd(q, r, n1, n0, d) 							\
+  do {                                                                  		\
+    UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m;                     		\
+    __d1 = (d >> 32);                                           			\
+    __d0 = (USItype)d;                                            			\
+                                                                        		\
+    __r1 = (n1) % __d1;                                                 		\
+    __q1 = (n1) / __d1;                                                 		\
+    __m = (UWtype) __q1 * __d0;                                         		\
+    __r1 = (__r1 << 32) | (n0 >> 32);                          				\
+    if (__r1 < __m)                                                     		\
+      {                                                                 		\
+        __q1--, __r1 += (d);                                            		\
+        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */		\
+          if (__r1 < __m)                                               		\
+            __q1--, __r1 += (d);                                        		\
+      }                                                                 		\
+    __r1 -= __m;                                                        		\
+                                                                        		\
+    __r0 = __r1 % __d1;                                                 		\
+    __q0 = __r1 / __d1;                                                 		\
+    __m = (UWtype) __q0 * __d0;                                         		\
+    __r0 = (__r0 << 32) | ((USItype)n0);                           			\
+    if (__r0 < __m)                                                     		\
+      {                                                                 		\
+        __q0--, __r0 += (d);                                            		\
+        if (__r0 >= (d))                                                		\
+          if (__r0 < __m)                                               		\
+            __q0--, __r0 += (d);                                        		\
+      }                                                                 		\
+    __r0 -= __m;                                                        		\
+                                                                        		\
+    (q) = (UWtype) (__q1 << 32)  | __q0;                                		\
+    (r) = __r0;                                                         		\
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1  
+
+#define abort()										\
+	return 0
+
+#ifdef __BIG_ENDIAN
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/single.h linux-2.2.14-pre7/arch/sparc64/math-emu/single.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/single.h	1998-04-14 17:44:21.000000000 -0700
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/single.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,66 +0,0 @@
-/*
- * Definitions for IEEE Single Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid.  Go buy yourself a real computer."
-#endif
-
-#define _FP_FRACBITS_S		24
-#define _FP_FRACXBITS_S		(_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
-#define _FP_WFRACBITS_S		(_FP_WORKBITS + _FP_FRACBITS_S)
-#define _FP_WFRACXBITS_S	(_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
-#define _FP_EXPBITS_S		8
-#define _FP_EXPBIAS_S		127
-#define _FP_EXPMAX_S		255
-#define _FP_QNANBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
-#define _FP_IMPLBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
-#define _FP_OVERFLOW_S		((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
-
-/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
-   chosen by the target machine.  */
-
-union _FP_UNION_S
-{
-  float flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign : 1;
-    unsigned exp  : _FP_EXPBITS_S;
-    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
-#else
-    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
-    unsigned exp  : _FP_EXPBITS_S;
-    unsigned sign : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_S(X)		_FP_DECL(1,X)
-#define FP_UNPACK_RAW_S(X,val)	_FP_UNPACK_RAW_1(S,X,val)
-#define FP_PACK_RAW_S(val,X)	_FP_PACK_RAW_1(S,val,X)
-
-#define FP_UNPACK_S(X,val)		\
-  do {					\
-    _FP_UNPACK_RAW_1(S,X,val);		\
-    _FP_UNPACK_CANONICAL(S,1,X);	\
-  } while (0)
-
-#define FP_PACK_S(val,X)		\
-  do {					\
-    _FP_PACK_CANONICAL(S,1,X);		\
-    _FP_PACK_RAW_1(S,val,X);		\
-  } while (0)
-
-#define FP_NEG_S(R,X)		_FP_NEG(S,1,R,X)
-#define FP_ADD_S(R,X,Y)		_FP_ADD(S,1,R,X,Y)
-#define FP_SUB_S(R,X,Y)		_FP_SUB(S,1,R,X,Y)
-#define FP_MUL_S(R,X,Y)		_FP_MUL(S,1,R,X,Y)
-#define FP_DIV_S(R,X,Y)		_FP_DIV(S,1,R,X,Y)
-#define FP_SQRT_S(R,X)		_FP_SQRT(S,1,R,X)
-
-#define FP_CMP_S(r,X,Y,un)	_FP_CMP(S,1,r,X,Y,un)
-#define FP_CMP_EQ_S(r,X,Y)	_FP_CMP_EQ(S,1,r,X,Y)
-
-#define FP_TO_INT_S(r,X,rsz,rsg)  _FP_TO_INT(S,1,r,X,rsz,rsg)
-#define FP_FROM_INT_S(X,r,rs,rt)  _FP_FROM_INT(S,1,X,r,rs,rt)
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/soft-fp.h linux-2.2.14-pre7/arch/sparc64/math-emu/soft-fp.h
--- linux-2.2.14-pre6/arch/sparc64/math-emu/soft-fp.h	1999-03-10 16:53:37.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/soft-fp.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,94 +0,0 @@
-#ifndef SOFT_FP_H
-#define SOFT_FP_H
-
-#include "sfp-machine.h"
-
-#define _FP_WORKBITS		3
-#define _FP_WORK_LSB		((_FP_W_TYPE)1 << 3)
-#define _FP_WORK_ROUND		((_FP_W_TYPE)1 << 2)
-#define _FP_WORK_GUARD		((_FP_W_TYPE)1 << 1)
-#define _FP_WORK_STICKY		((_FP_W_TYPE)1 << 0)
-
-#ifndef FP_RND_NEAREST
-# define FP_RND_NEAREST		0
-# define FP_RND_ZERO		1
-# define FP_RND_PINF		2
-# define FP_RND_MINF		3
-#ifndef FP_ROUNDMODE
-# define FP_ROUNDMODE		FP_RND_NEAREST
-#endif
-#endif
-
-#define _FP_ROUND_NEAREST(wc, X)			\
-({  int __ret = EFLAG_INEXACT;				\
-    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\
-      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);		\
-    else __ret = 0;					\
-    __ret;						\
-})
-
-#define _FP_ROUND_ZERO(wc, X)		0 /* XXX */
-
-#define _FP_ROUND_PINF(wc, X)				\
-({  int __ret = EFLAG_INEXACT;				\
-    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
-      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
-    else __ret = 0;					\
-    __ret;						\
-})
-
-#define _FP_ROUND_MINF(wc, X)				\
-({  int __ret = EFLAG_INEXACT;				\
-    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
-      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
-    else __ret = 0;					\
-    __ret;						\
-})
-
-#define _FP_ROUND(wc, X)			\
-({	int __ret = 0;				\
-	switch (FP_ROUNDMODE)			\
-	{					\
-	  case FP_RND_NEAREST:			\
-	    __ret |= _FP_ROUND_NEAREST(wc,X);	\
-	    break;				\
-	  case FP_RND_ZERO:			\
-	    __ret |= _FP_ROUND_ZERO(wc,X);	\
-	    break;				\
-	  case FP_RND_PINF:			\
-	    __ret |= _FP_ROUND_PINF(wc,X);	\
-	    break;				\
-	  case FP_RND_MINF:			\
-	    __ret |= _FP_ROUND_MINF(wc,X);	\
-	    break;				\
-	};					\
-	__ret;					\
-})
-
-#define FP_CLS_NORMAL		0
-#define FP_CLS_ZERO		1
-#define FP_CLS_INF		2
-#define FP_CLS_NAN		3
-
-#define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
-
-#include "op-1.h"
-#include "op-2.h"
-#include "op-4.h"
-#include "op-common.h"
-
-/* Sigh.  Silly things longlong.h needs.  */
-#define UWtype		_FP_W_TYPE
-#define W_TYPE_SIZE	_FP_W_TYPE_SIZE
-
-typedef int SItype __attribute__((mode(SI)));
-typedef int DItype __attribute__((mode(DI)));
-typedef unsigned int USItype __attribute__((mode(SI)));
-typedef unsigned int UDItype __attribute__((mode(DI)));
-#if _FP_W_TYPE_SIZE == 32
-typedef unsigned int UHWtype __attribute__((mode(HI)));
-#elif _FP_W_TYPE_SIZE == 64
-typedef USItype UHWtype;
-#endif
-
-#endif
diff -urN linux-2.2.14-pre6/arch/sparc64/math-emu/udivmodti4.c linux-2.2.14-pre7/arch/sparc64/math-emu/udivmodti4.c
--- linux-2.2.14-pre6/arch/sparc64/math-emu/udivmodti4.c	1998-01-12 15:15:44.000000000 -0800
+++ linux-2.2.14-pre7/arch/sparc64/math-emu/udivmodti4.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,191 +0,0 @@
-/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */
-
-#include "soft-fp.h"
-
-#undef count_leading_zeros
-#define count_leading_zeros  __FP_CLZ
-
-void
-_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
-	       _FP_W_TYPE n1, _FP_W_TYPE n0,
-	       _FP_W_TYPE d1, _FP_W_TYPE d0)
-{
-  _FP_W_TYPE q0, q1, r0, r1;
-  _FP_I_TYPE b, bm;
-
-  if (d1 == 0)
-    {
-#if !UDIV_NEEDS_NORMALIZATION
-      if (d0 > n1)
-	{
-	  /* 0q = nn / 0D */
-
-	  udiv_qrnnd (q0, n0, n1, n0, d0);
-	  q1 = 0;
-
-	  /* Remainder in n0.  */
-	}
-      else
-	{
-	  /* qq = NN / 0d */
-
-	  if (d0 == 0)
-	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
-
-	  udiv_qrnnd (q1, n1, 0, n1, d0);
-	  udiv_qrnnd (q0, n0, n1, n0, d0);
-
-	  /* Remainder in n0.  */
-	}
-
-      r0 = n0;
-      r1 = 0;
-
-#else /* UDIV_NEEDS_NORMALIZATION */
-
-      if (d0 > n1)
-	{
-	  /* 0q = nn / 0D */
-
-	  count_leading_zeros (bm, d0);
-
-	  if (bm != 0)
-	    {
-	      /* Normalize, i.e. make the most significant bit of the
-		 denominator set.  */
-
-	      d0 = d0 << bm;
-	      n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
-	      n0 = n0 << bm;
-	    }
-
-	  udiv_qrnnd (q0, n0, n1, n0, d0);
-	  q1 = 0;
-
-	  /* Remainder in n0 >> bm.  */
-	}
-      else
-	{
-	  /* qq = NN / 0d */
-
-	  if (d0 == 0)
-	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
-
-	  count_leading_zeros (bm, d0);
-
-	  if (bm == 0)
-	    {
-	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
-		 conclude (the most significant bit of n1 is set) /\ (the
-		 leading quotient digit q1 = 1).
-
-		 This special case is necessary, not an optimization.
-		 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
-
-	      n1 -= d0;
-	      q1 = 1;
-	    }
-	  else
-	    {
-	      _FP_W_TYPE n2;
-
-	      /* Normalize.  */
-
-	      b = _FP_W_TYPE_SIZE - bm;
-
-	      d0 = d0 << bm;
-	      n2 = n1 >> b;
-	      n1 = (n1 << bm) | (n0 >> b);
-	      n0 = n0 << bm;
-
-	      udiv_qrnnd (q1, n1, n2, n1, d0);
-	    }
-
-	  /* n1 != d0...  */
-
-	  udiv_qrnnd (q0, n0, n1, n0, d0);
-
-	  /* Remainder in n0 >> bm.  */
-	}
-
-      r0 = n0 >> bm;
-      r1 = 0;
-#endif /* UDIV_NEEDS_NORMALIZATION */
-    }
-  else
-    {
-      if (d1 > n1)
-	{
-	  /* 00 = nn / DD */
-
-	  q0 = 0;
-	  q1 = 0;
-
-	  /* Remainder in n1n0.  */
-	  r0 = n0;
-	  r1 = n1;
-	}
-      else
-	{
-	  /* 0q = NN / dd */
-
-	  count_leading_zeros (bm, d1);
-	  if (bm == 0)
-	    {
-	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
-		 conclude (the most significant bit of n1 is set) /\ (the
-		 quotient digit q0 = 0 or 1).
-
-		 This special case is necessary, not an optimization.  */
-
-	      /* The condition on the next line takes advantage of that
-		 n1 >= d1 (true due to program flow).  */
-	      if (n1 > d1 || n0 >= d0)
-		{
-		  q0 = 1;
-		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
-		}
-	      else
-		q0 = 0;
-
-	      q1 = 0;
-
-	      r0 = n0;
-	      r1 = n1;
-	    }
-	  else
-	    {
-	      _FP_W_TYPE m1, m0, n2;
-
-	      /* Normalize.  */
-
-	      b = _FP_W_TYPE_SIZE - bm;
-
-	      d1 = (d1 << bm) | (d0 >> b);
-	      d0 = d0 << bm;
-	      n2 = n1 >> b;
-	      n1 = (n1 << bm) | (n0 >> b);
-	      n0 = n0 << bm;
-
-	      udiv_qrnnd (q0, n1, n2, n1, d1);
-	      umul_ppmm (m1, m0, q0, d0);
-
-	      if (m1 > n1 || (m1 == n1 && m0 > n0))
-		{
-		  q0--;
-		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
-		}
-
-	      q1 = 0;
-
-	      /* Remainder in (n1n0 - m1m0) >> bm.  */
-	      sub_ddmmss (n1, n0, n1, n0, m1, m0);
-	      r0 = (n1 << b) | (n0 >> bm);
-	      r1 = n1 >> bm;
-	    }
-	}
-    }
-
-  q[0] = q0; q[1] = q1;
-  r[0] = r0, r[1] = r1;
-}
diff -urN linux-2.2.14-pre6/Documentation/pci.txt linux-2.2.14-pre7/Documentation/pci.txt
--- linux-2.2.14-pre6/Documentation/pci.txt	1998-04-28 14:22:04.000000000 -0700
+++ linux-2.2.14-pre7/Documentation/pci.txt	2003-08-15 15:09:03.000000000 -0700
@@ -51,6 +51,30 @@
 config space. You should use the values in the pci_dev structure as they might
 have been remapped by the kernel.
 
+   If your PCI device uses PCI I/O space, you need to use the check_region(),
+request_region() and release_region() routines. These prevent devices from 
+having conflicting I/O regions. You access your registers using the inb(),
+inw(), inl(), outb(), outw(), or outl() routines passing the value of
+(struct pci_dev *) dev->base_address[] masked by PCI_BASE_ADDRESS_IO_MASK
+as the base address of your registers.
+
+   If your PCI device uses PCI memory space, use ioremap() to create a cookie 
+mapping to your PCI device. The mask (struct pci_dev *) dev->base_address[] 
+with PCI_BASE_ADDRESS_MEM_MASK before passing it into ioremap(). This cookie 
+is passed to the readb(), readw(), readl(), writeb(), writew(), and writel() 
+routines when accessing PCI space. You must always use these routines when 
+accessing PCI space from the kernel. Not all architectures allow direct access
+to PCI memory space from the kernel.
+
+   The IO-mapping.txt file has information about converting between the
+various address spaces. People writing DMA device drivers should pay special
+attention to this information.
+
+   PCI interrupt routines are always SA_SHIRQ and should use the value from
+(struct pci_dev *) dev->irq field for the interrupt number passed into 
+request_irq(). Since it is a shared interrupt, you must also always pass a 
+unique dev_id to request_irq().
+
 4. Obsolete functions
 ~~~~~~~~~~~~~~~~~~~~~
 <linux/bios32.h> is obsolete and should not be included in new code.
diff -urN linux-2.2.14-pre6/drivers/block/genhd.c linux-2.2.14-pre7/drivers/block/genhd.c
--- linux-2.2.14-pre6/drivers/block/genhd.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/block/genhd.c	2003-08-15 15:09:03.000000000 -0700
@@ -1055,7 +1055,8 @@
 	int dev_bsize, dev_pos, pos;
 	unsigned secsize;
 #ifdef CONFIG_PPC
-	int first_bootable = 1;
+	int found_root = 0;
+	int found_root_goodness = 0;
 #endif
 	struct mac_partition *part;
 	struct mac_driver_desc *md;
@@ -1113,16 +1114,36 @@
 		 * If this is the first bootable partition, tell the
 		 * setup code, in case it wants to make this the root.
 		 */
-		if ( (_machine == _MACH_Pmac) && first_bootable
-		    && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
-		    && strcasecmp(part->processor, "powerpc") == 0) {
-			note_bootable_part(dev, blk);
-			first_bootable = 0;
+		if (_machine == _MACH_Pmac) {
+			int goodness = 0;
+		    
+			if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
+			    && strcasecmp(part->processor, "powerpc") == 0)
+				goodness++;
+
+			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0) {
+				goodness++;
+				if ((strcmp(part->name, "/") == 0) ||
+				    (strstr(part->name, "root") != 0)) {
+					goodness++;
+				}
+				if (strncmp(part->name, "swap", 4) == 0)
+					goodness--;
+			}
+
+			if (goodness > found_root_goodness) {
+				found_root = blk;
+				found_root_goodness = goodness;
+			}
 		}
 #endif /* CONFIG_PPC */
 
 		++current_minor;
 	}
+#ifdef CONFIG_PPC
+	if (found_root_goodness)
+		note_bootable_part(dev, found_root);
+#endif
 	brelse(bh);
 	printk("\n");
 	return 1;
diff -urN linux-2.2.14-pre6/drivers/block/ide-tape.c linux-2.2.14-pre7/drivers/block/ide-tape.c
--- linux-2.2.14-pre6/drivers/block/ide-tape.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/block/ide-tape.c	2003-08-15 15:09:03.000000000 -0700
@@ -346,6 +346,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/byteorder.h>
 #include <asm/unaligned.h>
 #include <asm/bitops.h>
 
@@ -524,7 +525,7 @@
 	byte *current_position;			/* Pointer into the above buffer */
 	ide_startstop_t (*callback) (ide_drive_t *);	/* Called when this packet command is completed */
 	byte pc_buffer[IDETAPE_PC_BUFFER_SIZE];	/* Temporary buffer */
-	unsigned int flags;			/* Status/Action bit flags */
+	unsigned long flags;			/* Status/Action bit flags */
 } idetape_pc_t;
 
 /*
@@ -541,19 +542,55 @@
  *	Capabilities and Mechanical Status Page
  */
 typedef struct {
-	unsigned	page_code	:6;	/* Page code - Should be 0x2a */
-	unsigned	reserved1_67	:2;
+#if defined(__BIG_ENDIAN_BITFIELD)
+	u8	reserved1_67	:2;
+	u8	page_code	:6;	/* Page code - Should be 0x2a */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	u8	page_code	:6;	/* Page code - Should be 0x2a */
+	u8	reserved1_67	:2;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
 	u8		page_length;		/* Page Length - Should be 0x12 */
 	u8		reserved2, reserved3;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	reserved4_67	:2;
+	unsigned	sprev		:1;	/* Supports SPACE in the reverse direction */
+	unsigned	reserved4_1234	:4;
+	unsigned	ro		:1;	/* Read Only Mode */
+
+	unsigned	reserved5_67	:2;
+	unsigned	qfa		:1;	/* Supports the QFA two partition formats */
+	unsigned	reserved5_4	:1;
+	unsigned	efmt		:1;	/* Supports ERASE command initiated formatting */
+	unsigned	reserved5_012	:3;
+
+	unsigned	cmprs		:1;	/* Supports data compression */
+	unsigned	ecc		:1;	/* Supports error correction */
+	unsigned	reserved6_45	:2;	/* Reserved */	
+	unsigned	eject		:1;	/* The device can eject the volume */
+	unsigned	prevent		:1;	/* The device defaults in the prevent state after power up */	
+	unsigned	locked		:1;	/* The volume is locked */
+	unsigned	lock		:1;	/* Supports locking the volume */
+
+	unsigned	slowb		:1;	/* The device restricts the byte count for PIO */
+	unsigned	reserved7_3_6	:4;
+	unsigned	blk1024		:1;	/* Supports 1024 bytes block size */
+	unsigned	blk512		:1;	/* Supports 512 bytes block size */
+	unsigned	reserved7_0	:1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	ro		:1;	/* Read Only Mode */
 	unsigned	reserved4_1234	:4;
 	unsigned	sprev		:1;	/* Supports SPACE in the reverse direction */
 	unsigned	reserved4_67	:2;
+
 	unsigned	reserved5_012	:3;
 	unsigned	efmt		:1;	/* Supports ERASE command initiated formatting */
 	unsigned	reserved5_4	:1;
 	unsigned	qfa		:1;	/* Supports the QFA two partition formats */
 	unsigned	reserved5_67	:2;
+
 	unsigned	lock		:1;	/* Supports locking the volume */
 	unsigned	locked		:1;	/* The volume is locked */
 	unsigned	prevent		:1;	/* The device defaults in the prevent state after power up */	
@@ -561,11 +598,13 @@
 	unsigned	reserved6_45	:2;	/* Reserved */	
 	unsigned	ecc		:1;	/* Supports error correction */
 	unsigned	cmprs		:1;	/* Supports data compression */
+
 	unsigned	reserved7_0	:1;
 	unsigned	blk512		:1;	/* Supports 512 bytes block size */
 	unsigned	blk1024		:1;	/* Supports 1024 bytes block size */
 	unsigned	reserved7_3_6	:4;
 	unsigned	slowb		:1;	/* The device restricts the byte count for PIO */
+#endif
 						/* transfers for slow buffer memory ??? */
 	u16		max_speed;		/* Maximum speed supported in KBps */
 	u8		reserved10, reserved11;
@@ -695,7 +734,7 @@
 	int pages_per_stage;
 	int excess_bh_size;			/* Wasted space in each stage */
 
-	unsigned int flags;			/* Status/Action flags */
+	unsigned long flags;			/* Status/Action flags */
 	spinlock_t spinlock;			/* protects the ide-tape queue */
 } idetape_tape_t;
 
@@ -787,6 +826,16 @@
 typedef union {
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned bsy		:1;	/* The device has access to the command block */
+		unsigned drdy		:1;	/* Ignored for ATAPI commands (ready to accept ATA command) */
+		unsigned reserved5	:1;	/* Reserved */
+		unsigned dsc		:1;	/* Buffer availability / Media access command finished */
+		unsigned drq		:1;	/* Data is request by the device */
+		unsigned corr		:1;	/* Correctable error occurred */
+		unsigned idx		:1;	/* Reserved */
+		unsigned check		:1;	/* Error occurred */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned check		:1;	/* Error occurred */
 		unsigned idx		:1;	/* Reserved */
 		unsigned corr		:1;	/* Correctable error occurred */
@@ -795,6 +844,7 @@
 		unsigned reserved5	:1;	/* Reserved */
 		unsigned drdy		:1;	/* Ignored for ATAPI commands (ready to accept ATA command) */
 		unsigned bsy		:1;	/* The device has access to the command block */
+#endif
 	} b;
 } idetape_status_reg_t;
 
@@ -804,11 +854,19 @@
 typedef union {
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned sense_key	:4;	/* Sense key of the last failed packet command */
+		unsigned mcr		:1;	/* Media Change Requested - As defined by ATA */
+		unsigned abrt		:1;	/* Aborted command - As defined by ATA */
+		unsigned eom		:1;	/* End Of Media Detected */
+		unsigned ili		:1;	/* Illegal Length Indication */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned ili		:1;	/* Illegal Length Indication */
 		unsigned eom		:1;	/* End Of Media Detected */
 		unsigned abrt		:1;	/* Aborted command - As defined by ATA */
 		unsigned mcr		:1;	/* Media Change Requested - As defined by ATA */
 		unsigned sense_key	:4;	/* Sense key of the last failed packet command */
+#endif
 	} b;
 } idetape_error_reg_t;
 
@@ -818,10 +876,17 @@
 typedef union {
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned reserved7	:1;	/* Reserved */
+		unsigned reserved654	:3;	/* Reserved (Tag Type) */
+		unsigned reserved321	:3;	/* Reserved */
+		unsigned dma		:1;	/* Using DMA of PIO */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned dma		:1;	/* Using DMA of PIO */
 		unsigned reserved321	:3;	/* Reserved */
 		unsigned reserved654	:3;	/* Reserved (Tag Type) */
 		unsigned reserved7	:1;	/* Reserved */
+#endif
 	} b;
 } idetape_feature_reg_t;
 
@@ -831,8 +896,13 @@
 typedef union {
 	unsigned all			:16;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned high		:8;	/* MSB */
+		unsigned low		:8;	/* LSB */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned low		:8;	/* LSB */
 		unsigned high		:8;	/* MSB */
+#endif
 	} b;
 } idetape_bcount_reg_t;
 
@@ -842,9 +912,15 @@
 typedef union {
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned reserved	:6;	/* Reserved */
+		unsigned io		:1;	/* The device requests us to read (1) or write (0) */
+		unsigned cod		:1;	/* Information transferred is command (1) or data (0) */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned cod		:1;	/* Information transferred is command (1) or data (0) */
 		unsigned io		:1;	/* The device requests us to read (1) or write (0) */
 		unsigned reserved	:6;	/* Reserved */
+#endif
 	} b;
 } idetape_ireason_reg_t;
 
@@ -854,11 +930,19 @@
 typedef union {	
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned one7		:1;	/* Should be set to 1 */
+		unsigned reserved6	:1;	/* Reserved */
+		unsigned one5		:1;	/* Should be set to 1 */
+		unsigned drv		:1;	/* The responding drive will be drive 0 (0) or drive 1 (1) */
+		unsigned sam_lun	:4;	/* Should be zero with ATAPI (not used) */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned sam_lun	:4;	/* Should be zero with ATAPI (not used) */
 		unsigned drv		:1;	/* The responding drive will be drive 0 (0) or drive 1 (1) */
 		unsigned one5		:1;	/* Should be set to 1 */
 		unsigned reserved6	:1;	/* Reserved */
 		unsigned one7		:1;	/* Should be set to 1 */
+#endif
 	} b;
 } idetape_drivesel_reg_t;
 
@@ -868,11 +952,19 @@
 typedef union {			
 	unsigned all			:8;
 	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+		unsigned reserved4567	:4;	/* Reserved */
+		unsigned one3		:1;	/* Should be set to 1 */
+		unsigned srst		:1;	/* ATA software reset. ATAPI devices should use the new ATAPI srst. */
+		unsigned nien		:1;	/* Device interrupt is disabled (1) or enabled (0) */
+		unsigned zero0		:1;	/* Should be set to zero */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 		unsigned zero0		:1;	/* Should be set to zero */
 		unsigned nien		:1;	/* Device interrupt is disabled (1) or enabled (0) */
 		unsigned srst		:1;	/* ATA software reset. ATAPI devices should use the new ATAPI srst. */
 		unsigned one3		:1;	/* Should be set to 1 */
 		unsigned reserved4567	:4;	/* Reserved */
+#endif
 	} b;
 } idetape_control_reg_t;
 
@@ -890,6 +982,15 @@
  *	the ATAPI IDENTIFY DEVICE command.
  */
 struct idetape_id_gcw {	
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned protocol		:2;	/* Protocol type */
+	unsigned reserved13		:1;	/* Reserved */
+	unsigned device_type		:5;	/* Device type */
+	unsigned removable		:1;	/* Removable media */
+	unsigned drq_type		:2;	/* Command packet DRQ type */
+	unsigned reserved234		:3;	/* Reserved */
+	unsigned packet_size		:2;	/* Packet Size */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned packet_size		:2;	/* Packet Size */
 	unsigned reserved234		:3;	/* Reserved */
 	unsigned drq_type		:2;	/* Command packet DRQ type */
@@ -897,23 +998,50 @@
 	unsigned device_type		:5;	/* Device type */
 	unsigned reserved13		:1;	/* Reserved */
 	unsigned protocol		:2;	/* Protocol type */
+#endif
 };
 
 /*
  *	INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
  */
 typedef struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */
+	unsigned	device_type	:5;	/* Peripheral Device Type */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	device_type	:5;	/* Peripheral Device Type */
 	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */
+#endif
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	rmb		:1;	/* Removable Medium Bit */
+	unsigned	reserved1_6t0	:7;	/* Reserved */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	reserved1_6t0	:7;	/* Reserved */
 	unsigned	rmb		:1;	/* Removable Medium Bit */
+#endif
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	iso_version	:2;	/* ISO Version */
+	unsigned	ecma_version	:3;	/* ECMA Version */
+	unsigned	ansi_version	:3;	/* ANSI Version */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	ansi_version	:3;	/* ANSI Version */
 	unsigned	ecma_version	:3;	/* ECMA Version */
 	unsigned	iso_version	:2;	/* ISO Version */
+#endif
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	reserved3_7	:1;	/* AENC - Reserved */
+	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
+	unsigned	reserved3_45	:2;	/* Reserved */
+	unsigned	response_format :4;	/* Response Data Format */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	response_format :4;	/* Response Data Format */
 	unsigned	reserved3_45	:2;	/* Reserved */
 	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
 	unsigned	reserved3_7	:1;	/* AENC - Reserved */
+#endif
 	u8		additional_length;	/* Additional Length (total_length-4) */
 	u8		rsv5, rsv6, rsv7;	/* Reserved */
 	u8		vendor_id[8];		/* Vendor Identification */
@@ -928,11 +1056,19 @@
  *	READ POSITION packet command - Data Format (From Table 6-57)
  */
 typedef struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	bop		:1;	/* Beginning Of Partition */
+	unsigned	eop		:1;	/* End Of Partition */
+	unsigned	reserved0_543	:3;	/* Reserved */
+	unsigned	bpu		:1;	/* Block Position Unknown */	
+	unsigned	reserved0_10	:2;	/* Reserved */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	reserved0_10	:2;	/* Reserved */
 	unsigned	bpu		:1;	/* Block Position Unknown */	
 	unsigned	reserved0_543	:3;	/* Reserved */
 	unsigned	eop		:1;	/* End Of Partition */
 	unsigned	bop		:1;	/* Beginning Of Partition */
+#endif
 	u8		partition;		/* Partition Number */
 	u8		reserved2, reserved3;	/* Reserved */
 	u32		first_block;		/* First Block Location */
@@ -946,22 +1082,41 @@
  *	REQUEST SENSE packet command result - Data Format.
  */
 typedef struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	valid		:1;	/* The information field conforms to QIC-157C */
+	unsigned	error_code	:7;	/* Current of deferred errors */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	error_code	:7;	/* Current of deferred errors */
 	unsigned	valid		:1;	/* The information field conforms to QIC-157C */
+#endif
+
 	u8		reserved1	:8;	/* Segment Number - Reserved */
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	filemark 	:1;	/* Filemark */
+	unsigned	eom		:1;	/* End Of Medium */
+	unsigned	ili		:1;	/* Incorrect Length Indicator */
+	unsigned	reserved2_4	:1;	/* Reserved */
+	unsigned	sense_key	:4;	/* Sense Key */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	sense_key	:4;	/* Sense Key */
 	unsigned	reserved2_4	:1;	/* Reserved */
 	unsigned	ili		:1;	/* Incorrect Length Indicator */
 	unsigned	eom		:1;	/* End Of Medium */
 	unsigned	filemark 	:1;	/* Filemark */
+#endif
 	u32		information __attribute__ ((packed));
 	u8		asl;			/* Additional sense length (n-7) */
 	u32		command_specific;	/* Additional command specific information */
 	u8		asc;			/* Additional Sense Code */
 	u8		ascq;			/* Additional Sense Code Qualifier */
 	u8		replaceable_unit_code;	/* Field Replaceable Unit Code */
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	sksv		:1;	/* Sense Key Specific information is valid */
+	unsigned	sk_specific1 	:7;	/* Sense Key Specific */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	sk_specific1 	:7;	/* Sense Key Specific */
 	unsigned	sksv		:1;	/* Sense Key Specific information is valid */
+#endif
 	u8		sk_specific2;		/* Sense Key Specific */
 	u8		sk_specific3;		/* Sense Key Specific */
 	u8		pad[2];			/* Padding to 20 bytes */
@@ -1000,16 +1155,35 @@
  *	The Data Compression Page, as returned by the MODE SENSE packet command.
  */
 typedef struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	ps		:1;
+	unsigned	reserved0	:1;	/* Reserved */
+	unsigned	page_code	:6;	/* Page Code - Should be 0xf */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	page_code	:6;	/* Page Code - Should be 0xf */
 	unsigned	reserved0	:1;	/* Reserved */
 	unsigned	ps		:1;
+#endif
 	u8		page_length;		/* Page Length - Should be 14 */
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	dce		:1;	/* Data Compression Enable */
+	unsigned	dcc		:1;	/* Data Compression Capable */
+	unsigned	reserved2	:6;	/* Reserved */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	reserved2	:6;	/* Reserved */
 	unsigned	dcc		:1;	/* Data Compression Capable */
 	unsigned	dce		:1;	/* Data Compression Enable */
+#endif
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	dde		:1;	/* Data Decompression Enable */
+	unsigned	red		:2;	/* Report Exception on Decompression */
+	unsigned	reserved3	:5;	/* Reserved */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	reserved3	:5;	/* Reserved */
 	unsigned	red		:2;	/* Report Exception on Decompression */
 	unsigned	dde		:1;	/* Data Decompression Enable */
+#endif
 	u32		ca;			/* Compression Algorithm */
 	u32		da;			/* Decompression Algorithm */
 	u8		reserved[4];		/* Reserved */
@@ -1019,17 +1193,31 @@
  *	The Medium Partition Page, as returned by the MODE SENSE packet command.
  */
 typedef struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	ps		:1;
+	unsigned	reserved1_6	:1;	/* Reserved */
+	unsigned	page_code	:6;	/* Page Code - Should be 0x11 */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	page_code	:6;	/* Page Code - Should be 0x11 */
 	unsigned	reserved1_6	:1;	/* Reserved */
 	unsigned	ps		:1;
+#endif
 	u8		page_length;		/* Page Length - Should be 6 */
 	u8		map;			/* Maximum Additional Partitions - Should be 0 */
 	u8		apd;			/* Additional Partitions Defined - Should be 0 */
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned	fdp		:1;	/* Fixed Data Partitions */
+	unsigned	sdp		:1;	/* Should be 0 */
+	unsigned	idp		:1;	/* Should be 0 */
+	unsigned	psum		:2;	/* Should be 0 */
+	unsigned	reserved4_012	:3;	/* Reserved */
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
 	unsigned	reserved4_012	:3;	/* Reserved */
 	unsigned	psum		:2;	/* Should be 0 */
 	unsigned	idp		:1;	/* Should be 0 */
 	unsigned	sdp		:1;	/* Should be 0 */
 	unsigned	fdp		:1;	/* Fixed Data Partitions */
+#endif
 	u8		mfr;			/* Medium Format Recognition */
 	u8		reserved[2];		/* Reserved */
 } idetape_medium_partition_page_t;
diff -urN linux-2.2.14-pre6/drivers/macintosh/mediabay.c linux-2.2.14-pre7/drivers/macintosh/mediabay.c
--- linux-2.2.14-pre6/drivers/macintosh/mediabay.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/macintosh/mediabay.c	2003-08-15 15:09:04.000000000 -0700
@@ -433,14 +433,13 @@
 			   in the middle of a wait loop */
 			if (bay->reset_timer)
 				bay->reset_timer = MB_RESET_COUNT;
+#ifdef CONFIG_BLK_DEV_IDE
 			if (bay->cd_timer)
 				bay->cd_timer = MB_IDE_WAIT;
+#endif
 		}
 		break;
 	}
 	return PBOOK_SLEEP_OK;
 }
 #endif /* CONFIG_PMAC_PBOOK */
-
-
-
diff -urN linux-2.2.14-pre6/drivers/macintosh/via-pmu.c linux-2.2.14-pre7/drivers/macintosh/via-pmu.c
--- linux-2.2.14-pre6/drivers/macintosh/via-pmu.c	1999-08-25 17:29:48.000000000 -0700
+++ linux-2.2.14-pre7/drivers/macintosh/via-pmu.c	2003-08-15 15:09:04.000000000 -0700
@@ -1126,11 +1126,6 @@
 		macio_base = (unsigned long)
 			ioremap(macio->addrs[0].address, 0x40);
 
-	/* Sync the disks. */
-	/* XXX It would be nice to have some way to ensure that
-	 * nobody is dirtying any new buffers while we wait. */
-	fsync_dev(0);
-
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, 1);
 	if (ret != PBOOK_SLEEP_OK) {
@@ -1138,6 +1133,15 @@
 		printk("pmu: sleep rejected\n");
 		return -EBUSY;
 	}
+
+	/* Sync the disks. */
+	/* XXX It would be nice to have some way to ensure that
+	 * nobody is dirtying any new buffers while we wait.
+	 * BenH: Moved to _after_ sleep request and changed video
+	 * drivers to vmalloc() during sleep request. This way, all
+	 * vmalloc's are done before actual sleep of block drivers */
+	fsync_dev(0);
+
 	broadcast_sleep(PBOOK_SLEEP_NOW, 0);
 
 	/* Give the disks a little time to actually finish writing */
@@ -1190,6 +1194,10 @@
 	pmcr1 &= ~(GRACKLE_PM|GRACKLE_DOZE|GRACKLE_SLEEP|GRACKLE_NAP); 
 	grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1);
 
+	/* Make sure the PMU is idle */
+	while (pmu_state != idle)
+		pmu_poll();
+
 	sti();
 #if 0
 	/* According to someone from Apple, this should not be needed,
@@ -1201,7 +1209,7 @@
 
 	/* Restore L2 cache */
 	if (save_l2cr)
-		_set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
+ 		_set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
 	
 	/* reenable interrupts */
 	sleep_restore_intrs();
@@ -1222,11 +1230,6 @@
 	unsigned long p, wait;
 	struct adb_request sleep_req;
 
-	/* Sync the disks. */
-	/* XXX It would be nice to have some way to ensure that
-	 * nobody is dirtying any new buffers while we wait. */
-	fsync_dev(0);
-
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, 1);
 	if (ret != PBOOK_SLEEP_OK) {
@@ -1234,6 +1237,15 @@
 		printk("pmu: sleep rejected\n");
 		return -EBUSY;
 	}
+
+	/* Sync the disks. */
+	/* XXX It would be nice to have some way to ensure that
+	 * nobody is dirtying any new buffers while we wait.
+	 * BenH: Moved to _after_ sleep request and changed video
+	 * drivers to vmalloc() during sleep request. This way, all
+	 * vmalloc's are done before actual sleep of block drivers */
+	fsync_dev(0);
+
 	broadcast_sleep(PBOOK_SLEEP_NOW, 0);
 
 	/* Give the disks a little time to actually finish writing */
diff -urN linux-2.2.14-pre6/drivers/net/arcnet.c linux-2.2.14-pre7/drivers/net/arcnet.c
--- linux-2.2.14-pre6/drivers/net/arcnet.c	1999-10-19 17:14:01.000000000 -0700
+++ linux-2.2.14-pre7/drivers/net/arcnet.c	2003-08-15 15:09:04.000000000 -0700
@@ -469,7 +469,7 @@
   register_netdevice(lp->edev);
 #endif
 
-#ifdef CONFIG_ARCNET_1051
+#if defined(CONFIG_ARCNET_1051) && defined(CONFIG_ARCNET_ETH)
   /* Initialize the RFC1051-encap protocol driver */
   lp->sdev=(struct device *)kmalloc(sizeof(struct device)+10,GFP_KERNEL);
   if(lp->sdev == NULL)
diff -urN linux-2.2.14-pre6/drivers/net/arlan.c linux-2.2.14-pre7/drivers/net/arlan.c
--- linux-2.2.14-pre6/drivers/net/arlan.c	1999-08-09 12:04:39.000000000 -0700
+++ linux-2.2.14-pre7/drivers/net/arlan.c	2003-08-15 15:09:04.000000000 -0700
@@ -101,7 +101,7 @@
 static  void 	arlan_tx_done_interrupt		(struct device * dev, int status);
 static  void	arlan_rx_interrupt		(struct device * dev, u_char rxStatus, u_short, u_short);
 static  void	arlan_process_interrupt		(struct device * dev);
-static  int	arlan_command(struct device * dev, int command);
+int	arlan_command(struct device * dev, int command);
 
 EXPORT_SYMBOL(arlan_command);
 
@@ -190,7 +190,7 @@
 };
 
 
-static int arlan_command(struct device *dev, int command_p)
+int arlan_command(struct device *dev, int command_p)
 {
 
 	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
diff -urN linux-2.2.14-pre6/drivers/net/comx.c linux-2.2.14-pre7/drivers/net/comx.c
--- linux-2.2.14-pre6/drivers/net/comx.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/net/comx.c	2003-08-15 15:09:04.000000000 -0700
@@ -1,4 +1,4 @@
-/*
+/* 
  * Device driver framework for the COMX line of synchronous serial boards
  * 
  * for Linux kernel 2.2.X
@@ -56,6 +56,10 @@
 #include <linux/kmod.h>
 #endif
 
+#ifndef CONFIG_PROC_FS
+#error For now, COMX really needs the /proc filesystem
+#endif
+
 #include "comx.h"
 #include "syncppp.h"
 
diff -urN linux-2.2.14-pre6/drivers/net/Config.in linux-2.2.14-pre7/drivers/net/Config.in
--- linux-2.2.14-pre6/drivers/net/Config.in	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/net/Config.in	2003-08-15 15:09:04.000000000 -0700
@@ -237,7 +237,7 @@
 
 bool 'Fibre Channel driver support' CONFIG_NET_FC
 if [ "$CONFIG_NET_FC" = "y" ]; then
-  tristate 'Interphase 5526 Tachyon chipset based adaptor support' CONFIG_IPHASE5526
+  dep_tristate 'Interphase 5526 Tachyon chipset based adaptor support' CONFIG_IPHASE5526 $CONFIG_SCSI
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -268,19 +268,22 @@
 #
 # COMX drivers
 #
+
 tristate 'MultiGate (COMX) synchronous serial boards support' CONFIG_COMX
-if [ "$CONFIG_COMX" != "n" ]; then
-    dep_tristate '  Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX
-    dep_tristate '  Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX
-    dep_tristate '  Support for MixCOM board' CONFIG_COMX_HW_MIXCOM $CONFIG_COMX
-    dep_tristate '  Support for HDLC and syncPPP protocols on MultiGate boards' CONFIG_COMX_PROTO_PPP $CONFIG_COMX
-    if [ "$CONFIG_LAPB" = "y" ]; then
-        dep_tristate '  Support for LAPB protocol on MultiGate boards' CONFIG_COMX_PROTO_LAPB $CONFIG_COMX
-    fi
-    if [ "$CONFIG_LAPB" = "m" ]; then
-        dep_tristate '  Support for LAPB protocol on MultiGate boards' CONFIG_COMX_PROTO_LAPB $CONFIG_LAPB
-    fi
-    dep_tristate '  Support for Frame Relay on MultiGate boards' CONFIG_COMX_PROTO_FR $CONFIG_COMX
+   if [ "$CONFIG_COMX" != "n" ]; then
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      dep_tristate '  Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX
+   fi
+   dep_tristate '  Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX
+   dep_tristate '  Support for MixCOM board' CONFIG_COMX_HW_MIXCOM $CONFIG_COMX
+   dep_tristate '  Support for HDLC and syncPPP protocols on MultiGate boards' CONFIG_COMX_PROTO_PPP $CONFIG_COMX
+   if [ "$CONFIG_LAPB" = "y" ]; then
+      dep_tristate '  Support for LAPB protocol on MultiGate boards' CONFIG_COMX_PROTO_LAPB $CONFIG_COMX
+   fi
+   if [ "$CONFIG_LAPB" = "m" ]; then
+      dep_tristate '  Support for LAPB protocol on MultiGate boards' CONFIG_COMX_PROTO_LAPB $CONFIG_LAPB
+   fi
+   dep_tristate '  Support for Frame Relay on MultiGate boards' CONFIG_COMX_PROTO_FR $CONFIG_COMX
 fi
 
 tristate 'Frame relay DLCI support' CONFIG_DLCI
diff -urN linux-2.2.14-pre6/drivers/net/hamradio/yam.c linux-2.2.14-pre7/drivers/net/hamradio/yam.c
--- linux-2.2.14-pre6/drivers/net/hamradio/yam.c	1999-08-09 12:04:39.000000000 -0700
+++ linux-2.2.14-pre7/drivers/net/hamradio/yam.c	2003-08-15 15:09:04.000000000 -0700
@@ -894,10 +894,12 @@
 }
 
 #ifdef CONFIG_INET
+
 #ifndef PROC_NET_YAM
 #define PROC_NET_YAM (PROC_NET_LAST+10)		/* Sorry again... */
 #endif
 
+#ifdef CONFIG_PROC_FS
 struct proc_dir_entry yam_proc_dir_entry =
 {
 	PROC_NET_YAM, 3, "yam", S_IFREG | S_IRUGO, 1, 0, 0, 0,
@@ -910,6 +912,10 @@
 #define yam_net_procfs_init()
 #define yam_net_procfs_remove()
 #endif
+#else
+#define yam_net_procfs_init()
+#define yam_net_procfs_remove()
+#endif
 
 /* --------------------------------------------------------------------- */
 
diff -urN linux-2.2.14-pre6/drivers/net/sdla.c linux-2.2.14-pre7/drivers/net/sdla.c
--- linux-2.2.14-pre6/drivers/net/sdla.c	1998-12-29 11:32:06.000000000 -0800
+++ linux-2.2.14-pre7/drivers/net/sdla.c	2003-08-15 15:09:04.000000000 -0700
@@ -1666,7 +1666,7 @@
 	return(0);
 }
 
-__initfunc(void sdla_setup(void))
+__initfunc(void sdla_c_setup(void))
 {
 	printk("%s.\n", version);
 	register_frad(devname);
@@ -1679,7 +1679,7 @@
 {
 	int result;
 
-	sdla_setup();
+	sdla_c_setup();
 	if ((result = register_netdev(&sdla0)) != 0)
 		return result;
 	return 0;
diff -urN linux-2.2.14-pre6/drivers/net/slhc.c linux-2.2.14-pre7/drivers/net/slhc.c
--- linux-2.2.14-pre6/drivers/net/slhc.c	1998-12-18 09:40:56.000000000 -0800
+++ linux-2.2.14-pre7/drivers/net/slhc.c	2003-08-15 15:09:04.000000000 -0700
@@ -760,12 +760,6 @@
 
 #endif /* MODULE */
 #else /* CONFIG_INET */
-EXPORT_SYMBOL(slhc_init);
-EXPORT_SYMBOL(slhc_free);
-EXPORT_SYMBOL(slhc_remember);
-EXPORT_SYMBOL(slhc_compress);
-EXPORT_SYMBOL(slhc_uncompress);
-EXPORT_SYMBOL(slhc_toss);
 
 int
 slhc_toss(struct slcompress *comp)
@@ -806,5 +800,11 @@
   printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init");
   return NULL;
 }
+EXPORT_SYMBOL(slhc_init);
+EXPORT_SYMBOL(slhc_free);
+EXPORT_SYMBOL(slhc_remember);
+EXPORT_SYMBOL(slhc_compress);
+EXPORT_SYMBOL(slhc_uncompress);
+EXPORT_SYMBOL(slhc_toss);
 
 #endif /* CONFIG_INET */
diff -urN linux-2.2.14-pre6/drivers/scsi/mesh.c linux-2.2.14-pre7/drivers/scsi/mesh.c
--- linux-2.2.14-pre6/drivers/scsi/mesh.c	1999-10-19 17:14:01.000000000 -0700
+++ linux-2.2.14-pre7/drivers/scsi/mesh.c	2003-08-15 15:09:04.000000000 -0700
@@ -29,6 +29,10 @@
 #include <asm/processor.h>
 #include <asm/spinlock.h>
 #include <asm/feature.h>
+#ifdef CONFIG_PMAC_PBOOK
+#include <asm/adb.h>
+#include <asm/pmu.h>
+#endif
 
 #include "scsi.h"
 #include "hosts.h"
@@ -154,6 +158,8 @@
 	struct dbdma_cmd *dma_cmds;	/* space for dbdma commands, aligned */
 	int	clk_freq;
 	struct mesh_target tgts[8];
+	struct device_node *dnode;
+	unsigned char *mio_base;
 #ifndef MESH_NEW_STYLE_EH
 	Scsi_Cmnd *completed_q;
 	Scsi_Cmnd *completed_qtail;
@@ -166,6 +172,14 @@
 #endif
 };
 
+#ifdef CONFIG_PMAC_PBOOK
+static int mesh_notify_sleep(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier mesh_sleep_notifier = {
+	mesh_notify_sleep,
+	SLEEP_LEVEL_BLOCK,
+};
+#endif
+
 #ifdef MESH_DBG
 
 static void dlog(struct mesh_state *ms, char *fmt, int a);
@@ -213,6 +227,7 @@
 static void halt_dma(struct mesh_state *);
 static int data_goes_out(Scsi_Cmnd *);
 static void do_abort(struct mesh_state *ms);
+static void set_mesh_power(struct mesh_state *ms, int state);
 
 static struct notifier_block mesh_notifier = {
 	mesh_notify_reboot,
@@ -247,6 +262,7 @@
 	if (mesh == 0)
 		mesh = find_compatible_devices("scsi", "chrp,mesh0");
 	for (; mesh != 0; mesh = mesh->next) {
+		struct device_node *mio;
 		if (mesh->n_addrs != 2 || mesh->n_intrs != 2) {
 			printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs"
 			       " (got %d,%d)", mesh->n_addrs, mesh->n_intrs);
@@ -267,6 +283,7 @@
 			panic("no mesh state");
 		memset(ms, 0, sizeof(*ms));
 		ms->host = mesh_host;
+		ms->dnode = mesh;
 		ms->mesh = (volatile struct mesh_regs *)
 			ioremap(mesh->addrs[0].address, 0x1000);
 		ms->dma = (volatile struct dbdma_regs *)
@@ -310,9 +327,16 @@
 		if (mesh_sync_period < minper)
 			mesh_sync_period = minper;
 
-		feature_set(mesh, FEATURE_MESH_enable);
-		mdelay(200);
+		ms->mio_base = 0;
+		for (mio = ms->dnode->parent; mio; mio = mio->parent)
+			if (strcmp(mio->name, "mac-io") == 0
+			    && mio->n_addrs > 0)
+				break;
+		if (mio)
+			ms->mio_base = (unsigned char *)
+				ioremap(mio->addrs[0].address, 0x40);
 
+		set_mesh_power(ms, 1);
 		mesh_init(ms);
 
 		if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) {
@@ -322,12 +346,74 @@
 		++nmeshes;
 	}
 
-	if ((_machine == _MACH_Pmac) && (nmeshes > 0))
-		register_reboot_notifier(&mesh_notifier);
+	if ((_machine == _MACH_Pmac) && (nmeshes > 0)) {
+#ifdef CONFIG_PMAC_PBOOK
+		pmu_register_sleep_notifier(&mesh_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+ 		register_reboot_notifier(&mesh_notifier);
+	}		
 
 	return nmeshes;
 }
 
+static void
+set_mesh_power(struct mesh_state *ms, int state)
+{
+	if (_machine != _MACH_Pmac || ms->mio_base == 0)
+		return;
+		
+	if (state) {
+		feature_set(ms->dnode, FEATURE_MESH_enable);
+		/* This seems to enable the termination power. strangely
+		   this doesn't fully agree with OF, but with MacOS */
+		if (ms->mio_base)
+			out_8(ms->mio_base + 0x36, 0x70);
+		mdelay(200);
+	} else {
+		feature_clear(ms->dnode, FEATURE_MESH_enable);
+		if (ms->mio_base)
+			out_8(ms->mio_base + 0x36, 0x34);
+		mdelay(10);
+	}
+}			
+
+#ifdef CONFIG_PMAC_PBOOK
+/*
+ * notify clients before sleep and reset bus afterwards
+ */
+int
+mesh_notify_sleep(struct pmu_sleep_notifier *self, int when)
+{
+	struct mesh_state *ms;
+	
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		/* XXX We should wait for current transactions and queue
+		 * new ones that would be posted beyond this point 
+		 */ 
+		break;
+	case PBOOK_SLEEP_REJECT:
+		break;
+		
+	case PBOOK_SLEEP_NOW:
+		for (ms = all_meshes; ms != 0; ms = ms->next) {
+			disable_irq(ms->meshintr);
+			set_mesh_power(ms, 0);
+		}
+		break;
+	case PBOOK_WAKE:
+		for (ms = all_meshes; ms != 0; ms = ms->next) {
+			set_mesh_power(ms, 1);
+			mesh_init(ms);
+			enable_irq(ms->meshintr);
+		}
+		break;
+	}
+	return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PMAC_PBOOK */
+ 
+
 int
 mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
diff -urN linux-2.2.14-pre6/drivers/scsi/ncr53c8xx.c linux-2.2.14-pre7/drivers/scsi/ncr53c8xx.c
--- linux-2.2.14-pre6/drivers/scsi/ncr53c8xx.c	1999-10-19 17:14:01.000000000 -0700
+++ linux-2.2.14-pre7/drivers/scsi/ncr53c8xx.c	2003-08-15 15:09:04.000000000 -0700
@@ -1763,6 +1763,8 @@
 	*/
 	u_short		device_id;	/* PCI device id		*/
 	u_char		revision_id;	/* PCI device revision id	*/
+	u_char		pci_bus;	/* PCI bus number		*/
+	u_char		pci_devfn;	/* PCI device and function	*/
 	u_long		port;		/* IO space base address	*/
 	u_int		irq;		/* IRQ level			*/
 	u_int		features;	/* Chip features map		*/
@@ -4393,6 +4395,8 @@
 	sprintf(np->inst_name, "ncr53c%s-%d", np->chip_name, np->unit);
 	np->device_id	= device->chip.device_id;
 	np->revision_id	= device->chip.revision_id;
+	np->pci_bus	= device->slot.bus;
+	np->pci_devfn	= device->slot.device_fn;
 	np->features	= device->chip.features;
 	np->clock_divn	= device->chip.nr_divisor;
 	np->maxoffs	= device->chip.offset_max;
@@ -10088,7 +10092,15 @@
 */
 const char *ncr53c8xx_info (struct Scsi_Host *host)
 {
+#ifdef __sparc__
+	/* Ok to do this on all archs? */
+	static char buffer[80];
+	ncb_p np = ((struct host_data *) host->hostdata)->ncb;
+	sprintf (buffer, "%s\nPCI bus %02x device %02x", SCSI_NCR_DRIVER_NAME, np->pci_bus, np->pci_devfn);
+	return buffer;
+#else
 	return SCSI_NCR_DRIVER_NAME;
+#endif
 }
 
 /*
@@ -10673,6 +10685,8 @@
 	copy_info(&info, "  IO port address 0x%lx, ", (u_long) np->port);
 #ifdef __sparc__
 	copy_info(&info, "IRQ number %s\n", __irq_itoa(np->irq));
+	/* Ok to do this on all archs? */
+	copy_info(&info, "PCI bus %02x device %02x\n", np->pci_bus, np->pci_devfn);
 #else
 	copy_info(&info, "IRQ number %d\n", (int) np->irq);
 #endif
diff -urN linux-2.2.14-pre6/drivers/scsi/sym53c8xx.c linux-2.2.14-pre7/drivers/scsi/sym53c8xx.c
--- linux-2.2.14-pre6/drivers/scsi/sym53c8xx.c	1999-10-19 17:14:01.000000000 -0700
+++ linux-2.2.14-pre7/drivers/scsi/sym53c8xx.c	2003-08-15 15:09:04.000000000 -0700
@@ -300,7 +300,7 @@
 **
 **==========================================================
 */
-#if	!defined(__i386__)
+#if	!defined(__i386__) && !defined(__sparc__)
 #define	SCSI_NCR_PCI_MEM_NOT_SUPPORTED
 #endif
 
@@ -586,10 +586,11 @@
 #endif
 
 #ifdef __sparc__
+#  include <asm/irq.h>
 #  define ioremap(base, size)		((u_long) __va(base))
 #  define iounmap(vaddr)
 #  define pcivtobus(p)			((p) & pci_dvma_mask)
-#  define memcpy_to_pci(a, b, c)	memcpy_toio((u_long) (a), (b), (c))
+#  define memcpy_to_pci(a, b, c)	memcpy_toio((void *) (a), (b), (c))
 #elif defined(__alpha__)
 #  define pcivtobus(p)			((p) & 0xfffffffful)
 #  define memcpy_to_pci(a, b, c)	memcpy_toio((a), (b), (c))
@@ -1819,6 +1820,8 @@
 	*/
 	u_short		device_id;	/* PCI device id		*/
 	u_char		revision_id;	/* PCI device revision id	*/
+	u_char		pci_bus;	/* PCI bus number		*/
+	u_char		pci_devfn;	/* PCI device and function	*/
 	u_int		features;	/* Chip features map		*/
 	u_char		myaddr;		/* SCSI id of the adapter	*/
 	u_char		maxburst;	/* log base 2 of dwords burst	*/
@@ -4550,6 +4553,8 @@
 	sprintf(np->inst_name, NAME53C "%s-%d", np->chip_name, np->unit);
 	np->device_id	= device->chip.device_id;
 	np->revision_id	= device->chip.revision_id;
+	np->pci_bus	= device->slot.bus;
+	np->pci_devfn	= device->slot.device_fn;
 	np->features	= device->chip.features;
 	np->clock_divn	= device->chip.nr_divisor;
 	np->maxoffs	= device->chip.offset_max;
@@ -9476,6 +9481,8 @@
 	if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
 		unsigned f2;
 
+		OUTB(nc_istat, SRST); UDELAY (5); OUTB(nc_istat, 0);
+
 		(void) ncrgetfreq (np, 11);	/* throw away first result */
 		f1 = ncrgetfreq (np, 11);
 		f2 = ncrgetfreq (np, 11);
@@ -10261,6 +10268,8 @@
 	if (!cache_line_size)
 		suggested_cache_line_size = 16;
 
+	driver_setup.pci_fix_up |= 0x7;
+
 #endif	/* __sparc__ */
 
 #if defined(__i386__) && !defined(MODULE)
@@ -10574,7 +10583,15 @@
 */
 const char *sym53c8xx_info (struct Scsi_Host *host)
 {
+#ifdef __sparc__
+	/* Ok to do this on all archs? */
+	static char buffer[80];
+	ncb_p np = ((struct host_data *) host->hostdata)->ncb;
+	sprintf (buffer, "%s\nPCI bus %02x device %02x", SCSI_NCR_DRIVER_NAME, np->pci_bus, np->pci_devfn);
+	return buffer;
+#else
 	return SCSI_NCR_DRIVER_NAME;
+#endif
 }
 
 /*
@@ -11159,7 +11176,13 @@
 	copy_info(&info, "revision id 0x%x\n",	np->revision_id);
 
 	copy_info(&info, "  IO port address 0x%lx, ", (u_long) np->base_io);
+#ifdef __sparc__
+	copy_info(&info, "IRQ number %s\n", __irq_itoa(np->irq));
+	/* Ok to do this on all archs? */
+	copy_info(&info, "PCI bus %02x device %02x\n", np->pci_bus, np->pci_devfn);
+#else
 	copy_info(&info, "IRQ number %d\n", (int) np->irq);
+#endif
 
 #ifndef NCR_IOMAPPED
 	if (np->reg)
diff -urN linux-2.2.14-pre6/drivers/sound/dmasound.c linux-2.2.14-pre7/drivers/sound/dmasound.c
--- linux-2.2.14-pre6/drivers/sound/dmasound.c	1999-08-25 17:29:48.000000000 -0700
+++ linux-2.2.14-pre7/drivers/sound/dmasound.c	2003-08-15 15:09:04.000000000 -0700
@@ -3171,7 +3171,7 @@
 		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
 		out_le32(&awacs->control,
 			 (in_le32(&awacs->control) & ~0x1f00)
-			 || (awacs_rate_index << 8));
+			 | (awacs_rate_index << 8));
 		out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
 		beep_playing = 0;
 	}
@@ -3259,6 +3259,11 @@
 	save_flags(flags); cli();
 	if (beep_playing) {
 		st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
+		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+		out_le32(&awacs->control,
+			 (in_le32(&awacs->control) & ~0x1f00)
+			 | (awacs_rate_index << 8));
+		out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
 		beep_playing = 0;
 	}
 	restore_flags(flags);
diff -urN linux-2.2.14-pre6/drivers/sound/lowlevel/miroaci.h linux-2.2.14-pre7/drivers/sound/lowlevel/miroaci.h
--- linux-2.2.14-pre6/drivers/sound/lowlevel/miroaci.h	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/sound/lowlevel/miroaci.h	2003-08-15 15:09:04.000000000 -0700
@@ -1,4 +1,4 @@
-#if defined(CONFIG_ACI_MIXER) || defined(CONFIG_ACI_MIXER_MODULE)
+#if defined(CONFIG_ACI_MIXER) || (defined(CONFIG_ACI_MIXER_MODULE) && defined(MODULE))
 extern int aci_implied_cmd(unsigned char opcode);
 extern int aci_write_cmd(unsigned char opcode, unsigned char parameter);
 extern int aci_write_cmd_d(unsigned char opcode, unsigned char parameter, unsigned char parameter2);
diff -urN linux-2.2.14-pre6/drivers/sound/sb_audio.c linux-2.2.14-pre7/drivers/sound/sb_audio.c
--- linux-2.2.14-pre6/drivers/sound/sb_audio.c	1999-01-14 22:59:47.000000000 -0800
+++ linux-2.2.14-pre7/drivers/sound/sb_audio.c	2003-08-15 15:09:04.000000000 -0700
@@ -460,7 +460,7 @@
 			speed = 44100;
 		if (devc->opened & OPEN_READ && speed > 15000)
 			speed = 15000;
-		devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
+		devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
 		tmp = 256 - devc->tconst;
 		speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
 
@@ -591,7 +591,7 @@
 		if (speed > 44100)
 			speed = 44100;
 
-		devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
+		devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
 
 		tmp = 256 - devc->tconst;
 		speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
diff -urN linux-2.2.14-pre6/drivers/video/atyfb.c linux-2.2.14-pre7/drivers/video/atyfb.c
--- linux-2.2.14-pre6/drivers/video/atyfb.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/drivers/video/atyfb.c	2003-08-15 15:09:04.000000000 -0700
@@ -89,7 +89,6 @@
  */
 #undef DEBUG
 
-
 #define GUI_RESERVE	0x00001000
 
 
@@ -3935,47 +3934,65 @@
 {
 	struct fb_info_aty *info;
  	unsigned int pm;
- 	
+
 	for (info = first_display; info != NULL; info = info->next) {
 		struct fb_fix_screeninfo fix;
 		int nb;
-		
+
 		atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
 		nb = fb_display[fg_console].var.yres * fix.line_length;
 
 		switch (when) {
+		case PBOOK_SLEEP_REQUEST:
+			info->save_framebuffer = vmalloc(nb);
+			break;
+		case PBOOK_SLEEP_REJECT:
+			if (info->save_framebuffer) {
+				vfree(info->save_framebuffer);
+				info->save_framebuffer = 0;
+			}
+			break;
 		case PBOOK_SLEEP_NOW:
+			if (info->blitter_may_be_busy)
+				wait_for_idle(info);
 			/* Stop accel engine (stop bus mastering) */
 			if (info->current_par.accel_flags & FB_ACCELF_TEXT)
 				reset_engine(info);
-#if 1
+
 			/* Backup fb content */	
-			info->save_framebuffer = vmalloc(nb);
 			if (info->save_framebuffer)
 				memcpy(info->save_framebuffer,
 				       (void *)info->frame_buffer, nb);
-#endif
-			/* Blank display and LCD */				       
-			atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);			
-			
-			/* Set chip to "suspend" mode. Note: There's an HW bug in the
-			   chip which prevents proper resync on wakeup with automatic
-			   power management, we handle suspend manually using the
-			   following (weird) sequence described by ATI. Note2:
+
+			/* Blank display and LCD */
+			atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
+
+			/* Set chip to "suspend" mode. Note: There's a HW bug
+			   in the chip which prevents proper resync on wakeup
+			   with automatic power management, we handle suspend
+			   manually using the following (weird) sequence
+			   described by ATI.
+			   Note2:
 			   We could enable this for all Rage LT Pro chip ids */
-			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID) || (Gx == LP_CHIP_ID)) {
+			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID)
+			    || (Gx == LP_CHIP_ID)) {
 				pm = aty_ld_le32(POWER_MANAGEMENT, info);
 				pm &= ~PWR_MGT_ON;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				pm = aty_ld_le32(POWER_MANAGEMENT, info);
+				mdelay(1);
 				pm &= ~(PWR_BLON | AUTO_PWR_UP);
 				pm |= SUSPEND_NOW;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				pm = aty_ld_le32(POWER_MANAGEMENT, info);
+				mdelay(1);
 				pm |= PWR_MGT_ON;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				do {
 					pm = aty_ld_le32(POWER_MANAGEMENT, info);
+					/* Fix a problem with revision 4c50 of the chip */
+					if (Gx == LP_CHIP_ID)
+						break;
 				} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
 				mdelay(500);
 			}
@@ -3987,18 +4004,23 @@
 				pm &= ~PWR_MGT_ON;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				pm = aty_ld_le32(POWER_MANAGEMENT, info);
+				mdelay(1);
 				pm |=  (PWR_BLON | AUTO_PWR_UP);
 				pm &= ~SUSPEND_NOW;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				pm = aty_ld_le32(POWER_MANAGEMENT, info);
+				mdelay(1);
 				pm |= PWR_MGT_ON;
 				aty_st_le32(POWER_MANAGEMENT, pm, info);
 				do {
 					pm = aty_ld_le32(POWER_MANAGEMENT, info);
+					/* Fix a problem with revision 4c50 of the chip */
+					if (Gx == LP_CHIP_ID)
+						break;
 				} while ((pm & PWR_MGT_STATUS_MASK) != 0);
 				mdelay(500);
 			}
-#if 1
+
 			/* Restore fb content */			
 			if (info->save_framebuffer) {
 				memcpy((void *)info->frame_buffer,
@@ -4006,7 +4028,7 @@
 				vfree(info->save_framebuffer);
 				info->save_framebuffer = 0;
 			}
-#endif
+
 			/* Restore display */			
 			atyfb_set_par(&info->current_par, info);
 			atyfbcon_blank(0, (struct fb_info *)info);
diff -urN linux-2.2.14-pre6/drivers/video/chipsfb.c linux-2.2.14-pre7/drivers/video/chipsfb.c
--- linux-2.2.14-pre6/drivers/video/chipsfb.c	1999-10-19 17:14:01.000000000 -0700
+++ linux-2.2.14-pre7/drivers/video/chipsfb.c	2003-08-15 15:09:04.000000000 -0700
@@ -726,9 +726,18 @@
 		int nb = p->var.yres * p->fix.line_length;
 
 		switch (when) {
+		case PBOOK_SLEEP_REQUEST:
+			p->save_framebuffer = vmalloc(nb);
+			break;
+		case PBOOK_SLEEP_REJECT:
+			if (p->save_framebuffer) {
+				vfree(p->save_framebuffer);
+				p->save_framebuffer = 0;
+			}
+			break;
+
 		case PBOOK_SLEEP_NOW:
 			chipsfb_blank(1, (struct fb_info *)p);
-			p->save_framebuffer = vmalloc(nb);
 			if (p->save_framebuffer)
 				memcpy(p->save_framebuffer,
 				       p->frame_buffer, nb);
diff -urN linux-2.2.14-pre6/drivers/video/vga16fb.c linux-2.2.14-pre7/drivers/video/vga16fb.c
--- linux-2.2.14-pre6/drivers/video/vga16fb.c	1999-08-09 12:04:40.000000000 -0700
+++ linux-2.2.14-pre7/drivers/video/vga16fb.c	2003-08-15 15:09:04.000000000 -0700
@@ -295,10 +295,14 @@
 	display->can_soft_blank = 1;
 	display->inverse = 0;
 
+#ifdef CONFIG_FBCON_VGA_PLANES
 	if (info->isVGA)
 		display->dispsw = &fbcon_vga_planes;
-	else
+	else	
 		display->dispsw = &fbcon_ega_planes;
+#else
+		display->dispsw = &fbcon_dummy;
+#endif	
 	display->scrollmode = SCROLL_YREDRAW;
 }
 
diff -urN linux-2.2.14-pre6/include/math-emu/double.h linux-2.2.14-pre7/include/math-emu/double.h
--- linux-2.2.14-pre6/include/math-emu/double.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/double.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,197 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Double Precision
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_D		(2 * _FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_D		_FP_W_TYPE_SIZE
+#endif
+
+#define _FP_FRACBITS_D		53
+#define _FP_FRACXBITS_D		(_FP_FRACTBITS_D - _FP_FRACBITS_D)
+#define _FP_WFRACBITS_D		(_FP_WORKBITS + _FP_FRACBITS_D)
+#define _FP_WFRACXBITS_D	(_FP_FRACTBITS_D - _FP_WFRACBITS_D)
+#define _FP_EXPBITS_D		11
+#define _FP_EXPBIAS_D		1023
+#define _FP_EXPMAX_D		2047
+
+#define _FP_QNANBIT_D		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_D		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_D		\
+	((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_D
+{
+  double flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+#else
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned sign  : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)		_FP_DECL(2,X)
+#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_2(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val)	_FP_UNPACK_RAW_2_P(D,X,val)
+#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_2(D,val,X)
+#define FP_PACK_RAW_DP(val,X)		\
+  do {					\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_2_P(D,val,X);	\
+  } while (0)
+
+#define FP_UNPACK_D(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_2(D,X,val);		\
+    _FP_UNPACK_CANONICAL(D,2,X);	\
+  } while (0)
+
+#define FP_UNPACK_DP(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_2_P(D,X,val);	\
+    _FP_UNPACK_CANONICAL(D,2,X);	\
+  } while (0)
+
+#define FP_PACK_D(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,2,X);		\
+    _FP_PACK_RAW_2(D,val,X);		\
+  } while (0)
+
+#define FP_PACK_DP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,2,X);		\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_2_P(D,val,X);	\
+  } while (0)
+
+#define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,2,X)
+#define FP_NEG_D(R,X)			_FP_NEG(D,2,R,X)
+#define FP_ADD_D(R,X,Y)			_FP_ADD(D,2,R,X,Y)
+#define FP_SUB_D(R,X,Y)			_FP_SUB(D,2,R,X,Y)
+#define FP_MUL_D(R,X,Y)			_FP_MUL(D,2,R,X,Y)
+#define FP_DIV_D(R,X,Y)			_FP_DIV(D,2,R,X,Y)
+#define FP_SQRT_D(R,X)			_FP_SQRT(D,2,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q)	_FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,2,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,2,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_D(X)	_FP_FRAC_HIGH_2(X)
+
+#else
+
+union _FP_UNION_D
+{
+  double flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+#else
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)		_FP_DECL(1,X)
+#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_1(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val)	_FP_UNPACK_RAW_1_P(D,X,val)
+#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_1(D,val,X)
+#define FP_PACK_RAW_DP(val,X)		\
+  do {					\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_1_P(D,val,X);	\
+  } while (0)
+
+#define FP_UNPACK_D(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1(D,X,val);		\
+    _FP_UNPACK_CANONICAL(D,1,X);	\
+  } while (0)
+
+#define FP_UNPACK_DP(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1_P(D,X,val);	\
+    _FP_UNPACK_CANONICAL(D,1,X);	\
+  } while (0)
+
+#define FP_PACK_D(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,1,X);		\
+    _FP_PACK_RAW_1(D,val,X);		\
+  } while (0)
+
+#define FP_PACK_DP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(D,1,X);		\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_1_P(D,val,X);	\
+  } while (0)
+
+#define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,1,X)
+#define FP_NEG_D(R,X)			_FP_NEG(D,1,R,X)
+#define FP_ADD_D(R,X,Y)			_FP_ADD(D,1,R,X,Y)
+#define FP_SUB_D(R,X,Y)			_FP_SUB(D,1,R,X,Y)
+#define FP_MUL_D(R,X,Y)			_FP_MUL(D,1,R,X,Y)
+#define FP_DIV_D(R,X,Y)			_FP_DIV(D,1,R,X,Y)
+#define FP_SQRT_D(R,X)			_FP_SQRT(D,1,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q)	_FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
+   the target machine.  */
+
+#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,1,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,1,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_D(X)	_FP_FRAC_HIGH_1(X)
+
+#endif /* W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/include/math-emu/extended.h linux-2.2.14-pre7/include/math-emu/extended.h
--- linux-2.2.14-pre6/include/math-emu/extended.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/extended.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,388 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Extended Precision.
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_E         (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_E		(2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_E		64
+#define _FP_FRACXBITS_E		(_FP_FRACTBITS_E - _FP_FRACBITS_E)
+#define _FP_WFRACBITS_E		(_FP_WORKBITS + _FP_FRACBITS_E)
+#define _FP_WFRACXBITS_E	(_FP_FRACTBITS_E - _FP_WFRACBITS_E)
+#define _FP_EXPBITS_E		15
+#define _FP_EXPBIAS_E		16383
+#define _FP_EXPMAX_E		32767
+
+#define _FP_QNANBIT_E		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_E		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_E		\
+	((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_E
+{
+   long double flt;
+   struct 
+   {
+#if __BYTE_ORDER == __BIG_ENDIAN
+      unsigned long pad1 : _FP_W_TYPE_SIZE;
+      unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+      unsigned long sign : 1;
+      unsigned long exp : _FP_EXPBITS_E;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned exp : _FP_EXPBITS_E;
+      unsigned sign : 1;
+#endif /* not bigendian */
+   } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_E(X)		_FP_DECL(4,X)
+
+#define FP_UNPACK_RAW_E(X, val)				\
+  do {							\
+    union _FP_UNION_E _flo; _flo.flt = (val);		\
+							\
+    X##_f[2] = 0; X##_f[3] = 0;				\
+    X##_f[0] = _flo.bits.frac0;				\
+    X##_f[1] = _flo.bits.frac1;				\
+    X##_e  = _flo.bits.exp;				\
+    X##_s  = _flo.bits.sign;				\
+    if (!X##_e && (X##_f[1] || X##_f[0])		\
+        && !(X##_f[1] & _FP_IMPLBIT_E))			\
+      {							\
+        X##_e++;					\
+        FP_SET_EXCEPTION(FP_EX_DENORM);			\
+      }							\
+  } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val)			\
+  do {							\
+    union _FP_UNION_E *_flo =				\
+    (union _FP_UNION_E *)(val);				\
+							\
+    X##_f[2] = 0; X##_f[3] = 0;				\
+    X##_f[0] = _flo->bits.frac0;			\
+    X##_f[1] = _flo->bits.frac1;			\
+    X##_e  = _flo->bits.exp;				\
+    X##_s  = _flo->bits.sign;				\
+    if (!X##_e && (X##_f[1] || X##_f[0])		\
+        && !(X##_f[1] & _FP_IMPLBIT_E))			\
+      {							\
+        X##_e++;					\
+        FP_SET_EXCEPTION(FP_EX_DENORM);			\
+      }							\
+  } while (0)
+
+#define FP_PACK_RAW_E(val, X)				\
+  do {							\
+    union _FP_UNION_E _flo;				\
+							\
+    if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;		\
+    else X##_f[1] &= ~(_FP_IMPLBIT_E);			\
+    _flo.bits.frac0 = X##_f[0];				\
+    _flo.bits.frac1 = X##_f[1];				\
+    _flo.bits.exp   = X##_e;				\
+    _flo.bits.sign  = X##_s;				\
+							\
+    (val) = _flo.flt;					\
+  } while (0)
+
+#define FP_PACK_RAW_EP(val, X)				\
+  do {							\
+    if (!FP_INHIBIT_RESULTS)				\
+      {							\
+	union _FP_UNION_E *_flo =			\
+	  (union _FP_UNION_E *)(val);			\
+							\
+	if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;		\
+	else X##_f[1] &= ~(_FP_IMPLBIT_E);		\
+	_flo->bits.frac0 = X##_f[0];			\
+	_flo->bits.frac1 = X##_f[1];			\
+	_flo->bits.exp   = X##_e;			\
+	_flo->bits.sign  = X##_s;			\
+      }							\
+  } while (0)
+
+#define FP_UNPACK_E(X,val)		\
+  do {					\
+    FP_UNPACK_RAW_E(X,val);		\
+    _FP_UNPACK_CANONICAL(E,4,X);	\
+  } while (0)
+
+#define FP_UNPACK_EP(X,val)		\
+  do {					\
+    FP_UNPACK_RAW_2_P(X,val);		\
+    _FP_UNPACK_CANONICAL(E,4,X);	\
+  } while (0)
+
+#define FP_PACK_E(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(E,4,X);		\
+    FP_PACK_RAW_E(val,X);		\
+  } while (0)
+
+#define FP_PACK_EP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(E,4,X);		\
+    FP_PACK_RAW_EP(val,X);		\
+  } while (0)
+
+#define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN(E,4,X)
+#define FP_NEG_E(R,X)		_FP_NEG(E,4,R,X)
+#define FP_ADD_E(R,X,Y)		_FP_ADD(E,4,R,X,Y)
+#define FP_SUB_E(R,X,Y)		_FP_SUB(E,4,R,X,Y)
+#define FP_MUL_E(R,X,Y)		_FP_MUL(E,4,R,X,Y)
+#define FP_DIV_E(R,X,Y)		_FP_DIV(E,4,R,X,Y)
+#define FP_SQRT_E(R,X)		_FP_SQRT(E,4,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * This has special _E version because standard _4 square
+ * root would not work (it has to start normally with the
+ * second word and not the first), but as we have to do it
+ * anyway, we optimize it by doing most of the calculations
+ * in two UWtype registers instead of four.
+ */
+ 
+#define _FP_SQRT_MEAT_E(R, S, T, X, q)			\
+  do {							\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
+    _FP_FRAC_SRL_4(X, (_FP_WORKBITS));			\
+    while (q)						\
+      {							\
+	T##_f[1] = S##_f[1] + q;			\
+	if (T##_f[1] <= X##_f[1])			\
+	  {						\
+	    S##_f[1] = T##_f[1] + q;			\
+	    X##_f[1] -= T##_f[1];			\
+	    R##_f[1] += q;				\
+	  }						\
+	_FP_FRAC_SLL_2(X, 1);				\
+	q >>= 1;					\
+      }							\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
+    while (q)						\
+      {							\
+	T##_f[0] = S##_f[0] + q;			\
+	T##_f[1] = S##_f[1];				\
+	if (T##_f[1] < X##_f[1] || 			\
+	    (T##_f[1] == X##_f[1] &&			\
+	     T##_f[0] <= X##_f[0]))			\
+	  {						\
+	    S##_f[0] = T##_f[0] + q;			\
+	    S##_f[1] += (T##_f[0] > S##_f[0]);		\
+	    _FP_FRAC_DEC_2(X, T);			\
+	    R##_f[0] += q;				\
+	  }						\
+	_FP_FRAC_SLL_2(X, 1);				\
+	q >>= 1;					\
+      }							\
+    _FP_FRAC_SLL_4(R, (_FP_WORKBITS));			\
+    if (X##_f[0] | X##_f[1])				\
+      {							\
+	if (S##_f[1] < X##_f[1] || 			\
+	    (S##_f[1] == X##_f[1] &&			\
+	     S##_f[0] < X##_f[0]))			\
+	  R##_f[0] |= _FP_WORK_ROUND;			\
+	R##_f[0] |= _FP_WORK_STICKY;			\
+      }							\
+  } while (0)
+
+#define FP_CMP_E(r,X,Y,un)	_FP_CMP(E,4,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y)	_FP_CMP_EQ(E,4,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg)	_FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt)	_FP_FROM_INT(E,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X)	(X##_f[2])
+#define _FP_FRAC_HIGH_RAW_E(X)	(X##_f[1])
+
+#else   /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_E
+{
+  long double flt /* __attribute__((mode(TF))) */ ;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_E;
+    unsigned long frac : _FP_W_TYPE_SIZE;
+#else
+    unsigned long frac : _FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_E;
+    unsigned sign  : 1;
+#endif
+  } bits;
+};
+
+#define FP_DECL_E(X)		_FP_DECL(2,X)
+
+#define FP_UNPACK_RAW_E(X, val)					\
+  do {								\
+    union _FP_UNION_E _flo; _flo.flt = (val);			\
+								\
+    X##_f0 = _flo.bits.frac;					\
+    X##_f1 = 0;							\
+    X##_e = _flo.bits.exp;					\
+    X##_s = _flo.bits.sign;					\
+    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))		\
+      {								\
+        X##_e++;						\
+        FP_SET_EXCEPTION(FP_EX_DENORM);				\
+      }								\
+  } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val)				\
+  do {								\
+    union _FP_UNION_E *_flo =					\
+      (union _FP_UNION_E *)(val);				\
+								\
+    X##_f0 = _flo->bits.frac;					\
+    X##_f1 = 0;							\
+    X##_e = _flo->bits.exp;					\
+    X##_s = _flo->bits.sign;					\
+    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))		\
+      {								\
+        X##_e++;						\
+        FP_SET_EXCEPTION(FP_EX_DENORM);				\
+      }								\
+  } while (0)
+
+#define FP_PACK_RAW_E(val, X)					\
+  do {								\
+    union _FP_UNION_E _flo;					\
+								\
+    if (X##_e) X##_f0 |= _FP_IMPLBIT_E;				\
+    else X##_f0 &= ~(_FP_IMPLBIT_E);				\
+    _flo.bits.frac = X##_f0;					\
+    _flo.bits.exp  = X##_e;					\
+    _flo.bits.sign = X##_s;					\
+								\
+    (val) = _flo.flt;						\
+  } while (0)
+
+#define FP_PACK_RAW_EP(fs, val, X)				\
+  do {								\
+    if (!FP_INHIBIT_RESULTS)					\
+      {								\
+	union _FP_UNION_E *_flo =				\
+	  (union _FP_UNION_E *)(val);				\
+								\
+	if (X##_e) X##_f0 |= _FP_IMPLBIT_E;			\
+	else X##_f0 &= ~(_FP_IMPLBIT_E);			\
+	_flo->bits.frac = X##_f0;				\
+	_flo->bits.exp  = X##_e;				\
+	_flo->bits.sign = X##_s;				\
+      }								\
+  } while (0)
+
+
+#define FP_UNPACK_E(X,val)		\
+  do {					\
+    FP_UNPACK_RAW_E(X,val);		\
+    _FP_UNPACK_CANONICAL(E,2,X);	\
+  } while (0)
+
+#define FP_UNPACK_EP(X,val)		\
+  do {					\
+    FP_UNPACK_RAW_EP(X,val);		\
+    _FP_UNPACK_CANONICAL(E,2,X);	\
+  } while (0)
+
+#define FP_PACK_E(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(E,2,X);		\
+    FP_PACK_RAW_E(val,X);		\
+  } while (0)
+
+#define FP_PACK_EP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(E,2,X);		\
+    FP_PACK_RAW_EP(val,X);		\
+  } while (0)
+
+#define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN(E,2,X)
+#define FP_NEG_E(R,X)		_FP_NEG(E,2,R,X)
+#define FP_ADD_E(R,X,Y)		_FP_ADD(E,2,R,X,Y)
+#define FP_SUB_E(R,X,Y)		_FP_SUB(E,2,R,X,Y)
+#define FP_MUL_E(R,X,Y)		_FP_MUL(E,2,R,X,Y)
+#define FP_DIV_E(R,X,Y)		_FP_DIV(E,2,R,X,Y)
+#define FP_SQRT_E(R,X)		_FP_SQRT(E,2,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * We optimize it by doing most of the calculations
+ * in one UWtype registers instead of two, although we don't
+ * have to.
+ */
+#define _FP_SQRT_MEAT_E(R, S, T, X, q)			\
+  do {							\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
+    _FP_FRAC_SRL_2(X, (_FP_WORKBITS));			\
+    while (q)						\
+      {							\
+        T##_f0 = S##_f0 + q;				\
+        if (T##_f0 <= X##_f0)				\
+          {						\
+            S##_f0 = T##_f0 + q;			\
+            X##_f0 -= T##_f0;				\
+            R##_f0 += q;				\
+          }						\
+        _FP_FRAC_SLL_1(X, 1);				\
+        q >>= 1;					\
+      }							\
+    _FP_FRAC_SLL_2(R, (_FP_WORKBITS));			\
+    if (X##_f0)						\
+      {							\
+	if (S##_f0 < X##_f0)				\
+	  R##_f0 |= _FP_WORK_ROUND;			\
+	R##_f0 |= _FP_WORK_STICKY;			\
+      }							\
+  } while (0)
+ 
+#define FP_CMP_E(r,X,Y,un)	_FP_CMP(E,2,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y)	_FP_CMP_EQ(E,2,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg)	_FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt)	_FP_FROM_INT(E,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X)	(X##_f1)
+#define _FP_FRAC_HIGH_RAW_E(X)	(X##_f0)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/include/math-emu/op-1.h linux-2.2.14-pre7/include/math-emu/op-1.h
--- linux-2.2.14-pre6/include/math-emu/op-1.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/op-1.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,297 @@
+/* Software floating-point emulation.
+   Basic one-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
+#define _FP_FRAC_COPY_1(D,S)	(D##_f = S##_f)
+#define _FP_FRAC_SET_1(X,I)	(X##_f = I)
+#define _FP_FRAC_HIGH_1(X)	(X##_f)
+#define _FP_FRAC_LOW_1(X)	(X##_f)
+#define _FP_FRAC_WORD_1(X,w)	(X##_f)
+
+#define _FP_FRAC_ADDI_1(X,I)	(X##_f += I)
+#define _FP_FRAC_SLL_1(X,N)			\
+  do {						\
+    if (__builtin_constant_p(N) && (N) == 1)	\
+      X##_f += X##_f;				\
+    else					\
+      X##_f <<= (N);				\
+  } while (0)
+#define _FP_FRAC_SRL_1(X,N)	(X##_f >>= N)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRS_1(X,N,sz)	__FP_FRAC_SRS_1(X##_f, N, sz)
+
+#define __FP_FRAC_SRS_1(X,N,sz)						\
+   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1		\
+		     ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
+
+#define _FP_FRAC_ADD_1(R,X,Y)	(R##_f = X##_f + Y##_f)
+#define _FP_FRAC_SUB_1(R,X,Y)	(R##_f = X##_f - Y##_f)
+#define _FP_FRAC_DEC_1(X,Y)	(X##_f -= Y##_f)
+#define _FP_FRAC_CLZ_1(z, X)	__FP_CLZ(z, X##_f)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
+#define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
+#define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
+#define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
+#define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
+
+#define _FP_ZEROFRAC_1		0
+#define _FP_MINFRAC_1		1
+#define _FP_MAXFRAC_1		(~(_FP_WS_TYPE)0)
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_1(fs, X, val)				\
+  do {								\
+    union _FP_UNION_##fs _flo; _flo.flt = (val);		\
+								\
+    X##_f = _flo.bits.frac;					\
+    X##_e = _flo.bits.exp;					\
+    X##_s = _flo.bits.sign;					\
+  } while (0)
+
+#define _FP_UNPACK_RAW_1_P(fs, X, val)				\
+  do {								\
+    union _FP_UNION_##fs *_flo =				\
+      (union _FP_UNION_##fs *)(val);				\
+								\
+    X##_f = _flo->bits.frac;					\
+    X##_e = _flo->bits.exp;					\
+    X##_s = _flo->bits.sign;					\
+  } while (0)
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_1(fs, val, X)				\
+  do {								\
+    union _FP_UNION_##fs _flo;					\
+								\
+    _flo.bits.frac = X##_f;					\
+    _flo.bits.exp  = X##_e;					\
+    _flo.bits.sign = X##_s;					\
+								\
+    (val) = _flo.flt;						\
+  } while (0)
+
+#define _FP_PACK_RAW_1_P(fs, val, X)				\
+  do {								\
+    union _FP_UNION_##fs *_flo =				\
+      (union _FP_UNION_##fs *)(val);				\
+								\
+    _flo->bits.frac = X##_f;					\
+    _flo->bits.exp  = X##_e;					\
+    _flo->bits.sign = X##_s;					\
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   multiplication immediately.  */
+
+#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)				\
+  do {									\
+    R##_f = X##_f * Y##_f;						\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits);			\
+  } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)			\
+  do {									\
+    _FP_W_TYPE _Z_f0, _Z_f1;						\
+    doit(_Z_f1, _Z_f0, X##_f, Y##_f);					\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits);			\
+    R##_f = _Z_f0;							\
+  } while (0)
+
+/* Finally, a simple widening multiply algorithm.  What fun!  */
+
+#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)				\
+  do {									\
+    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;		\
+									\
+    /* split the words in half */					\
+    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);					\
+    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
+    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);					\
+    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
+									\
+    /* multiply the pieces */						\
+    _z_f0 = _xl * _yl;							\
+    _a_f0 = _xh * _yl;							\
+    _a_f1 = _xl * _yh;							\
+    _z_f1 = _xh * _yh;							\
+									\
+    /* reassemble into two full words */				\
+    if ((_a_f0 += _a_f1) < _a_f1)					\
+      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
+    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);				\
+    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);				\
+    _FP_FRAC_ADD_2(_z, _z, _a);						\
+									\
+    /* normalize */							\
+    _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits);			\
+    R##_f = _z_f0;							\
+  } while (0)
+
+
+/*
+ * Division algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   division immediately.  Give this macro either _FP_DIV_HELP_imm for
+   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
+   choose will depend on what the compiler does with divrem4.  */
+
+#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)		\
+  do {							\
+    _FP_W_TYPE _q, _r;					\
+    X##_f <<= (X##_f < Y##_f				\
+	       ? R##_e--, _FP_WFRACBITS_##fs		\
+	       : _FP_WFRACBITS_##fs - 1);		\
+    doit(_q, _r, X##_f, Y##_f);				\
+    R##_f = _q | (_r != 0);				\
+  } while (0)
+
+/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
+   that may be useful in this situation.  This first is for a primitive
+   that requires normalization, the second for one that does not.  Look
+   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
+
+#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)				\
+  do {									\
+    _FP_W_TYPE _nh, _nl, _q, _r;					\
+									\
+    /* Normalize Y -- i.e. make the most significant bit set.  */	\
+    Y##_f <<= _FP_WFRACXBITS_##fs - 1;					\
+									\
+    /* Shift X op correspondingly high, that is, up one full word.  */	\
+    if (X##_f <= Y##_f)							\
+      {									\
+	_nl = 0;							\
+	_nh = X##_f;							\
+      }									\
+    else								\
+      {									\
+	R##_e++;							\
+	_nl = X##_f << (_FP_W_TYPE_SIZE-1);				\
+	_nh = X##_f >> 1;						\
+      }									\
+    									\
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);				\
+    R##_f = _q | (_r != 0);						\
+  } while (0)
+
+#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)		\
+  do {							\
+    _FP_W_TYPE _nh, _nl, _q, _r;			\
+    if (X##_f < Y##_f)					\
+      {							\
+	R##_e--;					\
+	_nl = X##_f << _FP_WFRACBITS_##fs;		\
+	_nh = X##_f >> _FP_WFRACXBITS_##fs;		\
+      }							\
+    else						\
+      {							\
+	_nl = X##_f << (_FP_WFRACBITS_##fs - 1);	\
+	_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);	\
+      }							\
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);		\
+    R##_f = _q | (_r != 0);				\
+  } while (0)
+  
+  
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+ 
+#define _FP_SQRT_MEAT_1(R, S, T, X, q)			\
+  do {							\
+    while (q != _FP_WORK_ROUND)				\
+      {							\
+        T##_f = S##_f + q;				\
+        if (T##_f <= X##_f)				\
+          {						\
+            S##_f = T##_f + q;				\
+            X##_f -= T##_f;				\
+            R##_f += q;					\
+          }						\
+        _FP_FRAC_SLL_1(X, 1);				\
+        q >>= 1;					\
+      }							\
+    if (X##_f)						\
+      {							\
+	if (S##_f < X##_f)				\
+	  R##_f |= _FP_WORK_ROUND;			\
+	R##_f |= _FP_WORK_STICKY;			\
+      }							\
+  } while (0)
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)	(r = X##_f)
+#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)	(X##_f = r)
+
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S)				\
+  do {									\
+    D##_f = S##_f;							\
+    if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs)			\
+      {									\
+	if (S##_c != FP_CLS_NAN)					\
+	  _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs),	\
+			 _FP_WFRACBITS_##sfs);				\
+	else								\
+	  _FP_FRAC_SRL_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs));	\
+      }									\
+    else								\
+      D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs;		\
+  } while (0)
diff -urN linux-2.2.14-pre6/include/math-emu/op-2.h linux-2.2.14-pre7/include/math-emu/op-2.h
--- linux-2.2.14-pre6/include/math-emu/op-2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/op-2.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,608 @@
+/* Software floating-point emulation.
+   Basic two-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define _FP_FRAC_DECL_2(X)	_FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_COPY_2(D,S)	(D##_f0 = S##_f0, D##_f1 = S##_f1)
+#define _FP_FRAC_SET_2(X,I)	__FP_FRAC_SET_2(X, I)
+#define _FP_FRAC_HIGH_2(X)	(X##_f1)
+#define _FP_FRAC_LOW_2(X)	(X##_f0)
+#define _FP_FRAC_WORD_2(X,w)	(X##_f##w)
+
+#define _FP_FRAC_SLL_2(X,N)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+	if (__builtin_constant_p(N) && (N) == 1) 			\
+	  {								\
+	    X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0);	\
+	    X##_f0 += X##_f0;						\
+	  }								\
+	else								\
+	  {								\
+	    X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N));	\
+	    X##_f0 <<= (N);						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);			\
+	X##_f0 = 0;							\
+      }									\
+  } while (0)
+
+#define _FP_FRAC_SRL_2(X,N)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+	X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N));	\
+	X##_f1 >>= (N);							\
+      }									\
+    else								\
+      {									\
+	X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);			\
+	X##_f1 = 0;							\
+      }									\
+  } while (0)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRS_2(X,N,sz)						\
+  do {									\
+    if ((N) < _FP_W_TYPE_SIZE)						\
+      {									\
+	X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) |	\
+		  (__builtin_constant_p(N) && (N) == 1			\
+		   ? X##_f0 & 1						\
+		   : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0));	\
+	X##_f1 >>= (N);							\
+      }									\
+    else								\
+      {									\
+	X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |			\
+		  (((X##_f1 << (sz - (N))) | X##_f0) != 0));		\
+	X##_f1 = 0;							\
+      }									\
+  } while (0)
+
+#define _FP_FRAC_ADDI_2(X,I)	\
+  __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
+
+#define _FP_FRAC_ADD_2(R,X,Y)	\
+  __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_SUB_2(R,X,Y)	\
+  __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_DEC_2(X,Y)	\
+  __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_CLZ_2(R,X)	\
+  do {				\
+    if (X##_f1)			\
+      __FP_CLZ(R,X##_f1);	\
+    else 			\
+    {				\
+      __FP_CLZ(R,X##_f0);	\
+      R += _FP_W_TYPE_SIZE;	\
+    }				\
+  } while(0)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_2(X)	((_FP_WS_TYPE)X##_f1 < 0)
+#define _FP_FRAC_ZEROP_2(X)	((X##_f1 | X##_f0) == 0)
+#define _FP_FRAC_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
+#define _FP_FRAC_GT_2(X, Y)	\
+  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 > Y##_f0)
+#define _FP_FRAC_GE_2(X, Y)	\
+  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)
+
+#define _FP_ZEROFRAC_2		0, 0
+#define _FP_MINFRAC_2		0, 1
+#define _FP_MAXFRAC_2		(~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_2(X,I1,I0)	(X##_f0 = I0, X##_f1 = I1)
+
+#define __FP_CLZ_2(R, xh, xl)	\
+  do {				\
+    if (xh)			\
+      __FP_CLZ(R,xh);		\
+    else 			\
+    {				\
+      __FP_CLZ(R,xl);		\
+      R += _FP_W_TYPE_SIZE;	\
+    }				\
+  } while(0)
+
+#if 0
+
+#ifndef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i)	\
+  (xh += ((xl += i) < i))
+#endif
+#ifndef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)	\
+  (rh = xh + yh + ((rl = xl + yl) < xl))
+#endif
+#ifndef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)	\
+  (rh = xh - yh - ((rl = xl - yl) > xl))
+#endif
+#ifndef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl)	\
+  do {					\
+    UWtype _t = xl;			\
+    xh -= yh + ((xl -= yl) > _t);	\
+  } while (0)
+#endif
+
+#else
+
+#undef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i)	add_ssaaaa(xh, xl, xh, xl, 0, i)
+#undef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2			add_ssaaaa
+#undef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2			sub_ddmmss
+#undef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl)	sub_ddmmss(xh, xl, xh, xl, yh, yl)
+
+#endif
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_2(fs, X, val)			\
+  do {							\
+    union _FP_UNION_##fs _flo; _flo.flt = (val);	\
+							\
+    X##_f0 = _flo.bits.frac0;				\
+    X##_f1 = _flo.bits.frac1;				\
+    X##_e  = _flo.bits.exp;				\
+    X##_s  = _flo.bits.sign;				\
+  } while (0)
+
+#define _FP_UNPACK_RAW_2_P(fs, X, val)			\
+  do {							\
+    union _FP_UNION_##fs *_flo =			\
+      (union _FP_UNION_##fs *)(val);			\
+							\
+    X##_f0 = _flo->bits.frac0;				\
+    X##_f1 = _flo->bits.frac1;				\
+    X##_e  = _flo->bits.exp;				\
+    X##_s  = _flo->bits.sign;				\
+  } while (0)
+
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_2(fs, val, X)			\
+  do {							\
+    union _FP_UNION_##fs _flo;				\
+							\
+    _flo.bits.frac0 = X##_f0;				\
+    _flo.bits.frac1 = X##_f1;				\
+    _flo.bits.exp   = X##_e;				\
+    _flo.bits.sign  = X##_s;				\
+							\
+    (val) = _flo.flt;					\
+  } while (0)
+
+#define _FP_PACK_RAW_2_P(fs, val, X)			\
+  do {							\
+    union _FP_UNION_##fs *_flo =			\
+      (union _FP_UNION_##fs *)(val);			\
+							\
+    _flo->bits.frac0 = X##_f0;				\
+    _flo->bits.frac1 = X##_f1;				\
+    _flo->bits.exp   = X##_e;				\
+    _flo->bits.sign  = X##_s;				\
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit)			\
+  do {									\
+    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	\
+									\
+    doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0);	\
+    doit(_b_f1, _b_f0, X##_f0, Y##_f1);					\
+    doit(_c_f1, _c_f0, X##_f1, Y##_f0);					\
+    doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1);	\
+									\
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0,		\
+		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1));				\
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0,		\
+		    _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1));				\
+									\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);			\
+    R##_f0 = _FP_FRAC_WORD_4(_z,0);					\
+    R##_f1 = _FP_FRAC_WORD_4(_z,1);					\
+  } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.
+   Do only 3 multiplications instead of four. This one is for machines
+   where multiplication is much more expensive than subtraction.  */
+
+#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit)		\
+  do {									\
+    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	\
+    _FP_W_TYPE _d;							\
+    int _c1, _c2;							\
+									\
+    _b_f0 = X##_f0 + X##_f1;						\
+    _c1 = _b_f0 < X##_f0;						\
+    _b_f1 = Y##_f0 + Y##_f1;						\
+    _c2 = _b_f1 < Y##_f0;						\
+    doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0);			\
+    doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1);	\
+    doit(_c_f1, _c_f0, X##_f1, Y##_f1);					\
+									\
+    _b_f0 &= -_c2;							\
+    _b_f1 &= -_c1;							\
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d,		\
+		    0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1));	\
+    __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		     _b_f0);						\
+    __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		     _b_f1);						\
+    __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1),				\
+		    0, _d, _FP_FRAC_WORD_4(_z,0));			\
+    __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),	\
+		    _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0);		\
+    __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2),	\
+		    _c_f1, _c_f0,					\
+		    _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2));	\
+									\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);			\
+    R##_f0 = _FP_FRAC_WORD_4(_z,0);					\
+    R##_f1 = _FP_FRAC_WORD_4(_z,1);					\
+  } while (0)
+
+#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y)				\
+  do {									\
+    _FP_FRAC_DECL_4(_z);						\
+    _FP_W_TYPE _x[2], _y[2];						\
+    _x[0] = X##_f0; _x[1] = X##_f1;					\
+    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
+									\
+    mpn_mul_n(_z_f, _x, _y, 2);						\
+									\
+    /* Normalize since we know where the msb of the multiplicands	\
+       were (bit B), we know that the msb of the of the product is	\
+       at either 2B or 2B-1.  */					\
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);			\
+    R##_f0 = _z_f[0];							\
+    R##_f1 = _z_f[1];							\
+  } while (0)
+
+/* Do at most 120x120=240 bits multiplication using double floating
+   point multiplication.  This is useful if floating point
+   multiplication has much bigger throughput than integer multiply.
+   It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits
+   between 106 and 120 only.  
+   Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set.
+   SETFETZ is a macro which will disable all FPU exceptions and set rounding
+   towards zero,  RESETFE should optionally reset it back.  */
+
+#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe)	\
+  do {										\
+    static const double _const[] = {						\
+      /* 2^-24 */ 5.9604644775390625e-08,					\
+      /* 2^-48 */ 3.5527136788005009e-15,					\
+      /* 2^-72 */ 2.1175823681357508e-22,					\
+      /* 2^-96 */ 1.2621774483536189e-29,					\
+      /* 2^28 */ 2.68435456e+08,						\
+      /* 2^4 */ 1.600000e+01,							\
+      /* 2^-20 */ 9.5367431640625e-07,						\
+      /* 2^-44 */ 5.6843418860808015e-14,					\
+      /* 2^-68 */ 3.3881317890172014e-21,					\
+      /* 2^-92 */ 2.0194839173657902e-28,					\
+      /* 2^-116 */ 1.2037062152420224e-35};					\
+    double _a240, _b240, _c240, _d240, _e240, _f240, 				\
+	   _g240, _h240, _i240, _j240, _k240;					\
+    union { double d; UDItype i; } _l240, _m240, _n240, _o240,			\
+				   _p240, _q240, _r240, _s240;			\
+    UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0;			\
+										\
+    if (wfracbits < 106 || wfracbits > 120)					\
+      abort();									\
+										\
+    setfetz;									\
+										\
+    _e240 = (double)(long)(X##_f0 & 0xffffff);					\
+    _j240 = (double)(long)(Y##_f0 & 0xffffff);					\
+    _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff);				\
+    _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff);				\
+    _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48));	\
+    _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48));	\
+    _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff);				\
+    _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff);				\
+    _a240 = (double)(long)(X##_f1 >> 32);					\
+    _f240 = (double)(long)(Y##_f1 >> 32);					\
+    _e240 *= _const[3];								\
+    _j240 *= _const[3];								\
+    _d240 *= _const[2];								\
+    _i240 *= _const[2];								\
+    _c240 *= _const[1];								\
+    _h240 *= _const[1];								\
+    _b240 *= _const[0];								\
+    _g240 *= _const[0];								\
+    _s240.d =							      _e240*_j240;\
+    _r240.d =						_d240*_j240 + _e240*_i240;\
+    _q240.d =				  _c240*_j240 + _d240*_i240 + _e240*_h240;\
+    _p240.d =		    _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\
+    _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\
+    _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240;		\
+    _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240;				\
+    _l240.d = _a240*_g240 + _b240*_f240;					\
+    _k240 =   _a240*_f240;							\
+    _r240.d += _s240.d;								\
+    _q240.d += _r240.d;								\
+    _p240.d += _q240.d;								\
+    _o240.d += _p240.d;								\
+    _n240.d += _o240.d;								\
+    _m240.d += _n240.d;								\
+    _l240.d += _m240.d;								\
+    _k240 += _l240.d;								\
+    _s240.d -= ((_const[10]+_s240.d)-_const[10]);				\
+    _r240.d -= ((_const[9]+_r240.d)-_const[9]);					\
+    _q240.d -= ((_const[8]+_q240.d)-_const[8]);					\
+    _p240.d -= ((_const[7]+_p240.d)-_const[7]);					\
+    _o240.d += _const[7];							\
+    _n240.d += _const[6];							\
+    _m240.d += _const[5];							\
+    _l240.d += _const[4];							\
+    if (_s240.d != 0.0) _y240 = 1;						\
+    if (_r240.d != 0.0) _y240 = 1;						\
+    if (_q240.d != 0.0) _y240 = 1;						\
+    if (_p240.d != 0.0) _y240 = 1;						\
+    _t240 = (DItype)_k240;							\
+    _u240 = _l240.i;								\
+    _v240 = _m240.i;								\
+    _w240 = _n240.i;								\
+    _x240 = _o240.i;								\
+    R##_f1 = (_t240 << (128 - (wfracbits - 1)))					\
+	     | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104));			\
+    R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1)))			\
+    	     | ((_v240 & 0xffffff) << (144 - (wfracbits - 1)))			\
+    	     | ((_w240 & 0xffffff) << (120 - (wfracbits - 1)))			\
+    	     | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96))			\
+    	     | _y240;								\
+    resetfe;									\
+  } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y)				\
+  do {									\
+    _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0;		\
+    if (_FP_FRAC_GT_2(X, Y))						\
+      {									\
+	_n_f2 = X##_f1 >> 1;						\
+	_n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1;		\
+	_n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1);			\
+      }									\
+    else								\
+      {									\
+	R##_e--;							\
+	_n_f2 = X##_f1;							\
+	_n_f1 = X##_f0;							\
+	_n_f0 = 0;							\
+      }									\
+									\
+    /* Normalize, i.e. make the most significant bit of the 		\
+       denominator set. */						\
+    _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs);				\
+									\
+    udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1);			\
+    umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0);				\
+    _r_f0 = _n_f0;							\
+    if (_FP_FRAC_GT_2(_m, _r))						\
+      {									\
+	R##_f1--;							\
+	_FP_FRAC_ADD_2(_r, Y, _r);					\
+	if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
+	  {								\
+	    R##_f1--;							\
+	    _FP_FRAC_ADD_2(_r, Y, _r);					\
+	  }								\
+      }									\
+    _FP_FRAC_DEC_2(_r, _m);						\
+									\
+    if (_r_f1 == Y##_f1)						\
+      {									\
+	/* This is a special case, not an optimization			\
+	   (_r/Y##_f1 would not fit into UWtype).			\
+	   As _r is guaranteed to be < Y,  R##_f0 can be either		\
+	   (UWtype)-1 or (UWtype)-2.  But as we know what kind		\
+	   of bits it is (sticky, guard, round),  we don't care.	\
+	   We also don't care what the reminder is,  because the	\
+	   guard bit will be set anyway.  -jj */			\
+	R##_f0 = -1;							\
+      }									\
+    else								\
+      {									\
+	udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1);		\
+	umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0);			\
+	_r_f0 = 0;							\
+	if (_FP_FRAC_GT_2(_m, _r))					\
+	  {								\
+	    R##_f0--;							\
+	    _FP_FRAC_ADD_2(_r, Y, _r);					\
+	    if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))		\
+	      {								\
+		R##_f0--;						\
+		_FP_FRAC_ADD_2(_r, Y, _r);				\
+	      }								\
+	  }								\
+	if (!_FP_FRAC_EQ_2(_r, _m))					\
+	  R##_f0 |= _FP_WORK_STICKY;					\
+      }									\
+  } while (0)
+
+
+#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y)					\
+  do {									\
+    _FP_W_TYPE _x[4], _y[2], _z[4];					\
+    _y[0] = Y##_f0; _y[1] = Y##_f1;					\
+    _x[0] = _x[3] = 0;							\
+    if (_FP_FRAC_GT_2(X, Y))						\
+      {									\
+	R##_e++;							\
+	_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) |	\
+		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
+			    (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE)));	\
+	_x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE);	\
+      }									\
+    else								\
+      {									\
+	_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) |	\
+		 X##_f1 >> (_FP_W_TYPE_SIZE -				\
+			    (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE)));	\
+	_x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE);	\
+      }									\
+									\
+    (void) mpn_divrem (_z, 0, _x, 4, _y, 2);				\
+    R##_f1 = _z[1];							\
+    R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0);				\
+  } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+ 
+#define _FP_SQRT_MEAT_2(R, S, T, X, q)			\
+  do {							\
+    while (q)						\
+      {							\
+	T##_f1 = S##_f1 + q;				\
+	if (T##_f1 <= X##_f1)				\
+	  {						\
+	    S##_f1 = T##_f1 + q;			\
+	    X##_f1 -= T##_f1;				\
+	    R##_f1 += q;				\
+	  }						\
+	_FP_FRAC_SLL_2(X, 1);				\
+	q >>= 1;					\
+      }							\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);		\
+    while (q != _FP_WORK_ROUND)				\
+      {							\
+	T##_f0 = S##_f0 + q;				\
+	T##_f1 = S##_f1;				\
+	if (T##_f1 < X##_f1 || 				\
+	    (T##_f1 == X##_f1 && T##_f0 <= X##_f0))	\
+	  {						\
+	    S##_f0 = T##_f0 + q;			\
+	    S##_f1 += (T##_f0 > S##_f0);		\
+	    _FP_FRAC_DEC_2(X, T);			\
+	    R##_f0 += q;				\
+	  }						\
+	_FP_FRAC_SLL_2(X, 1);				\
+	q >>= 1;					\
+      }							\
+    if (X##_f0 | X##_f1)				\
+      {							\
+	if (S##_f1 < X##_f1 || 				\
+	    (S##_f1 == X##_f1 && S##_f0 < X##_f0))	\
+	  R##_f0 |= _FP_WORK_ROUND;			\
+	R##_f0 |= _FP_WORK_STICKY;			\
+      }							\
+  } while (0)
+
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_2(r, X, rsize)	\
+  do {						\
+    if (rsize <= _FP_W_TYPE_SIZE)		\
+      r = X##_f0;				\
+    else					\
+      {						\
+	r = X##_f1;				\
+	r <<= _FP_W_TYPE_SIZE;			\
+	r += X##_f0;				\
+      }						\
+  } while (0)
+
+#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)				\
+  do {									\
+    X##_f0 = r;								\
+    X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);	\
+  } while (0)
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S)				\
+  do {									\
+    if (S##_c != FP_CLS_NAN)						\
+      _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),	\
+		     _FP_WFRACBITS_##sfs);				\
+    else								\
+      _FP_FRAC_SRL_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs));	\
+    D##_f = S##_f0;							\
+  } while (0)
+
+#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S)				\
+  do {									\
+    D##_f0 = S##_f;							\
+    D##_f1 = 0;								\
+    _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));	\
+  } while (0)
+
diff -urN linux-2.2.14-pre6/include/math-emu/op-4.h linux-2.2.14-pre7/include/math-emu/op-4.h
--- linux-2.2.14-pre6/include/math-emu/op-4.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/op-4.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,661 @@
+/* Software floating-point emulation.
+   Basic four-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define _FP_FRAC_DECL_4(X)	_FP_W_TYPE X##_f[4]
+#define _FP_FRAC_COPY_4(D,S)			\
+  (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1],	\
+   D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
+#define _FP_FRAC_SET_4(X,I)	__FP_FRAC_SET_4(X, I)
+#define _FP_FRAC_HIGH_4(X)	(X##_f[3])
+#define _FP_FRAC_LOW_4(X)	(X##_f[0])
+#define _FP_FRAC_WORD_4(X,w)	(X##_f[w])
+
+#define _FP_FRAC_SLL_4(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _up = (N) % _FP_W_TYPE_SIZE;					\
+    _down = _FP_W_TYPE_SIZE - _up;					\
+    if (!_up)								\
+      for (_i = 3; _i >= _skip; --_i)					\
+	X##_f[_i] = X##_f[_i-_skip];					\
+    else								\
+      {									\
+	for (_i = 3; _i > _skip; --_i)					\
+	  X##_f[_i] = X##_f[_i-_skip] << _up				\
+		      | X##_f[_i-_skip-1] >> _down;			\
+	X##_f[_i--] = X##_f[0] << _up; 					\
+      }									\
+    for (; _i >= 0; --_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+/* This one was broken too */
+#define _FP_FRAC_SRL_4(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    if (!_down)								\
+      for (_i = 0; _i <= 3-_skip; ++_i)					\
+	X##_f[_i] = X##_f[_i+_skip];					\
+    else								\
+      {									\
+	for (_i = 0; _i < 3-_skip; ++_i)				\
+	  X##_f[_i] = X##_f[_i+_skip] >> _down				\
+		      | X##_f[_i+_skip+1] << _up;			\
+	X##_f[_i++] = X##_f[3] >> _down;				\
+      }									\
+    for (; _i < 4; ++_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+
+/* Right shift with sticky-lsb. 
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRS_4(X,N,size)					\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _FP_W_TYPE _s;							\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    for (_s = _i = 0; _i < _skip; ++_i)					\
+      _s |= X##_f[_i];							\
+    _s |= X##_f[_i] << _up;						\
+/* s is now != 0 if we want to set the LSbit */				\
+    if (!_down)								\
+      for (_i = 0; _i <= 3-_skip; ++_i)					\
+	X##_f[_i] = X##_f[_i+_skip];					\
+    else								\
+      {									\
+	for (_i = 0; _i < 3-_skip; ++_i)				\
+	  X##_f[_i] = X##_f[_i+_skip] >> _down				\
+		      | X##_f[_i+_skip+1] << _up;			\
+	X##_f[_i++] = X##_f[3] >> _down;				\
+      }									\
+    for (; _i < 4; ++_i)						\
+      X##_f[_i] = 0;							\
+    /* don't fix the LSB until the very end when we're sure f[0] is stable */	\
+    X##_f[0] |= (_s != 0);						\
+  } while (0)
+
+#define _FP_FRAC_ADD_4(R,X,Y)						\
+  __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
+		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
+		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_SUB_4(R,X,Y)						\
+  __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],		\
+		  X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
+		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_DEC_4(X,Y)						\
+  __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0],		\
+		  Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_ADDI_4(X,I)						\
+  __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
+
+#define _FP_ZEROFRAC_4  0,0,0,0
+#define _FP_MINFRAC_4   0,0,0,1
+#define _FP_MAXFRAC_4	(~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+#define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
+#define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
+#define _FP_FRAC_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+
+#define _FP_FRAC_EQ_4(X,Y)				\
+ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]		\
+  && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
+
+#define _FP_FRAC_GT_4(X,Y)				\
+ (X##_f[3] > Y##_f[3] ||				\
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||	\
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||	\
+    (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0])	\
+   ))							\
+  ))							\
+ )
+
+#define _FP_FRAC_GE_4(X,Y)				\
+ (X##_f[3] > Y##_f[3] ||				\
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||	\
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||	\
+    (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0])	\
+   ))							\
+  ))							\
+ )
+
+
+#define _FP_FRAC_CLZ_4(R,X)		\
+  do {					\
+    if (X##_f[3])			\
+    {					\
+	__FP_CLZ(R,X##_f[3]);		\
+    }					\
+    else if (X##_f[2])			\
+    {					\
+	__FP_CLZ(R,X##_f[2]);		\
+	R += _FP_W_TYPE_SIZE;		\
+    }					\
+    else if (X##_f[1])			\
+    {					\
+	__FP_CLZ(R,X##_f[2]);		\
+	R += _FP_W_TYPE_SIZE*2;		\
+    }					\
+    else				\
+    {					\
+	__FP_CLZ(R,X##_f[0]);		\
+	R += _FP_W_TYPE_SIZE*3;		\
+    }					\
+  } while(0)
+
+
+#define _FP_UNPACK_RAW_4(fs, X, val)				\
+  do {								\
+    union _FP_UNION_##fs _flo; _flo.flt = (val);		\
+    X##_f[0] = _flo.bits.frac0;					\
+    X##_f[1] = _flo.bits.frac1;					\
+    X##_f[2] = _flo.bits.frac2;					\
+    X##_f[3] = _flo.bits.frac3;					\
+    X##_e  = _flo.bits.exp;					\
+    X##_s  = _flo.bits.sign;					\
+  } while (0)
+
+#define _FP_UNPACK_RAW_4_P(fs, X, val)				\
+  do {								\
+    union _FP_UNION_##fs *_flo =				\
+      (union _FP_UNION_##fs *)(val);				\
+								\
+    X##_f[0] = _flo->bits.frac0;				\
+    X##_f[1] = _flo->bits.frac1;				\
+    X##_f[2] = _flo->bits.frac2;				\
+    X##_f[3] = _flo->bits.frac3;				\
+    X##_e  = _flo->bits.exp;					\
+    X##_s  = _flo->bits.sign;					\
+  } while (0)
+
+#define _FP_PACK_RAW_4(fs, val, X)				\
+  do {								\
+    union _FP_UNION_##fs _flo;					\
+    _flo.bits.frac0 = X##_f[0];					\
+    _flo.bits.frac1 = X##_f[1];					\
+    _flo.bits.frac2 = X##_f[2];					\
+    _flo.bits.frac3 = X##_f[3];					\
+    _flo.bits.exp   = X##_e;					\
+    _flo.bits.sign  = X##_s;					\
+    (val) = _flo.flt;				   		\
+  } while (0)
+
+#define _FP_PACK_RAW_4_P(fs, val, X)				\
+  do {								\
+    union _FP_UNION_##fs *_flo =				\
+      (union _FP_UNION_##fs *)(val);				\
+								\
+    _flo->bits.frac0 = X##_f[0];				\
+    _flo->bits.frac1 = X##_f[1];				\
+    _flo->bits.frac2 = X##_f[2];				\
+    _flo->bits.frac3 = X##_f[3];				\
+    _flo->bits.exp   = X##_e;					\
+    _flo->bits.sign  = X##_s;					\
+  } while (0)
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit)			    \
+  do {									    \
+    _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	    \
+    _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f);	    \
+									    \
+    doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
+    doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]);				    \
+    doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]);				    \
+    doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]);				    \
+    doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]);				    \
+    doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]);				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
+		    _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0,		    \
+		    0,0,_FP_FRAC_WORD_8(_z,1));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
+		    _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
+		    _FP_FRAC_WORD_8(_z,1));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
+		    _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0,		    \
+		    0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
+		    _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0,		    \
+		    _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
+		    _FP_FRAC_WORD_8(_z,2));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
+		    _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0,		    \
+		    _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
+		    _FP_FRAC_WORD_8(_z,2));				    \
+    doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]);				    \
+    doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]);				    \
+    doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]);				    \
+    doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]);				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0,		    \
+		    0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0,		    \
+		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0,		    \
+		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
+		    _FP_FRAC_WORD_8(_z,3));				    \
+    doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]);				    \
+    doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]);				    \
+    doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]);				    \
+    doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]);				    \
+    doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]);				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
+		    _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0,		    \
+		    0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
+		    _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
+		    _FP_FRAC_WORD_8(_z,4));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
+		    _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0,		    \
+		    _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
+		    _FP_FRAC_WORD_8(_z,4));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
+		    _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0,		    \
+		    0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
+		    _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0,		    \
+		    _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
+		    _FP_FRAC_WORD_8(_z,5));				    \
+    doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]);				    \
+    __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
+		    _b_f1,_b_f0,					    \
+		    _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6));	    \
+									    \
+    /* Normalize since we know where the msb of the multiplicands	    \
+       were (bit B), we know that the msb of the of the product is	    \
+       at either 2B or 2B-1.  */					    \
+    _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits);			    \
+    __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2),	    \
+		    _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0));	    \
+  } while (0)
+
+#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y)				    \
+  do {									    \
+    _FP_FRAC_DECL_8(_z);						    \
+									    \
+    mpn_mul_n(_z_f, _x_f, _y_f, 4);					    \
+									    \
+    /* Normalize since we know where the msb of the multiplicands	    \
+       were (bit B), we know that the msb of the of the product is	    \
+       at either 2B or 2B-1.  */					    \
+    _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits);	 		    \
+    __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2),	    \
+		    _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0));	    \
+  } while (0)
+
+/*
+ * Helper utility for _FP_DIV_MEAT_4_udiv:
+ * pppp = m * nnn
+ */
+#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0)				    \
+  do {									    \
+    UWtype _t;								    \
+    umul_ppmm(p1,p0,m,n0);						    \
+    umul_ppmm(p2,_t,m,n1);						    \
+    __FP_FRAC_ADDI_2(p2,p1,_t);						    \
+    umul_ppmm(p3,_t,m,n2);						    \
+    __FP_FRAC_ADDI_2(p3,p2,_t);						    \
+  } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y)				    \
+  do {									    \
+    int _i;								    \
+    _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m);				    \
+    _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4);					    \
+    if (_FP_FRAC_GT_4(X, Y))						    \
+      {									    \
+	_n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1);			    \
+	_FP_FRAC_SRL_4(X, 1);						    \
+      }									    \
+    else								    \
+      R##_e--;								    \
+									    \
+    /* Normalize, i.e. make the most significant bit of the 		    \
+       denominator set. */						    \
+    _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs);				    \
+									    \
+    for (_i = 3; ; _i--)						    \
+      {									    \
+        if (X##_f[3] == Y##_f[3])					    \
+          {								    \
+            /* This is a special case, not an optimization		    \
+               (X##_f[3]/Y##_f[3] would not fit into UWtype).		    \
+               As X## is guaranteed to be < Y,  R##_f[_i] can be either	    \
+               (UWtype)-1 or (UWtype)-2.  */				    \
+            R##_f[_i] = -1;						    \
+            if (!_i)							    \
+	      break;							    \
+            __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0],	    \
+			    Y##_f[2], Y##_f[1], Y##_f[0], 0,		    \
+			    X##_f[2], X##_f[1], X##_f[0], _n_f[_i]);	    \
+            _FP_FRAC_SUB_4(X, Y, X);					    \
+            if (X##_f[3] > Y##_f[3])					    \
+              {								    \
+                R##_f[_i] = -2;						    \
+                _FP_FRAC_ADD_4(X, Y, X);				    \
+              }								    \
+          }								    \
+        else								    \
+          {								    \
+            udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]);  \
+            umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0],		    \
+			  R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]);	    \
+            X##_f[2] = X##_f[1];					    \
+            X##_f[1] = X##_f[0];					    \
+            X##_f[0] = _n_f[_i];					    \
+            if (_FP_FRAC_GT_4(_m, X))					    \
+              {								    \
+                R##_f[_i]--;						    \
+                _FP_FRAC_ADD_4(X, Y, X);				    \
+                if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X))	    \
+                  {							    \
+		    R##_f[_i]--;					    \
+		    _FP_FRAC_ADD_4(X, Y, X);				    \
+                  }							    \
+              }								    \
+            _FP_FRAC_DEC_4(X, _m);					    \
+            if (!_i)							    \
+	      {								    \
+		if (!_FP_FRAC_EQ_4(X, _m))				    \
+		  R##_f[0] |= _FP_WORK_STICKY;				    \
+		break;							    \
+	      }								    \
+          }								    \
+      }									    \
+  } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+ 
+#define _FP_SQRT_MEAT_4(R, S, T, X, q)				\
+  do {								\
+    while (q)							\
+      {								\
+	T##_f[3] = S##_f[3] + q;				\
+	if (T##_f[3] <= X##_f[3])				\
+	  {							\
+	    S##_f[3] = T##_f[3] + q;				\
+	    X##_f[3] -= T##_f[3];				\
+	    R##_f[3] += q;					\
+	  }							\
+	_FP_FRAC_SLL_4(X, 1);					\
+	q >>= 1;						\
+      }								\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);			\
+    while (q)							\
+      {								\
+	T##_f[2] = S##_f[2] + q;				\
+	T##_f[3] = S##_f[3];					\
+	if (T##_f[3] < X##_f[3] || 				\
+	    (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2]))	\
+	  {							\
+	    S##_f[2] = T##_f[2] + q;				\
+	    S##_f[3] += (T##_f[2] > S##_f[2]);			\
+	    __FP_FRAC_DEC_2(X##_f[3], X##_f[2],			\
+			    T##_f[3], T##_f[2]);		\
+	    R##_f[2] += q;					\
+	  }							\
+	_FP_FRAC_SLL_4(X, 1);					\
+	q >>= 1;						\
+      }								\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);			\
+    while (q)							\
+      {								\
+	T##_f[1] = S##_f[1] + q;				\
+	T##_f[2] = S##_f[2];					\
+	T##_f[3] = S##_f[3];					\
+	if (T##_f[3] < X##_f[3] || 				\
+	    (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] ||	\
+	     (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1]))))	\
+	  {							\
+	    S##_f[1] = T##_f[1] + q;				\
+	    S##_f[2] += (T##_f[1] > S##_f[1]);			\
+	    S##_f[3] += (T##_f[2] > S##_f[2]);			\
+	    __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1],	\
+	    		    T##_f[3], T##_f[2], T##_f[1]);	\
+	    R##_f[1] += q;					\
+	  }							\
+	_FP_FRAC_SLL_4(X, 1);					\
+	q >>= 1;						\
+      }								\
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);			\
+    while (q != _FP_WORK_ROUND)					\
+      {								\
+	T##_f[0] = S##_f[0] + q;				\
+	T##_f[1] = S##_f[1];					\
+	T##_f[2] = S##_f[2];					\
+	T##_f[3] = S##_f[3];					\
+	if (_FP_FRAC_GE_4(X,T))					\
+	  {							\
+	    S##_f[0] = T##_f[0] + q;				\
+	    S##_f[1] += (T##_f[0] > S##_f[0]);			\
+	    S##_f[2] += (T##_f[1] > S##_f[1]);			\
+	    S##_f[3] += (T##_f[2] > S##_f[2]);			\
+	    _FP_FRAC_DEC_4(X, T);				\
+	    R##_f[0] += q;					\
+	  }							\
+	_FP_FRAC_SLL_4(X, 1);					\
+	q >>= 1;						\
+      }								\
+    if (!_FP_FRAC_ZEROP_4(X))					\
+      {								\
+	if (_FP_FRAC_GT_4(X,S))					\
+	  R##_f[0] |= _FP_WORK_ROUND;				\
+	R##_f[0] |= _FP_WORK_STICKY;				\
+      }								\
+  } while (0)
+
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_4(X,I3,I2,I1,I0)					\
+  (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+
+#ifndef __FP_FRAC_ADD_3
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  (r0 = x0 + y0,							\
+   r1 = x1 + y1 + (r0 < x0),						\
+   r2 = x2 + y2 + (r1 < x1))
+#endif
+
+#ifndef __FP_FRAC_ADD_4
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  (r0 = x0 + y0,							\
+   r1 = x1 + y1 + (r0 < x0),						\
+   r2 = x2 + y2 + (r1 < x1),						\
+   r3 = x3 + y3 + (r2 < x2))
+#endif
+
+#ifndef __FP_FRAC_SUB_3
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  (r0 = x0 - y0,							\
+   r1 = x1 - y1 - (r0 > x0),						\
+   r2 = x2 - y2 - (r1 > x1))
+#endif
+
+#ifndef __FP_FRAC_SUB_4
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  (r0 = x0 - y0,							\
+   r1 = x1 - y1 - (r0 > x0),						\
+   r2 = x2 - y2 - (r1 > x1),						\
+   r3 = x3 - y3 - (r2 > x2))
+#endif
+
+#ifndef __FP_FRAC_DEC_3
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0)				\
+  do {									\
+    UWtype _t0, _t1;							\
+    _t0 = x0;								\
+    x0 -= y0;								\
+    _t1 = x1;								\
+    x1 -= y1 + (x0 > _t0);						\
+    x2 -= y2 + (x1 > _t1);						\
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_DEC_4
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0)			\
+  do {									\
+    UWtype _t0, _t1;							\
+    _t0 = x0;								\
+    x0 -= y0;								\
+    _t1 = x1;								\
+    x1 -= y1 + (x0 > _t0);						\
+    _t0 = x2;								\
+    x2 -= y2 + (x1 > _t1);						\
+    x3 -= y3 + (x2 > _t0);						\
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_ADDI_4
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)					\
+  do {									\
+    UWtype _t;								\
+    _t = ((x0 += i) < i);						\
+    x1 += _t; _t = (x1 < _t);						\
+    x2 += _t; _t = (x2 < _t);						\
+    x3 += _t;								\
+  } while (0)
+#endif
+
+/* Convert FP values between word sizes. This appears to be more
+ * complicated than I'd have expected it to be, so these might be
+ * wrong... These macros are in any case somewhat bogus because they
+ * use information about what various FRAC_n variables look like 
+ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
+ * the ones in op-2.h and op-1.h. 
+ */
+#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S)				\
+   do {									\
+     if (S##_c != FP_CLS_NAN)						\
+       _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),	\
+			  _FP_WFRACBITS_##sfs);				\
+     else								\
+       _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs));	\
+     D##_f = S##_f[0];							\
+  } while (0)
+
+#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S)				\
+   do {									\
+     if (S##_c != FP_CLS_NAN)						\
+       _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),	\
+		      _FP_WFRACBITS_##sfs);				\
+     else								\
+       _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs));	\
+     D##_f0 = S##_f[0];							\
+     D##_f1 = S##_f[1];							\
+  } while (0)
+
+/* Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+/* Put the FP value X into r, which is an integer of size rsize. */
+#define _FP_FRAC_ASSEMBLE_4(r, X, rsize)				\
+  do {									\
+    if (rsize <= _FP_W_TYPE_SIZE)					\
+      r = X##_f[0];							\
+    else if (rsize <= 2*_FP_W_TYPE_SIZE)				\
+    {									\
+      r = X##_f[1];							\
+      r <<= _FP_W_TYPE_SIZE;						\
+      r += X##_f[0];							\
+    }									\
+    else								\
+    {									\
+      /* I'm feeling lazy so we deal with int == 3words (implausible)*/	\
+      /* and int == 4words as a single case.			 */	\
+      r = X##_f[3];							\
+      r <<= _FP_W_TYPE_SIZE;						\
+      r += X##_f[2];							\
+      r <<= _FP_W_TYPE_SIZE;						\
+      r += X##_f[1];							\
+      r <<= _FP_W_TYPE_SIZE;						\
+      r += X##_f[0];							\
+    }									\
+  } while (0)
+
+/* "No disassemble Number Five!" */
+/* move an integer of size rsize into X's fractional part. We rely on
+ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
+ * having to mask the values we store into it.
+ */
+#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize)				\
+  do {									\
+    X##_f[0] = r;							\
+    X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);	\
+    X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
+    X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
+  } while (0);
+
+#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)				\
+   do {									\
+     D##_f[0] = S##_f;							\
+     D##_f[1] = D##_f[2] = D##_f[3] = 0;				\
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));	\
+   } while (0)
+
+#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S)				\
+   do {									\
+     D##_f[0] = S##_f0;							\
+     D##_f[1] = S##_f1;							\
+     D##_f[2] = D##_f[3] = 0;						\
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));	\
+   } while (0)
+
diff -urN linux-2.2.14-pre6/include/math-emu/op-8.h linux-2.2.14-pre7/include/math-emu/op-8.h
--- linux-2.2.14-pre6/include/math-emu/op-8.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/op-8.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,103 @@
+/* Software floating-point emulation.
+   Basic eight-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+                                                         
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* We need just a few things from here for op-4, if we ever need some
+   other macros, they can be added. */
+#define _FP_FRAC_DECL_8(X)	_FP_W_TYPE X##_f[8]
+#define _FP_FRAC_HIGH_8(X)	(X##_f[7])
+#define _FP_FRAC_LOW_8(X)	(X##_f[0])
+#define _FP_FRAC_WORD_8(X,w)	(X##_f[w])
+
+#define _FP_FRAC_SLL_8(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _up = (N) % _FP_W_TYPE_SIZE;					\
+    _down = _FP_W_TYPE_SIZE - _up;					\
+    if (!_up)								\
+      for (_i = 7; _i >= _skip; --_i)					\
+	X##_f[_i] = X##_f[_i-_skip];					\
+    else								\
+      {									\
+	for (_i = 7; _i > _skip; --_i)					\
+	  X##_f[_i] = X##_f[_i-_skip] << _up				\
+		      | X##_f[_i-_skip-1] >> _down;			\
+	X##_f[_i--] = X##_f[0] << _up; 					\
+      }									\
+    for (; _i >= 0; --_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+#define _FP_FRAC_SRL_8(X,N)						\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    if (!_down)								\
+      for (_i = 0; _i <= 7-_skip; ++_i)					\
+	X##_f[_i] = X##_f[_i+_skip];					\
+    else								\
+      {									\
+	for (_i = 0; _i < 7-_skip; ++_i)				\
+	  X##_f[_i] = X##_f[_i+_skip] >> _down				\
+		      | X##_f[_i+_skip+1] << _up;			\
+	X##_f[_i++] = X##_f[7] >> _down;				\
+      }									\
+    for (; _i < 8; ++_i)						\
+      X##_f[_i] = 0;							\
+  } while (0)
+
+
+/* Right shift with sticky-lsb. 
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRS_8(X,N,size)					\
+  do {									\
+    _FP_I_TYPE _up, _down, _skip, _i;					\
+    _FP_W_TYPE _s;							\
+    _skip = (N) / _FP_W_TYPE_SIZE;					\
+    _down = (N) % _FP_W_TYPE_SIZE;					\
+    _up = _FP_W_TYPE_SIZE - _down;					\
+    for (_s = _i = 0; _i < _skip; ++_i)					\
+      _s |= X##_f[_i];							\
+    _s |= X##_f[_i] << _up;						\
+/* s is now != 0 if we want to set the LSbit */				\
+    if (!_down)								\
+      for (_i = 0; _i <= 7-_skip; ++_i)					\
+	X##_f[_i] = X##_f[_i+_skip];					\
+    else								\
+      {									\
+	for (_i = 0; _i < 7-_skip; ++_i)				\
+	  X##_f[_i] = X##_f[_i+_skip] >> _down				\
+		      | X##_f[_i+_skip+1] << _up;			\
+	X##_f[_i++] = X##_f[7] >> _down;				\
+      }									\
+    for (; _i < 8; ++_i)						\
+      X##_f[_i] = 0;							\
+    /* don't fix the LSB until the very end when we're sure f[0] is stable */	\
+    X##_f[0] |= (_s != 0);						\
+  } while (0)
+
diff -urN linux-2.2.14-pre6/include/math-emu/op-common.h linux-2.2.14-pre7/include/math-emu/op-common.h
--- linux-2.2.14-pre6/include/math-emu/op-common.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/op-common.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,767 @@
+/* Software floating-point emulation. Common operations.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define _FP_DECL(wc, X)			\
+  _FP_I_TYPE X##_c, X##_s, X##_e;	\
+  _FP_FRAC_DECL_##wc(X)
+
+/*
+ * Finish truely unpacking a native fp value by classifying the kind
+ * of fp value and normalizing both the exponent and the fraction.
+ */
+
+#define _FP_UNPACK_CANONICAL(fs, wc, X)					\
+do {									\
+  switch (X##_e)							\
+  {									\
+  default:								\
+    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;			\
+    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
+    X##_e -= _FP_EXPBIAS_##fs;						\
+    X##_c = FP_CLS_NORMAL;						\
+    break;								\
+									\
+  case 0:								\
+    if (_FP_FRAC_ZEROP_##wc(X))						\
+      X##_c = FP_CLS_ZERO;						\
+    else								\
+      {									\
+	/* a denormalized number */					\
+	_FP_I_TYPE _shift;						\
+	_FP_FRAC_CLZ_##wc(_shift, X);					\
+	_shift -= _FP_FRACXBITS_##fs;					\
+	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));			\
+	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
+	X##_c = FP_CLS_NORMAL;						\
+	FP_SET_EXCEPTION(FP_EX_DENORM);					\
+      }									\
+    break;								\
+									\
+  case _FP_EXPMAX_##fs:							\
+    if (_FP_FRAC_ZEROP_##wc(X))						\
+      X##_c = FP_CLS_INF;						\
+    else								\
+      {									\
+	X##_c = FP_CLS_NAN;						\
+	/* Check for signaling NaN */					\
+	if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))		\
+	  FP_SET_EXCEPTION(FP_EX_INVALID);				\
+      }									\
+    break;								\
+  }									\
+} while (0)
+
+/*
+ * Before packing the bits back into the native fp result, take care
+ * of such mundane things as rounding and overflow.  Also, for some
+ * kinds of fp values, the original parts may not have been fully
+ * extracted -- but that is ok, we can regenerate them now.
+ */
+
+#define _FP_PACK_CANONICAL(fs, wc, X)				\
+do {								\
+  switch (X##_c)						\
+  {								\
+  case FP_CLS_NORMAL:						\
+    X##_e += _FP_EXPBIAS_##fs;					\
+    if (X##_e > 0)						\
+      {								\
+	_FP_ROUND(wc, X);					\
+	if (_FP_FRAC_OVERP_##wc(fs, X))				\
+	  {							\
+	    _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));		\
+	    X##_e++;						\
+	  }							\
+	else							\
+	  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
+	if (X##_e >= _FP_EXPMAX_##fs)				\
+	  {							\
+	    /* overflow */					\
+	    switch (FP_ROUNDMODE)				\
+	      {							\
+	      case FP_RND_NEAREST:				\
+		X##_c = FP_CLS_INF;				\
+		break;						\
+	      case FP_RND_PINF:					\
+		if (!X##_s) X##_c = FP_CLS_INF;			\
+		break;						\
+	      case FP_RND_MINF:					\
+		if (X##_s) X##_c = FP_CLS_INF;			\
+		break;						\
+	      }							\
+	    if (X##_c == FP_CLS_INF)				\
+	      {							\
+		/* Overflow to infinity */			\
+		X##_e = _FP_EXPMAX_##fs;			\
+		_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
+	      }							\
+	    else						\
+	      {							\
+		/* Overflow to maximum normal */		\
+		X##_e = _FP_EXPMAX_##fs - 1;			\
+		_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
+	      }							\
+	    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
+            FP_SET_EXCEPTION(FP_EX_INEXACT);			\
+	  }							\
+      }								\
+    else							\
+      {								\
+	/* we've got a denormalized number */			\
+	X##_e = -X##_e + 1;					\
+	if (X##_e <= _FP_WFRACBITS_##fs)			\
+	  {							\
+	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
+	    _FP_ROUND(wc, X);					\
+	    if (_FP_FRAC_HIGH_##fs(X)				\
+		& (_FP_OVERFLOW_##fs >> 1))			\
+	      {							\
+	        X##_e = 1;					\
+	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
+	      }							\
+	    else						\
+	      {							\
+		X##_e = 0;					\
+		_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);		\
+		FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
+	      }							\
+	  }							\
+	else							\
+	  {							\
+	    /* underflow to zero */				\
+	    X##_e = 0;						\
+	    if (!_FP_FRAC_ZEROP_##wc(X))			\
+	      {							\
+	        _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);		\
+	        _FP_ROUND(wc, X);				\
+	        _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);	\
+	      }							\
+	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
+	  }							\
+      }								\
+    break;							\
+								\
+  case FP_CLS_ZERO:						\
+    X##_e = 0;							\
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
+    break;							\
+								\
+  case FP_CLS_INF:						\
+    X##_e = _FP_EXPMAX_##fs;					\
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
+    break;							\
+								\
+  case FP_CLS_NAN:						\
+    X##_e = _FP_EXPMAX_##fs;					\
+    if (!_FP_KEEPNANFRACP)					\
+      {								\
+	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
+	X##_s = _FP_NANSIGN_##fs;				\
+      }								\
+    else							\
+      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;		\
+    break;							\
+  }								\
+} while (0)
+
+/* This one accepts raw argument and not cooked,  returns
+ * 1 if X is a signaling NaN.
+ */
+#define _FP_ISSIGNAN(fs, wc, X)					\
+({								\
+  int __ret = 0;						\
+  if (X##_e == _FP_EXPMAX_##fs)					\
+    {								\
+      if (!_FP_FRAC_ZEROP_##wc(X)				\
+	  && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
+	__ret = 1;						\
+    }								\
+  __ret;							\
+})
+
+
+
+
+
+/*
+ * Main addition routine.  The input values should be cooked.
+ */
+
+#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)				     \
+do {									     \
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))				     \
+  {									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):			     \
+    {									     \
+      /* shift the smaller number so that its exponent matches the larger */ \
+      _FP_I_TYPE diff = X##_e - Y##_e;					     \
+									     \
+      if (diff < 0)							     \
+	{								     \
+	  diff = -diff;							     \
+	  if (diff <= _FP_WFRACBITS_##fs)				     \
+	    _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);		     \
+	  else if (!_FP_FRAC_ZEROP_##wc(X))				     \
+	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			     \
+	  R##_e = Y##_e;						     \
+	}								     \
+      else								     \
+	{								     \
+	  if (diff > 0)							     \
+	    {								     \
+	      if (diff <= _FP_WFRACBITS_##fs)				     \
+	        _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);		     \
+	      else if (!_FP_FRAC_ZEROP_##wc(Y))				     \
+	        _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			     \
+	    }								     \
+	  R##_e = X##_e;						     \
+	}								     \
+									     \
+      R##_c = FP_CLS_NORMAL;						     \
+									     \
+      if (X##_s == Y##_s)						     \
+	{								     \
+	  R##_s = X##_s;						     \
+	  _FP_FRAC_ADD_##wc(R, X, Y);					     \
+	  if (_FP_FRAC_OVERP_##wc(fs, R))				     \
+	    {								     \
+	      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);		     \
+	      R##_e++;							     \
+	    }								     \
+	}								     \
+      else								     \
+	{								     \
+	  R##_s = X##_s;						     \
+	  _FP_FRAC_SUB_##wc(R, X, Y);					     \
+	  if (_FP_FRAC_ZEROP_##wc(R))					     \
+	    {								     \
+	      /* return an exact zero */				     \
+	      if (FP_ROUNDMODE == FP_RND_MINF)				     \
+		R##_s |= Y##_s;						     \
+	      else							     \
+		R##_s &= Y##_s;						     \
+	      R##_c = FP_CLS_ZERO;					     \
+	    }								     \
+	  else								     \
+	    {								     \
+	      if (_FP_FRAC_NEGP_##wc(R))				     \
+		{							     \
+		  _FP_FRAC_SUB_##wc(R, Y, X);				     \
+		  R##_s = Y##_s;					     \
+		}							     \
+									     \
+	      /* renormalize after subtraction */			     \
+	      _FP_FRAC_CLZ_##wc(diff, R);				     \
+	      diff -= _FP_WFRACXBITS_##fs;				     \
+	      if (diff)							     \
+		{							     \
+		  R##_e -= diff;					     \
+		  _FP_FRAC_SLL_##wc(R, diff);				     \
+		}							     \
+	    }								     \
+	}								     \
+      break;								     \
+    }									     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):				     \
+    _FP_CHOOSENAN(fs, wc, R, X, Y, OP);					     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):			     \
+    R##_e = X##_e;							     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):			     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):				     \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):				     \
+    _FP_FRAC_COPY_##wc(R, X);						     \
+    R##_s = X##_s;							     \
+    R##_c = X##_c;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):			     \
+    R##_e = Y##_e;							     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):			     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):				     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):				     \
+    _FP_FRAC_COPY_##wc(R, Y);						     \
+    R##_s = Y##_s;							     \
+    R##_c = Y##_c;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):				     \
+    if (X##_s != Y##_s)							     \
+      {									     \
+	/* +INF + -INF => NAN */					     \
+	_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);				     \
+	R##_s = _FP_NANSIGN_##fs;					     \
+	R##_c = FP_CLS_NAN;						     \
+	FP_SET_EXCEPTION(FP_EX_INVALID);				     \
+	break;								     \
+      }									     \
+    /* FALLTHRU */							     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):			     \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):				     \
+    R##_s = X##_s;							     \
+    R##_c = FP_CLS_INF;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):			     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):				     \
+    R##_s = Y##_s;							     \
+    R##_c = FP_CLS_INF;							     \
+    break;								     \
+									     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):			     \
+    /* make sure the sign is correct */					     \
+    if (FP_ROUNDMODE == FP_RND_MINF)					     \
+      R##_s = X##_s | Y##_s;						     \
+    else								     \
+      R##_s = X##_s & Y##_s;						     \
+    R##_c = FP_CLS_ZERO;						     \
+    break;								     \
+									     \
+  default:								     \
+    abort();								     \
+  }									     \
+} while (0)
+
+#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
+#define _FP_SUB(fs, wc, R, X, Y)					     \
+  do {									     \
+    if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;				     \
+    _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');				     \
+  } while (0)
+
+
+/*
+ * Main negation routine.  FIXME -- when we care about setting exception
+ * bits reliably, this will not do.  We should examine all of the fp classes.
+ */
+
+#define _FP_NEG(fs, wc, R, X)		\
+  do {					\
+    _FP_FRAC_COPY_##wc(R, X);		\
+    R##_c = X##_c;			\
+    R##_e = X##_e;			\
+    R##_s = 1 ^ X##_s;			\
+  } while (0)
+
+
+/*
+ * Main multiplication routine.  The input values should be cooked.
+ */
+
+#define _FP_MUL(fs, wc, R, X, Y)			\
+do {							\
+  R##_s = X##_s ^ Y##_s;				\
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
+  {							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_NORMAL;				\
+    R##_e = X##_e + Y##_e + 1;				\
+							\
+    _FP_MUL_MEAT_##fs(R,X,Y);				\
+							\
+    if (_FP_FRAC_OVERP_##wc(fs, R))			\
+      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
+    else						\
+      R##_e--;						\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
+    _FP_CHOOSENAN(fs, wc, R, X, Y, '*');		\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
+    R##_s = X##_s;					\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
+    _FP_FRAC_COPY_##wc(R, X);				\
+    R##_c = X##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
+    R##_s = Y##_s;					\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
+    _FP_FRAC_COPY_##wc(R, Y);				\
+    R##_c = Y##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
+    R##_s = _FP_NANSIGN_##fs;				\
+    R##_c = FP_CLS_NAN;					\
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
+    FP_SET_EXCEPTION(FP_EX_INVALID);			\
+    break;						\
+							\
+  default:						\
+    abort();						\
+  }							\
+} while (0)
+
+
+/*
+ * Main division routine.  The input values should be cooked.
+ */
+
+#define _FP_DIV(fs, wc, R, X, Y)			\
+do {							\
+  R##_s = X##_s ^ Y##_s;				\
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
+  {							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_NORMAL;				\
+    R##_e = X##_e - Y##_e;				\
+							\
+    _FP_DIV_MEAT_##fs(R,X,Y);				\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
+    _FP_CHOOSENAN(fs, wc, R, X, Y, '/');		\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
+    R##_s = X##_s;					\
+    _FP_FRAC_COPY_##wc(R, X);				\
+    R##_c = X##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
+    R##_s = Y##_s;					\
+    _FP_FRAC_COPY_##wc(R, Y);				\
+    R##_c = Y##_c;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_ZERO;				\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
+    FP_SET_EXCEPTION(FP_EX_DIVZERO);			\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
+    R##_c = FP_CLS_INF;					\
+    break;						\
+							\
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
+    R##_s = _FP_NANSIGN_##fs;				\
+    R##_c = FP_CLS_NAN;					\
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
+    FP_SET_EXCEPTION(FP_EX_INVALID);			\
+    break;						\
+							\
+  default:						\
+    abort();						\
+  }							\
+} while (0)
+
+
+/*
+ * Main differential comparison routine.  The inputs should be raw not
+ * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
+ */
+
+#define _FP_CMP(fs, wc, ret, X, Y, un)					\
+  do {									\
+    /* NANs are unordered */						\
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
+	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
+      {									\
+	ret = un;							\
+      }									\
+    else								\
+      {									\
+	int __is_zero_x;						\
+	int __is_zero_y;						\
+									\
+	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
+	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
+									\
+	if (__is_zero_x && __is_zero_y)					\
+		ret = 0;						\
+	else if (__is_zero_x)						\
+		ret = Y##_s ? 1 : -1;					\
+	else if (__is_zero_y)						\
+		ret = X##_s ? -1 : 1;					\
+	else if (X##_s != Y##_s)					\
+	  ret = X##_s ? -1 : 1;						\
+	else if (X##_e > Y##_e)						\
+	  ret = X##_s ? -1 : 1;						\
+	else if (X##_e < Y##_e)						\
+	  ret = X##_s ? 1 : -1;						\
+	else if (_FP_FRAC_GT_##wc(X, Y))				\
+	  ret = X##_s ? -1 : 1;						\
+	else if (_FP_FRAC_GT_##wc(Y, X))				\
+	  ret = X##_s ? 1 : -1;						\
+	else								\
+	  ret = 0;							\
+      }									\
+  } while (0)
+
+
+/* Simplification for strict equality.  */
+
+#define _FP_CMP_EQ(fs, wc, ret, X, Y)					  \
+  do {									  \
+    /* NANs are unordered */						  \
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		  \
+	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	  \
+      {									  \
+	ret = 1;							  \
+      }									  \
+    else								  \
+      {									  \
+	ret = !(X##_e == Y##_e						  \
+		&& _FP_FRAC_EQ_##wc(X, Y)				  \
+		&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
+      }									  \
+  } while (0)
+
+/*
+ * Main square root routine.  The input value should be cooked.
+ */
+
+#define _FP_SQRT(fs, wc, R, X)						\
+do {									\
+    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
+    _FP_W_TYPE q;							\
+    switch (X##_c)							\
+    {									\
+    case FP_CLS_NAN:							\
+	_FP_FRAC_COPY_##wc(R, X);					\
+	R##_s = X##_s;							\
+    	R##_c = FP_CLS_NAN;						\
+    	break;								\
+    case FP_CLS_INF:							\
+    	if (X##_s)							\
+    	  {								\
+    	    R##_s = _FP_NANSIGN_##fs;					\
+	    R##_c = FP_CLS_NAN; /* NAN */				\
+	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
+	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
+    	  }								\
+    	else								\
+    	  {								\
+    	    R##_s = 0;							\
+    	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
+    	  }								\
+    	break;								\
+    case FP_CLS_ZERO:							\
+	R##_s = X##_s;							\
+	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
+	break;								\
+    case FP_CLS_NORMAL:							\
+    	R##_s = 0;							\
+        if (X##_s)							\
+          {								\
+	    R##_c = FP_CLS_NAN; /* sNAN */				\
+	    R##_s = _FP_NANSIGN_##fs;					\
+	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
+	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
+	    break;							\
+          }								\
+    	R##_c = FP_CLS_NORMAL;						\
+        if (X##_e & 1)							\
+          _FP_FRAC_SLL_##wc(X, 1);					\
+        R##_e = X##_e >> 1;						\
+        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
+        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
+        q = _FP_OVERFLOW_##fs >> 1;					\
+        _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
+    }									\
+  } while (0)
+
+/*
+ * Convert from FP to integer
+ */
+
+/* RSIGNED can have following values:
+ * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
+ *     the result is either 0 or (2^rsize)-1 depending on the sign in such case.
+ * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
+ *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
+ *     on the sign in such case.
+ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
+ *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
+ *     on the sign in such case.
+ */
+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)				\
+  do {										\
+    switch (X##_c)								\
+      {										\
+      case FP_CLS_NORMAL:							\
+	if (X##_e < 0)								\
+	  {									\
+	    FP_SET_EXCEPTION(FP_EX_INEXACT);					\
+	  case FP_CLS_ZERO:							\
+	    r = 0;								\
+	  }									\
+	else if (X##_e >= rsize - (rsigned > 0 || X##_s)			\
+		 || (!rsigned && X##_s))					\
+	  {	/* overflow */							\
+	  case FP_CLS_NAN:                                                      \
+	  case FP_CLS_INF:							\
+	    if (rsigned)							\
+	      {									\
+		r = 1;								\
+		r <<= rsize - 1;						\
+		r -= 1 - X##_s;							\
+	      } else {								\
+		r = 0;								\
+		if (X##_s)							\
+		  r = ~r;							\
+	      }									\
+	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
+	  }									\
+	else									\
+	  {									\
+	    if (_FP_W_TYPE_SIZE*wc < rsize)					\
+	      {									\
+		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
+		r <<= X##_e - _FP_WFRACBITS_##fs;				\
+	      }									\
+	    else								\
+	      {									\
+		if (X##_e >= _FP_WFRACBITS_##fs)				\
+		  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
+		else if (X##_e < _FP_WFRACBITS_##fs - 1)			\
+		  {								\
+		    _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),	\
+				      _FP_WFRACBITS_##fs);			\
+		    if (_FP_FRAC_LOW_##wc(X) & 1)				\
+		      FP_SET_EXCEPTION(FP_EX_INEXACT);				\
+		    _FP_FRAC_SRL_##wc(X, 1);					\
+		  }								\
+		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
+	      }									\
+	    if (rsigned && X##_s)						\
+	      r = -r;								\
+	  }									\
+	break;									\
+      }										\
+  } while (0)
+
+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
+  do {									\
+    if (r)								\
+      {									\
+	X##_c = FP_CLS_NORMAL;						\
+									\
+	if ((X##_s = (r < 0)))						\
+	  r = -r;							\
+									\
+	if (rsize <= _FP_W_TYPE_SIZE)					\
+	  __FP_CLZ(X##_e, r);						\
+	else								\
+	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), 	\
+		     (_FP_W_TYPE)r);					\
+	if (rsize < _FP_W_TYPE_SIZE)					\
+		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
+	X##_e = rsize - X##_e - 1;					\
+									\
+	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)	\
+	  __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);	\
+	r &= ~((rtype)1 << X##_e);					\
+	_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);	\
+	_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));		\
+      }									\
+    else								\
+      {									\
+	X##_c = FP_CLS_ZERO, X##_s = 0;					\
+      }									\
+  } while (0)
+
+
+#define FP_CONV(dfs,sfs,dwc,swc,D,S)			\
+  do {							\
+    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);	\
+    D##_e = S##_e;					\
+    D##_c = S##_c;					\
+    D##_s = S##_s;					\
+  } while (0)
+
+/*
+ * Helper primitives.
+ */
+
+/* Count leading zeros in a word.  */
+
+#ifndef __FP_CLZ
+#if _FP_W_TYPE_SIZE < 64
+/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
+#define __FP_CLZ(r, x)				\
+  do {						\
+    _FP_W_TYPE _t = (x);			\
+    r = _FP_W_TYPE_SIZE - 1;			\
+    if (_t > 0xffff) r -= 16;			\
+    if (_t > 0xffff) _t >>= 16;			\
+    if (_t > 0xff) r -= 8;			\
+    if (_t > 0xff) _t >>= 8;			\
+    if (_t & 0xf0) r -= 4;			\
+    if (_t & 0xf0) _t >>= 4;			\
+    if (_t & 0xc) r -= 2;			\
+    if (_t & 0xc) _t >>= 2;			\
+    if (_t & 0x2) r -= 1;			\
+  } while (0)
+#else /* not _FP_W_TYPE_SIZE < 64 */
+#define __FP_CLZ(r, x)				\
+  do {						\
+    _FP_W_TYPE _t = (x);			\
+    r = _FP_W_TYPE_SIZE - 1;			\
+    if (_t > 0xffffffff) r -= 32;		\
+    if (_t > 0xffffffff) _t >>= 32;		\
+    if (_t > 0xffff) r -= 16;			\
+    if (_t > 0xffff) _t >>= 16;			\
+    if (_t > 0xff) r -= 8;			\
+    if (_t > 0xff) _t >>= 8;			\
+    if (_t & 0xf0) r -= 4;			\
+    if (_t & 0xf0) _t >>= 4;			\
+    if (_t & 0xc) r -= 2;			\
+    if (_t & 0xc) _t >>= 2;			\
+    if (_t & 0x2) r -= 1;			\
+  } while (0)
+#endif /* not _FP_W_TYPE_SIZE < 64 */
+#endif /* ndef __FP_CLZ */
+
+#define _FP_DIV_HELP_imm(q, r, n, d)		\
+  do {						\
+    q = n / d, r = n % d;			\
+  } while (0)
+
diff -urN linux-2.2.14-pre6/include/math-emu/quad.h linux-2.2.14-pre7/include/math-emu/quad.h
--- linux-2.2.14-pre6/include/math-emu/quad.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/quad.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,201 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Quad Precision.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_Q         (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_Q		(2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_Q		113
+#define _FP_FRACXBITS_Q		(_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
+#define _FP_WFRACBITS_Q		(_FP_WORKBITS + _FP_FRACBITS_Q)
+#define _FP_WFRACXBITS_Q	(_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
+#define _FP_EXPBITS_Q		15
+#define _FP_EXPBIAS_Q		16383
+#define _FP_EXPMAX_Q		32767
+
+#define _FP_QNANBIT_Q		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_Q		\
+	((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_Q		\
+	((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_Q
+{
+   long double flt;
+   struct 
+   {
+#if __BYTE_ORDER == __BIG_ENDIAN
+      unsigned sign : 1;
+      unsigned exp : _FP_EXPBITS_Q;
+      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+      unsigned long frac2 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac2 : _FP_W_TYPE_SIZE;
+      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+      unsigned exp : _FP_EXPBITS_Q;
+      unsigned sign : 1;
+#endif /* not bigendian */
+   } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_Q(X)		_FP_DECL(4,X)
+#define FP_UNPACK_RAW_Q(X,val)	_FP_UNPACK_RAW_4(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val)	_FP_UNPACK_RAW_4_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X)	_FP_PACK_RAW_4(Q,val,X)
+#define FP_PACK_RAW_QP(val,X)		\
+  do {					\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_4_P(Q,val,X);	\
+  } while (0)
+
+#define FP_UNPACK_Q(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_4(Q,X,val);		\
+    _FP_UNPACK_CANONICAL(Q,4,X);	\
+  } while (0)
+
+#define FP_UNPACK_QP(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_4_P(Q,X,val);	\
+    _FP_UNPACK_CANONICAL(Q,4,X);	\
+  } while (0)
+
+#define FP_PACK_Q(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(Q,4,X);		\
+    _FP_PACK_RAW_4(Q,val,X);		\
+  } while (0)
+
+#define FP_PACK_QP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(Q,4,X);		\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_4_P(Q,val,X);	\
+  } while (0)
+
+#define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN(Q,4,X)
+#define FP_NEG_Q(R,X)			_FP_NEG(Q,4,R,X)
+#define FP_ADD_Q(R,X,Y)			_FP_ADD(Q,4,R,X,Y)
+#define FP_SUB_Q(R,X,Y)			_FP_SUB(Q,4,R,X,Y)
+#define FP_MUL_Q(R,X,Y)			_FP_MUL(Q,4,R,X,Y)
+#define FP_DIV_Q(R,X,Y)			_FP_DIV(Q,4,R,X,Y)
+#define FP_SQRT_Q(R,X)			_FP_SQRT(Q,4,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q)	_FP_SQRT_MEAT_4(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un)	_FP_CMP(Q,4,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,4,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg)	_FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt)	_FP_FROM_INT(Q,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_4(X)
+#define _FP_FRAC_HIGH_RAW_Q(X)	_FP_FRAC_HIGH_4(X)
+
+#else   /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_Q
+{
+  long double flt /* __attribute__((mode(TF))) */ ;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_Q;
+    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+    unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+    unsigned long frac0 : _FP_W_TYPE_SIZE;
+    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_Q;
+    unsigned sign  : 1;
+#endif
+  } bits;
+};
+
+#define FP_DECL_Q(X)		_FP_DECL(2,X)
+#define FP_UNPACK_RAW_Q(X,val)	_FP_UNPACK_RAW_2(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val)	_FP_UNPACK_RAW_2_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X)	_FP_PACK_RAW_2(Q,val,X)
+#define FP_PACK_RAW_QP(val,X)		\
+  do {					\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_2_P(Q,val,X);	\
+  } while (0)
+
+#define FP_UNPACK_Q(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_2(Q,X,val);		\
+    _FP_UNPACK_CANONICAL(Q,2,X);	\
+  } while (0)
+
+#define FP_UNPACK_QP(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_2_P(Q,X,val);	\
+    _FP_UNPACK_CANONICAL(Q,2,X);	\
+  } while (0)
+
+#define FP_PACK_Q(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(Q,2,X);		\
+    _FP_PACK_RAW_2(Q,val,X);		\
+  } while (0)
+
+#define FP_PACK_QP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(Q,2,X);		\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_2_P(Q,val,X);	\
+  } while (0)
+
+#define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN(Q,2,X)
+#define FP_NEG_Q(R,X)			_FP_NEG(Q,2,R,X)
+#define FP_ADD_Q(R,X,Y)			_FP_ADD(Q,2,R,X,Y)
+#define FP_SUB_Q(R,X,Y)			_FP_SUB(Q,2,R,X,Y)
+#define FP_MUL_Q(R,X,Y)			_FP_MUL(Q,2,R,X,Y)
+#define FP_DIV_Q(R,X,Y)			_FP_DIV(Q,2,R,X,Y)
+#define FP_SQRT_Q(R,X)			_FP_SQRT(Q,2,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q)	_FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un)	_FP_CMP(Q,2,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,2,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg)	_FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt)	_FP_FROM_INT(Q,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_Q(X)	_FP_FRAC_HIGH_2(X)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff -urN linux-2.2.14-pre6/include/math-emu/single.h linux-2.2.14-pre7/include/math-emu/single.h
--- linux-2.2.14-pre6/include/math-emu/single.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/single.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,110 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Single Precision.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACBITS_S		24
+#define _FP_FRACXBITS_S		(_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
+#define _FP_WFRACBITS_S		(_FP_WORKBITS + _FP_FRACBITS_S)
+#define _FP_WFRACXBITS_S	(_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
+#define _FP_EXPBITS_S		8
+#define _FP_EXPBIAS_S		127
+#define _FP_EXPMAX_S		255
+#define _FP_QNANBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
+#define _FP_IMPLBIT_S		((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
+#define _FP_OVERFLOW_S		((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
+
+/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
+   chosen by the target machine.  */
+
+union _FP_UNION_S
+{
+  float flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+#else
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_S(X)		_FP_DECL(1,X)
+#define FP_UNPACK_RAW_S(X,val)	_FP_UNPACK_RAW_1(S,X,val)
+#define FP_UNPACK_RAW_SP(X,val)	_FP_UNPACK_RAW_1_P(S,X,val)
+#define FP_PACK_RAW_S(val,X)	_FP_PACK_RAW_1(S,val,X)
+#define FP_PACK_RAW_SP(val,X)		\
+  do {					\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_1_P(S,val,X);	\
+  } while (0)
+
+#define FP_UNPACK_S(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1(S,X,val);		\
+    _FP_UNPACK_CANONICAL(S,1,X);	\
+  } while (0)
+
+#define FP_UNPACK_SP(X,val)		\
+  do {					\
+    _FP_UNPACK_RAW_1_P(S,X,val);	\
+    _FP_UNPACK_CANONICAL(S,1,X);	\
+  } while (0)
+
+#define FP_PACK_S(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(S,1,X);		\
+    _FP_PACK_RAW_1(S,val,X);		\
+  } while (0)
+
+#define FP_PACK_SP(val,X)		\
+  do {					\
+    _FP_PACK_CANONICAL(S,1,X);		\
+    if (!FP_INHIBIT_RESULTS)		\
+      _FP_PACK_RAW_1_P(S,val,X);	\
+  } while (0)
+
+#define FP_ISSIGNAN_S(X)		_FP_ISSIGNAN(S,1,X)
+#define FP_NEG_S(R,X)			_FP_NEG(S,1,R,X)
+#define FP_ADD_S(R,X,Y)			_FP_ADD(S,1,R,X,Y)
+#define FP_SUB_S(R,X,Y)			_FP_SUB(S,1,R,X,Y)
+#define FP_MUL_S(R,X,Y)			_FP_MUL(S,1,R,X,Y)
+#define FP_DIV_S(R,X,Y)			_FP_DIV(S,1,R,X,Y)
+#define FP_SQRT_S(R,X)			_FP_SQRT(S,1,R,X)
+#define _FP_SQRT_MEAT_S(R,S,T,X,Q)	_FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+#define FP_CMP_S(r,X,Y,un)	_FP_CMP(S,1,r,X,Y,un)
+#define FP_CMP_EQ_S(r,X,Y)	_FP_CMP_EQ(S,1,r,X,Y)
+
+#define FP_TO_INT_S(r,X,rsz,rsg)	_FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_FROM_INT_S(X,r,rs,rt)	_FP_FROM_INT(S,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_S(X)	_FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_S(X)	_FP_FRAC_HIGH_1(X)
diff -urN linux-2.2.14-pre6/include/math-emu/soft-fp.h linux-2.2.14-pre7/include/math-emu/soft-fp.h
--- linux-2.2.14-pre6/include/math-emu/soft-fp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.14-pre7/include/math-emu/soft-fp.h	2003-08-15 15:09:04.000000000 -0700
@@ -0,0 +1,176 @@
+/* Software floating-point emulation.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef SOFT_FP_H
+#define SOFT_FP_H
+
+#include "sfp-machine.h"
+
+/* Allow sfp-machine to have its own byte order definitions. */
+#ifndef __BYTE_ORDER
+#include <endian.h>
+#endif
+
+#define _FP_WORKBITS		3
+#define _FP_WORK_LSB		((_FP_W_TYPE)1 << 3)
+#define _FP_WORK_ROUND		((_FP_W_TYPE)1 << 2)
+#define _FP_WORK_GUARD		((_FP_W_TYPE)1 << 1)
+#define _FP_WORK_STICKY		((_FP_W_TYPE)1 << 0)
+
+#ifndef FP_RND_NEAREST
+# define FP_RND_NEAREST		0
+# define FP_RND_ZERO		1
+# define FP_RND_PINF		2
+# define FP_RND_MINF		3
+#ifndef FP_ROUNDMODE
+# define FP_ROUNDMODE		FP_RND_NEAREST
+#endif
+#endif
+
+/* By default don't care about exceptions. */
+#ifndef FP_EX_INVALID
+#define FP_EX_INVALID		0
+#endif
+#ifndef FP_EX_OVERFLOW
+#define FP_EX_OVERFLOW		0
+#endif
+#ifndef FP_EX_UNDERFLOW
+#define FP_EX_UNDERFLOW		
+#endif
+#ifndef FP_EX_DIVZERO
+#define FP_EX_DIVZERO		0
+#endif
+#ifndef FP_EX_INEXACT
+#define FP_EX_INEXACT		0
+#endif
+#ifndef FP_EX_DENORM
+#define FP_EX_DENORM		0
+#endif
+
+#ifdef _FP_DECL_EX
+#define FP_DECL_EX					\
+  int _fex = 0;						\
+  _FP_DECL_EX
+#else
+#define FP_DECL_EX int _fex = 0
+#endif
+  
+#ifndef FP_INIT_ROUNDMODE
+#define FP_INIT_ROUNDMODE do {} while (0)
+#endif
+
+#ifndef FP_HANDLE_EXCEPTIONS
+#define FP_HANDLE_EXCEPTIONS do {} while (0)
+#endif
+
+#ifndef FP_INHIBIT_RESULTS
+/* By default we write the results always.
+ * sfp-machine may override this and e.g.
+ * check if some exceptions are unmasked
+ * and inhibit it in such a case.
+ */
+#define FP_INHIBIT_RESULTS 0
+#endif
+
+#define FP_SET_EXCEPTION(ex)				\
+  _fex |= (ex)
+  
+#define FP_UNSET_EXCEPTION(ex)				\
+  _fex &= ~(ex)
+
+#define FP_CLEAR_EXCEPTIONS				\
+  _fex = 0
+
+#define _FP_ROUND_NEAREST(wc, X)			\
+do {							\
+    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);		\
+} while (0)
+
+#define _FP_ROUND_ZERO(wc, X)		0
+
+#define _FP_ROUND_PINF(wc, X)				\
+do {							\
+    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
+} while (0)
+
+#define _FP_ROUND_MINF(wc, X)				\
+do {							\
+    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
+} while (0)
+
+#define _FP_ROUND(wc, X)			\
+do {						\
+	if (_FP_FRAC_LOW_##wc(X) & 7)		\
+	  FP_SET_EXCEPTION(FP_EX_INEXACT);	\
+	switch (FP_ROUNDMODE)			\
+	{					\
+	  case FP_RND_NEAREST:			\
+	    _FP_ROUND_NEAREST(wc,X);		\
+	    break;				\
+	  case FP_RND_ZERO:			\
+	    _FP_ROUND_ZERO(wc,X);		\
+	    break;				\
+	  case FP_RND_PINF:			\
+	    _FP_ROUND_PINF(wc,X);		\
+	    break;				\
+	  case FP_RND_MINF:			\
+	    _FP_ROUND_MINF(wc,X);		\
+	    break;				\
+	}					\
+} while (0)
+
+#define FP_CLS_NORMAL		0
+#define FP_CLS_ZERO		1
+#define FP_CLS_INF		2
+#define FP_CLS_NAN		3
+
+#define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
+
+#include "op-1.h"
+#include "op-2.h"
+#include "op-4.h"
+#include "op-8.h"
+#include "op-common.h"
+
+/* Sigh.  Silly things longlong.h needs.  */
+#define UWtype		_FP_W_TYPE
+#define W_TYPE_SIZE	_FP_W_TYPE_SIZE
+
+typedef int SItype __attribute__((mode(SI)));
+typedef int DItype __attribute__((mode(DI)));
+typedef unsigned int USItype __attribute__((mode(SI)));
+typedef unsigned int UDItype __attribute__((mode(DI)));
+#if _FP_W_TYPE_SIZE == 32
+typedef unsigned int UHWtype __attribute__((mode(HI)));
+#elif _FP_W_TYPE_SIZE == 64
+typedef USItype UHWtype;
+#endif
+
+#ifndef umul_ppmm
+#include <stdlib/longlong.h>
+#endif
+
+#endif
diff -urN linux-2.2.14-pre6/Makefile linux-2.2.14-pre7/Makefile
--- linux-2.2.14-pre6/Makefile	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/Makefile	2003-08-15 15:09:03.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 14
-EXTRAVERSION = pre6
+EXTRAVERSION = pre7
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.14-pre6/net/irda/irda_device.c linux-2.2.14-pre7/net/irda/irda_device.c
--- linux-2.2.14-pre6/net/irda/irda_device.c	2003-08-15 15:09:03.000000000 -0700
+++ linux-2.2.14-pre7/net/irda/irda_device.c	2003-08-15 15:09:04.000000000 -0700
@@ -120,7 +120,7 @@
 #ifdef CONFIG_GIRBIL_DONGLE
 	girbil_init();
 #endif
-#ifdef CONFIG_GIRBIL_DONGLE
+#ifdef CONFIG_LITELINK_DONGLE
 	litelink_init();
 #endif
 
