Merge branch 'fortglx/3.3/tip/timers/core' of git://git.linaro.org/people/jstultz...
[cascardo/linux.git] / arch / powerpc / math-emu / math_efp.c
index 6227920..a73f088 100644 (file)
@@ -171,10 +171,6 @@ static unsigned long insn_type(unsigned long speinsn)
        case EFDNABS:   ret = XA;       break;
        case EFDNEG:    ret = XA;       break;
        case EFDSUB:    ret = AB;       break;
-
-       default:
-               printk(KERN_ERR "\nOoops! SPE instruction no type found.");
-               printk(KERN_ERR "\ninst code: %08lx\n", speinsn);
        }
 
        return ret;
@@ -195,7 +191,7 @@ int do_spe_mathemu(struct pt_regs *regs)
 
        type = insn_type(speinsn);
        if (type == NOTYPE)
-               return -ENOSYS;
+               goto illegal;
 
        func = speinsn & 0x7ff;
        fc = (speinsn >> 21) & 0x1f;
@@ -212,12 +208,10 @@ int do_spe_mathemu(struct pt_regs *regs)
 
        __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
 
-#ifdef DEBUG
-       printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
-       printk("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
-       printk("va: %08x  %08x\n", va.wp[0], va.wp[1]);
-       printk("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
-#endif
+       pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
+       pr_debug("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
+       pr_debug("va: %08x  %08x\n", va.wp[0], va.wp[1]);
+       pr_debug("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
 
        switch (src) {
        case SPFP: {
@@ -235,10 +229,8 @@ int do_spe_mathemu(struct pt_regs *regs)
                        break;
                }
 
-#ifdef DEBUG
-               printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
-               printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
-#endif
+               pr_debug("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
+               pr_debug("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
 
                switch (func) {
                case EFSABS:
@@ -305,10 +297,10 @@ int do_spe_mathemu(struct pt_regs *regs)
                        FP_DECL_D(DB);
                        FP_CLEAR_EXCEPTIONS;
                        FP_UNPACK_DP(DB, vb.dp);
-#ifdef DEBUG
-                       printk("DB: %ld %08lx %08lx %ld (%ld)\n",
+
+                       pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
                                        DB_s, DB_f1, DB_f0, DB_e, DB_c);
-#endif
+
                        FP_CONV(S, D, 1, 2, SR, DB);
                        goto pack_s;
                }
@@ -332,9 +324,8 @@ int do_spe_mathemu(struct pt_regs *regs)
                break;
 
 pack_s:
-#ifdef DEBUG
-               printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
-#endif
+               pr_debug("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
+
                FP_PACK_SP(vc.wp + 1, SR);
                goto update_regs;
 
@@ -365,12 +356,10 @@ cmp_s:
                        break;
                }
 
-#ifdef DEBUG
-               printk("DA: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DA: %ld %08lx %08lx %ld (%ld)\n",
                                DA_s, DA_f1, DA_f0, DA_e, DA_c);
-               printk("DB: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
                                DB_s, DB_f1, DB_f0, DB_e, DB_c);
-#endif
 
                switch (func) {
                case EFDABS:
@@ -438,10 +427,10 @@ cmp_s:
                        FP_DECL_S(SB);
                        FP_CLEAR_EXCEPTIONS;
                        FP_UNPACK_SP(SB, vb.wp + 1);
-#ifdef DEBUG
-                       printk("SB: %ld %08lx %ld (%ld)\n",
+
+                       pr_debug("SB: %ld %08lx %ld (%ld)\n",
                                        SB_s, SB_f, SB_e, SB_c);
-#endif
+
                        FP_CONV(D, S, 2, 1, DR, SB);
                        goto pack_d;
                }
@@ -471,10 +460,9 @@ cmp_s:
                break;
 
 pack_d:
-#ifdef DEBUG
-               printk("DR: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DR: %ld %08lx %08lx %ld (%ld)\n",
                                DR_s, DR_f1, DR_f0, DR_e, DR_c);
-#endif
+
                FP_PACK_DP(vc.dp, DR);
                goto update_regs;
 
@@ -511,12 +499,14 @@ cmp_d:
                        break;
                }
 
-#ifdef DEBUG
-               printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c);
-               printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c);
-               printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c);
-               printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c);
-#endif
+               pr_debug("SA0: %ld %08lx %ld (%ld)\n",
+                               SA0_s, SA0_f, SA0_e, SA0_c);
+               pr_debug("SA1: %ld %08lx %ld (%ld)\n",
+                               SA1_s, SA1_f, SA1_e, SA1_c);
+               pr_debug("SB0: %ld %08lx %ld (%ld)\n",
+                               SB0_s, SB0_f, SB0_e, SB0_c);
+               pr_debug("SB1: %ld %08lx %ld (%ld)\n",
+                               SB1_s, SB1_f, SB1_e, SB1_c);
 
                switch (func) {
                case EVFSABS:
@@ -605,10 +595,11 @@ cmp_d:
                break;
 
 pack_vs:
-#ifdef DEBUG
-               printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c);
-               printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c);
-#endif
+               pr_debug("SR0: %ld %08lx %ld (%ld)\n",
+                               SR0_s, SR0_f, SR0_e, SR0_c);
+               pr_debug("SR1: %ld %08lx %ld (%ld)\n",
+                               SR1_s, SR1_f, SR1_e, SR1_c);
+
                FP_PACK_SP(vc.wp, SR0);
                FP_PACK_SP(vc.wp + 1, SR1);
                goto update_regs;
@@ -646,14 +637,12 @@ update_regs:
        current->thread.evr[fc] = vc.wp[0];
        regs->gpr[fc] = vc.wp[1];
 
-#ifdef DEBUG
-       printk("ccr = %08lx\n", regs->ccr);
-       printk("cur exceptions = %08x spefscr = %08lx\n",
+       pr_debug("ccr = %08lx\n", regs->ccr);
+       pr_debug("cur exceptions = %08x spefscr = %08lx\n",
                        FP_CUR_EXCEPTIONS, __FPU_FPSCR);
-       printk("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
-       printk("va: %08x  %08x\n", va.wp[0], va.wp[1]);
-       printk("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
-#endif
+       pr_debug("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
+       pr_debug("va: %08x  %08x\n", va.wp[0], va.wp[1]);
+       pr_debug("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
 
        return 0;
 
@@ -661,9 +650,7 @@ illegal:
        if (have_e500_cpu_a005_erratum) {
                /* according to e500 cpu a005 erratum, reissue efp inst */
                regs->nip -= 4;
-#ifdef DEBUG
-               printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
-#endif
+               pr_debug("re-issue efp inst: %08lx\n", speinsn);
                return 0;
        }
 
@@ -685,13 +672,20 @@ int speround_handler(struct pt_regs *regs)
        type = insn_type(speinsn & 0x7ff);
        if (type == XCR) return -ENOSYS;
 
+       __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
+       pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
+
+       /* No need to round if the result is exact */
+       if (!(__FPU_FPSCR & FP_EX_INEXACT))
+               return 0;
+
        fc = (speinsn >> 21) & 0x1f;
        s_lo = regs->gpr[fc] & SIGN_BIT_S;
        s_hi = current->thread.evr[fc] & SIGN_BIT_S;
        fgpr.wp[0] = current->thread.evr[fc];
        fgpr.wp[1] = regs->gpr[fc];
 
-       __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
+       pr_debug("round fgpr: %08x  %08x\n", fgpr.wp[0], fgpr.wp[1]);
 
        switch ((speinsn >> 5) & 0x7) {
        /* Since SPE instructions on E500 core can handle round to nearest
@@ -731,6 +725,8 @@ int speround_handler(struct pt_regs *regs)
        current->thread.evr[fc] = fgpr.wp[0];
        regs->gpr[fc] = fgpr.wp[1];
 
+       pr_debug("  to fgpr: %08x  %08x\n", fgpr.wp[0], fgpr.wp[1]);
+
        return 0;
 }