summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/math-emu
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2006-03-27 23:43:27 -0600
committerKumar Gala <galak@kernel.crashing.org>2006-03-27 23:43:27 -0600
commit5cd272085bbc905532869f3e1fd18a7100496b56 (patch)
tree2c29f8a713e90fe55864502ed962c656014bca71 /arch/powerpc/math-emu
parentff2e6d7e27cf1f757ab0d97e1a9e46de47152a0e (diff)
powerpc: move math-emu over to arch/powerpc
Towards the goal of having arch/powerpc not build anything over in arch/ppc move math-emu over. Also, killed some references to arch/ppc/ in the arch/powerpc Makefile which should belong in drivers/ when the particular sub-arch's move over to arch/powerpc. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/math-emu')
-rw-r--r--arch/powerpc/math-emu/Makefile13
-rw-r--r--arch/powerpc/math-emu/double.h129
-rw-r--r--arch/powerpc/math-emu/fabs.c18
-rw-r--r--arch/powerpc/math-emu/fadd.c38
-rw-r--r--arch/powerpc/math-emu/fadds.c39
-rw-r--r--arch/powerpc/math-emu/fcmpo.c46
-rw-r--r--arch/powerpc/math-emu/fcmpu.c42
-rw-r--r--arch/powerpc/math-emu/fctiw.c25
-rw-r--r--arch/powerpc/math-emu/fctiwz.c32
-rw-r--r--arch/powerpc/math-emu/fdiv.c53
-rw-r--r--arch/powerpc/math-emu/fdivs.c55
-rw-r--r--arch/powerpc/math-emu/fmadd.c48
-rw-r--r--arch/powerpc/math-emu/fmadds.c49
-rw-r--r--arch/powerpc/math-emu/fmr.c18
-rw-r--r--arch/powerpc/math-emu/fmsub.c51
-rw-r--r--arch/powerpc/math-emu/fmsubs.c52
-rw-r--r--arch/powerpc/math-emu/fmul.c42
-rw-r--r--arch/powerpc/math-emu/fmuls.c43
-rw-r--r--arch/powerpc/math-emu/fnabs.c18
-rw-r--r--arch/powerpc/math-emu/fneg.c18
-rw-r--r--arch/powerpc/math-emu/fnmadd.c51
-rw-r--r--arch/powerpc/math-emu/fnmadds.c52
-rw-r--r--arch/powerpc/math-emu/fnmsub.c54
-rw-r--r--arch/powerpc/math-emu/fnmsubs.c55
-rw-r--r--arch/powerpc/math-emu/fres.c12
-rw-r--r--arch/powerpc/math-emu/frsp.c25
-rw-r--r--arch/powerpc/math-emu/frsqrte.c12
-rw-r--r--arch/powerpc/math-emu/fsel.c38
-rw-r--r--arch/powerpc/math-emu/fsqrt.c37
-rw-r--r--arch/powerpc/math-emu/fsqrts.c38
-rw-r--r--arch/powerpc/math-emu/fsub.c41
-rw-r--r--arch/powerpc/math-emu/fsubs.c42
-rw-r--r--arch/powerpc/math-emu/lfd.c19
-rw-r--r--arch/powerpc/math-emu/lfs.c37
-rw-r--r--arch/powerpc/math-emu/math.c483
-rw-r--r--arch/powerpc/math-emu/mcrfs.c31
-rw-r--r--arch/powerpc/math-emu/mffs.c17
-rw-r--r--arch/powerpc/math-emu/mtfsb0.c18
-rw-r--r--arch/powerpc/math-emu/mtfsb1.c18
-rw-r--r--arch/powerpc/math-emu/mtfsf.c45
-rw-r--r--arch/powerpc/math-emu/mtfsfi.c23
-rw-r--r--arch/powerpc/math-emu/op-1.h245
-rw-r--r--arch/powerpc/math-emu/op-2.h433
-rw-r--r--arch/powerpc/math-emu/op-4.h297
-rw-r--r--arch/powerpc/math-emu/op-common.h688
-rw-r--r--arch/powerpc/math-emu/sfp-machine.h377
-rw-r--r--arch/powerpc/math-emu/single.h66
-rw-r--r--arch/powerpc/math-emu/soft-fp.h104
-rw-r--r--arch/powerpc/math-emu/stfd.c20
-rw-r--r--arch/powerpc/math-emu/stfiwx.c16
-rw-r--r--arch/powerpc/math-emu/stfs.c41
-rw-r--r--arch/powerpc/math-emu/types.c51
-rw-r--r--arch/powerpc/math-emu/udivmodti4.c191
53 files changed, 4506 insertions, 0 deletions
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
new file mode 100644
index 000000000000..754143e8936b
--- /dev/null
+++ b/arch/powerpc/math-emu/Makefile
@@ -0,0 +1,13 @@
+
+obj-y := math.o fmr.o lfd.o stfd.o
+
+obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
+ fctiw.o fctiwz.o fdiv.o fdivs.o \
+ fmadd.o fmadds.o fmsub.o fmsubs.o \
+ fmul.o fmuls.o fnabs.o fneg.o types.o \
+ fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
+ fres.o frsp.o frsqrte.o fsel.o lfs.o \
+ fsqrt.o fsqrts.o fsub.o fsubs.o \
+ mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
+ mtfsf.o mtfsfi.o stfiwx.o stfs.o \
+ udivmodti4.o
diff --git a/arch/powerpc/math-emu/double.h b/arch/powerpc/math-emu/double.h
new file mode 100644
index 000000000000..ffba8b67f059
--- /dev/null
+++ b/arch/powerpc/math-emu/double.h
@@ -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 --git a/arch/powerpc/math-emu/fabs.c b/arch/powerpc/math-emu/fabs.c
new file mode 100644
index 000000000000..41f0617f3d3a
--- /dev/null
+++ b/arch/powerpc/math-emu/fabs.c
@@ -0,0 +1,18 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int
+fabs(u32 *frD, u32 *frB)
+{
+ frD[0] = frB[0] & 0x7fffffff;
+ frD[1] = frB[1];
+
+#ifdef DEBUG
+ printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
+ dump_double(frD);
+ printk("\n");
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c
new file mode 100644
index 000000000000..fc8836488b64
--- /dev/null
+++ b/arch/powerpc/math-emu/fadd.c
@@ -0,0 +1,38 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fadd(void *frD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(R);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
+ ret |= EFLAG_VXISI;
+
+ FP_ADD_D(R, A, B);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_D(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fadds.c b/arch/powerpc/math-emu/fadds.c
new file mode 100644
index 000000000000..93025b6c8f3c
--- /dev/null
+++ b/arch/powerpc/math-emu/fadds.c
@@ -0,0 +1,39 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+
+int
+fadds(void *frD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(R);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
+ ret |= EFLAG_VXISI;
+
+ FP_ADD_D(R, A, B);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_DS(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c
new file mode 100644
index 000000000000..4efac394b4cb
--- /dev/null
+++ b/arch/powerpc/math-emu/fcmpo.c
@@ -0,0 +1,46 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
+ long cmp;
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ if (A_c == FP_CLS_NAN || B_c == FP_CLS_NAN)
+ ret |= EFLAG_VXVC;
+
+ FP_CMP_D(cmp, A, B, 2);
+ cmp = code[(cmp + 1) & 3];
+
+ __FPU_FPSCR &= ~(0x1f000);
+ __FPU_FPSCR |= (cmp << 12);
+
+ *ccr &= ~(15 << ((7 - crfD) << 2));
+ *ccr |= (cmp << ((7 - crfD) << 2));
+
+#ifdef DEBUG
+ printk("CR: %08x\n", *ccr);
+#endif
+
+ return ret;
+}
diff --git a/arch/powerpc/math-emu/fcmpu.c b/arch/powerpc/math-emu/fcmpu.c
new file mode 100644
index 000000000000..b7e33176e618
--- /dev/null
+++ b/arch/powerpc/math-emu/fcmpu.c
@@ -0,0 +1,42 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
+ long cmp;
+
+#ifdef DEBUG
+ printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ FP_CMP_D(cmp, A, B, 2);
+ cmp = code[(cmp + 1) & 3];
+
+ __FPU_FPSCR &= ~(0x1f000);
+ __FPU_FPSCR |= (cmp << 12);
+
+ *ccr &= ~(15 << ((7 - crfD) << 2));
+ *ccr |= (cmp << ((7 - crfD) << 2));
+
+#ifdef DEBUG
+ printk("CR: %08x\n", *ccr);
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/fctiw.c b/arch/powerpc/math-emu/fctiw.c
new file mode 100644
index 000000000000..3b3c98b840cf
--- /dev/null
+++ b/arch/powerpc/math-emu/fctiw.c
@@ -0,0 +1,25 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fctiw(u32 *frD, void *frB)
+{
+ FP_DECL_D(B);
+ unsigned int r;
+
+ __FP_UNPACK_D(B, frB);
+ FP_TO_INT_D(r, B, 32, 1);
+ frD[1] = r;
+
+#ifdef DEBUG
+ printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
+ dump_double(frD);
+ printk("\n");
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/fctiwz.c b/arch/powerpc/math-emu/fctiwz.c
new file mode 100644
index 000000000000..7717eb6fcfb6
--- /dev/null
+++ b/arch/powerpc/math-emu/fctiwz.c
@@ -0,0 +1,32 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fctiwz(u32 *frD, void *frB)
+{
+ FP_DECL_D(B);
+ u32 fpscr;
+ unsigned int r;
+
+ fpscr = __FPU_FPSCR;
+ __FPU_FPSCR &= ~(3);
+ __FPU_FPSCR |= FP_RND_ZERO;
+
+ __FP_UNPACK_D(B, frB);
+ FP_TO_INT_D(r, B, 32, 1);
+ frD[1] = r;
+
+ __FPU_FPSCR = fpscr;
+
+#ifdef DEBUG
+ printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
+ dump_double(frD);
+ printk("\n");
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c
new file mode 100644
index 000000000000..f2fba825b2d0
--- /dev/null
+++ b/arch/powerpc/math-emu/fdiv.c
@@ -0,0 +1,53 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fdiv(void *frD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(R);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
+ ret |= EFLAG_VXZDZ;
+#ifdef DEBUG
+ printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
+#endif
+ }
+ if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
+ ret |= EFLAG_VXIDI;
+#ifdef DEBUG
+ printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
+#endif
+ }
+
+ 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);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_D(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c
new file mode 100644
index 000000000000..b971196e3175
--- /dev/null
+++ b/arch/powerpc/math-emu/fdivs.c
@@ -0,0 +1,55 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+
+int
+fdivs(void *frD, void *frA, void *frB)
+{
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(R);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+#endif
+
+ if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
+ ret |= EFLAG_VXZDZ;
+#ifdef DEBUG
+ printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
+#endif
+ }
+ if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
+ ret |= EFLAG_VXIDI;
+#ifdef DEBUG
+ printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
+#endif
+ }
+
+ 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);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_DS(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c
new file mode 100644
index 000000000000..0a1dbce793e9
--- /dev/null
+++ b/arch/powerpc/math-emu/fmadd.c
@@ -0,0 +1,48 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fmadd(void *frD, void *frA, void *frB, void *frC)
+{
+ FP_DECL_D(R);
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(C);
+ FP_DECL_D(T);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+ __FP_UNPACK_D(C, frC);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+ printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
+#endif
+
+ if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
+ (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
+ ret |= EFLAG_VXIMZ;
+
+ FP_MUL_D(T, A, C);
+
+ if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
+ ret |= EFLAG_VXISI;
+
+ FP_ADD_D(R, T, B);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_D(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c
new file mode 100644
index 000000000000..0f70bba9445e
--- /dev/null
+++ b/arch/powerpc/math-emu/fmadds.c
@@ -0,0 +1,49 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+
+int
+fmadds(void *frD, void *frA, void *frB, void *frC)
+{
+ FP_DECL_D(R);
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(C);
+ FP_DECL_D(T);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+ __FP_UNPACK_D(C, frC);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+ printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
+#endif
+
+ if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
+ (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
+ ret |= EFLAG_VXIMZ;
+
+ FP_MUL_D(T, A, C);
+
+ if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
+ ret |= EFLAG_VXISI;
+
+ FP_ADD_D(R, T, B);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_DS(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fmr.c b/arch/powerpc/math-emu/fmr.c
new file mode 100644
index 000000000000..28df700c0c7e
--- /dev/null
+++ b/arch/powerpc/math-emu/fmr.c
@@ -0,0 +1,18 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int
+fmr(u32 *frD, u32 *frB)
+{
+ frD[0] = frB[0];
+ frD[1] = frB[1];
+
+#ifdef DEBUG
+ printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
+ dump_double(frD);
+ printk("\n");
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c
new file mode 100644
index 000000000000..203fd48a6fec
--- /dev/null
+++ b/arch/powerpc/math-emu/fmsub.c
@@ -0,0 +1,51 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+fmsub(void *frD, void *frA, void *frB, void *frC)
+{
+ FP_DECL_D(R);
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(C);
+ FP_DECL_D(T);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+ __FP_UNPACK_D(C, frC);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+ printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
+#endif
+
+ if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
+ (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
+ ret |= EFLAG_VXIMZ;
+
+ FP_MUL_D(T, A, C);
+
+ if (B_c != FP_CLS_NAN)
+ B_s ^= 1;
+
+ if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
+ ret |= EFLAG_VXISI;
+
+ FP_ADD_D(R, T, B);
+
+#ifdef DEBUG
+ printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
+#endif
+
+ return (ret | __FP_PACK_D(frD, R));
+}
diff --git a/arch/powerpc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c
new file mode 100644
index 000000000000..8ce68624c189
--- /dev/null
+++ b/arch/powerpc/math-emu/fmsubs.c
@@ -0,0 +1,52 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+
+int
+fmsubs(void *frD, void *frA, void *frB, void *frC)
+{
+ FP_DECL_D(R);
+ FP_DECL_D(A);
+ FP_DECL_D(B);
+ FP_DECL_D(C);
+ FP_DECL_D(T);
+ int ret = 0;
+
+#ifdef DEBUG
+ printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
+#endif
+
+ __FP_UNPACK_D(A, frA);
+ __FP_UNPACK_D(B, frB);
+ __FP_UNPACK_D(C, frC);
+
+#ifdef DEBUG
+ printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
+ printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
+ printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
+#endif
+
+ if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
+ (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
+ ret |= EFLAG_VXIMZ;
<