]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/mips/math-emu/cp1emu.c
MIPS: math-emu: Header file weeding.
[karo-tx-linux.git] / arch / mips / math-emu / cp1emu.c
index 0b4e2e38294bf174132fcb4036cc958a370cfbec..3ef9d99a729ed238d681eea0554305450c1adce7 100644 (file)
  * better performance by compiling with -msoft-float!
  */
 #include <linux/sched.h>
-#include <linux/module.h>
 #include <linux/debugfs.h>
 #include <linux/perf_event.h>
 
+#include <asm/branch.h>
 #include <asm/inst.h>
-#include <asm/bootinfo.h>
-#include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
-#include <asm/mipsregs.h>
+#include <asm/uaccess.h>
+
+#include <asm/processor.h>
 #include <asm/fpu_emulator.h>
 #include <asm/fpu.h>
-#include <asm/uaccess.h>
-#include <asm/branch.h>
 
 #include "ieee754.h"
 
@@ -876,20 +874,43 @@ static inline int cop1_64bit(struct pt_regs *xcp)
 #endif
 }
 
-#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
-                       (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
-
-#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
-                       cop1_64bit(xcp) || !(x & 1) ? \
-                       ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
-                       ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
-
-#define SIFROMHREG(si, x)      ((si) = (int)(ctx->fpr[x] >> 32))
-#define SITOHREG(si, x)                (ctx->fpr[x] = \
-                               ctx->fpr[x] << 32 >> 32 | (u64)(si) << 32)
-
-#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
-#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
+#define SIFROMREG(si, x) do {                                          \
+       if (cop1_64bit(xcp))                                            \
+               (si) = get_fpr32(&ctx->fpr[x], 0);                      \
+       else                                                            \
+               (si) = get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1);         \
+} while (0)
+
+#define SITOREG(si, x) do {                                            \
+       if (cop1_64bit(xcp)) {                                          \
+               unsigned i;                                             \
+               set_fpr32(&ctx->fpr[x], 0, si);                         \
+               for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)     \
+                       set_fpr32(&ctx->fpr[x], i, 0);                  \
+       } else {                                                        \
+               set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si);            \
+       }                                                               \
+} while (0)
+
+#define SIFROMHREG(si, x)      ((si) = get_fpr32(&ctx->fpr[x], 1))
+
+#define SITOHREG(si, x) do {                                           \
+       unsigned i;                                                     \
+       set_fpr32(&ctx->fpr[x], 1, si);                                 \
+       for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)             \
+               set_fpr32(&ctx->fpr[x], i, 0);                          \
+} while (0)
+
+#define DIFROMREG(di, x) \
+       ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0))
+
+#define DITOREG(di, x) do {                                            \
+       unsigned fpr, i;                                                \
+       fpr = (x) & ~(cop1_64bit(xcp) == 0);                            \
+       set_fpr64(&ctx->fpr[fpr], 0, di);                               \
+       for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++)             \
+               set_fpr64(&ctx->fpr[fpr], i, 0);                        \
+} while (0)
 
 #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
 #define SPTOREG(sp, x) SITOREG((sp).bits, x)
@@ -910,17 +931,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        int pc_inc;
 
        /* XXX NEC Vr54xx bug workaround */
-       if (xcp->cp0_cause & CAUSEF_BD) {
+       if (delay_slot(xcp)) {
                if (dec_insn.micro_mips_mode) {
                        if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
-                               xcp->cp0_cause &= ~CAUSEF_BD;
+                               clear_delay_slot(xcp);
                } else {
                        if (!isBranchInstr(xcp, dec_insn, &contpc))
-                               xcp->cp0_cause &= ~CAUSEF_BD;
+                               clear_delay_slot(xcp);
                }
        }
 
-       if (xcp->cp0_cause & CAUSEF_BD) {
+       if (delay_slot(xcp)) {
                /*
                 * The instruction to be emulated is in a branch delay slot
                 * which means that we have to  emulate the branch instruction
@@ -1155,7 +1176,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case bc_op:{
                        int likely = 0;
 
-                       if (xcp->cp0_cause & CAUSEF_BD)
+                       if (delay_slot(xcp))
                                return SIGILL;
 
 #if __mips >= 4
@@ -1178,7 +1199,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                return SIGILL;
                        }
 
-                       xcp->cp0_cause |= CAUSEF_BD;
+                       set_delay_slot(xcp);
                        if (cond) {
                                /* branch taken: emulate dslot
                                 * instruction
@@ -1298,7 +1319,7 @@ sigill:
 
        /* we did it !! */
        xcp->cp0_epc = contpc;
-       xcp->cp0_cause &= ~CAUSEF_BD;
+       clear_delay_slot(xcp);
 
        return 0;
 }
@@ -1326,8 +1347,8 @@ static const unsigned char cmptab[8] = {
  */
 
 #define DEF3OP(name, p, f1, f2, f3) \
-static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
-    ieee754##p t) \
+static union ieee754##p fpemu_##p##_##name(union ieee754##p r, union ieee754##p s, \
+    union ieee754##p t) \
 { \
        struct _ieee754_csr ieee754_csr_save; \
        s = f1(s, t); \
@@ -1341,22 +1362,22 @@ static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
        return s; \
 }
 
-static ieee754dp fpemu_dp_recip(ieee754dp d)
+static union ieee754dp fpemu_dp_recip(union ieee754dp d)
 {
        return ieee754dp_div(ieee754dp_one(0), d);
 }
 
-static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
+static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
 {
        return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
 }
 
-static ieee754sp fpemu_sp_recip(ieee754sp s)
+static union ieee754sp fpemu_sp_recip(union ieee754sp s)
 {
        return ieee754sp_div(ieee754sp_one(0), s);
 }
 
-static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
+static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
 {
        return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
 }
@@ -1380,8 +1401,8 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        switch (MIPSInst_FMA_FFMT(ir)) {
        case s_fmt:{            /* 0 */
 
-               ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
-               ieee754sp fd, fr, fs, ft;
+               union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
+               union ieee754sp fd, fr, fs, ft;
                u32 __user *va;
                u32 val;
 
@@ -1469,8 +1490,8 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        }
 
        case d_fmt:{            /* 1 */
-               ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
-               ieee754dp fd, fr, fs, ft;
+               union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
+               union ieee754dp fd, fr, fs, ft;
                u64 __user *va;
                u64 val;
 
@@ -1565,8 +1586,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        unsigned rcsr = 0;      /* resulting csr */
        unsigned cond;
        union {
-               ieee754dp d;
-               ieee754sp s;
+               union ieee754dp d;
+               union ieee754sp s;
                int w;
 #ifdef __mips64
                s64 l;
@@ -1577,8 +1598,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
        case s_fmt:{            /* 0 */
                union {
-                       ieee754sp(*b) (ieee754sp, ieee754sp);
-                       ieee754sp(*u) (ieee754sp);
+                       union ieee754sp(*b) (union ieee754sp, union ieee754sp);
+                       union ieee754sp(*u) (union ieee754sp);
                } handler;
 
                switch (MIPSInst_FUNC(ir)) {
@@ -1643,7 +1664,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        /* binary op on handler */
                      scopbop:
                        {
-                               ieee754sp fs, ft;
+                               union ieee754sp fs, ft;
 
                                SPFROMREG(fs, MIPSInst_FS(ir));
                                SPFROMREG(ft, MIPSInst_FT(ir));
@@ -1653,7 +1674,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        }
                      scopuop:
                        {
-                               ieee754sp fs;
+                               union ieee754sp fs;
 
                                SPFROMREG(fs, MIPSInst_FS(ir));
                                rv.s = (*handler.u) (fs);
@@ -1676,7 +1697,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case fcvts_op:
                        return SIGILL;  /* not defined */
                case fcvtd_op:{
-                       ieee754sp fs;
+                       union ieee754sp fs;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
                        rv.d = ieee754dp_fsp(fs);
@@ -1684,7 +1705,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        goto copcsr;
                }
                case fcvtw_op:{
-                       ieee754sp fs;
+                       union ieee754sp fs;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
                        rv.w = ieee754sp_tint(fs);
@@ -1698,7 +1719,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case fceil_op:
                case ffloor_op:{
                        unsigned int oldrm = ieee754_csr.rm;
-                       ieee754sp fs;
+                       union ieee754sp fs;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
                        ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
@@ -1711,7 +1732,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
 #if defined(__mips64)
                case fcvtl_op:{
-                       ieee754sp fs;
+                       union ieee754sp fs;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
                        rv.l = ieee754sp_tlong(fs);
@@ -1724,7 +1745,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case fceill_op:
                case ffloorl_op:{
                        unsigned int oldrm = ieee754_csr.rm;
-                       ieee754sp fs;
+                       union ieee754sp fs;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
                        ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
@@ -1738,7 +1759,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                default:
                        if (MIPSInst_FUNC(ir) >= fcmp_op) {
                                unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-                               ieee754sp fs, ft;
+                               union ieee754sp fs, ft;
 
                                SPFROMREG(fs, MIPSInst_FS(ir));
                                SPFROMREG(ft, MIPSInst_FT(ir));
@@ -1762,8 +1783,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
        case d_fmt:{
                union {
-                       ieee754dp(*b) (ieee754dp, ieee754dp);
-                       ieee754dp(*u) (ieee754dp);
+                       union ieee754dp(*b) (union ieee754dp, union ieee754dp);
+                       union ieee754dp(*u) (union ieee754dp);
                } handler;
 
                switch (MIPSInst_FUNC(ir)) {
@@ -1829,7 +1850,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        /* binary op on handler */
                      dcopbop:{
-                               ieee754dp fs, ft;
+                               union ieee754dp fs, ft;
 
                                DPFROMREG(fs, MIPSInst_FS(ir));
                                DPFROMREG(ft, MIPSInst_FT(ir));
@@ -1838,7 +1859,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                goto copcsr;
                        }
                      dcopuop:{
-                               ieee754dp fs;
+                               union ieee754dp fs;
 
                                DPFROMREG(fs, MIPSInst_FS(ir));
                                rv.d = (*handler.u) (fs);
@@ -1847,7 +1868,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        /* unary conv ops */
                case fcvts_op:{
-                       ieee754dp fs;
+                       union ieee754dp fs;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
                        rv.s = ieee754sp_fdp(fs);
@@ -1858,7 +1879,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        return SIGILL;  /* not defined */
 
                case fcvtw_op:{
-                       ieee754dp fs;
+                       union ieee754dp fs;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
                        rv.w = ieee754dp_tint(fs);      /* wrong */
@@ -1872,7 +1893,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case fceil_op:
                case ffloor_op:{
                        unsigned int oldrm = ieee754_csr.rm;
-                       ieee754dp fs;
+                       union ieee754dp fs;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
                        ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
@@ -1885,7 +1906,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
 #if defined(__mips64)
                case fcvtl_op:{
-                       ieee754dp fs;
+                       union ieee754dp fs;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
                        rv.l = ieee754dp_tlong(fs);
@@ -1898,7 +1919,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                case fceill_op:
                case ffloorl_op:{
                        unsigned int oldrm = ieee754_csr.rm;
-                       ieee754dp fs;
+                       union ieee754dp fs;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
                        ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
@@ -1912,7 +1933,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                default:
                        if (MIPSInst_FUNC(ir) >= fcmp_op) {
                                unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-                               ieee754dp fs, ft;
+                               union ieee754dp fs, ft;
 
                                DPFROMREG(fs, MIPSInst_FS(ir));
                                DPFROMREG(ft, MIPSInst_FT(ir));
@@ -1937,7 +1958,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        }
 
        case w_fmt:{
-               ieee754sp fs;
+               union ieee754sp fs;
 
                switch (MIPSInst_FUNC(ir)) {
                case fcvts_op:
@@ -1960,15 +1981,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
 #if defined(__mips64)
        case l_fmt:{
+               u64 bits;
+               DIFROMREG(bits, MIPSInst_FS(ir));
+
                switch (MIPSInst_FUNC(ir)) {
                case fcvts_op:
                        /* convert long to single precision real */
-                       rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+                       rv.s = ieee754sp_flong(bits);
                        rfmt = s_fmt;
                        goto copcsr;
                case fcvtd_op:
                        /* convert long to double precision real */
-                       rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+                       rv.d = ieee754dp_flong(bits);
                        rfmt = d_fmt;
                        goto copcsr;
                default: