aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/math-emu/math_efp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/math-emu/math_efp.c')
-rw-r--r--arch/powerpc/math-emu/math_efp.c100
1 files changed, 48 insertions, 52 deletions
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
index 62279200d965..a73f0884d358 100644
--- a/arch/powerpc/math-emu/math_efp.c
+++ b/arch/powerpc/math-emu/math_efp.c
@@ -171,10 +171,6 @@ static unsigned long insn_type(unsigned long speinsn)
171 case EFDNABS: ret = XA; break; 171 case EFDNABS: ret = XA; break;
172 case EFDNEG: ret = XA; break; 172 case EFDNEG: ret = XA; break;
173 case EFDSUB: ret = AB; break; 173 case EFDSUB: ret = AB; break;
174
175 default:
176 printk(KERN_ERR "\nOoops! SPE instruction no type found.");
177 printk(KERN_ERR "\ninst code: %08lx\n", speinsn);
178 } 174 }
179 175
180 return ret; 176 return ret;
@@ -195,7 +191,7 @@ int do_spe_mathemu(struct pt_regs *regs)
195 191
196 type = insn_type(speinsn); 192 type = insn_type(speinsn);
197 if (type == NOTYPE) 193 if (type == NOTYPE)
198 return -ENOSYS; 194 goto illegal;
199 195
200 func = speinsn & 0x7ff; 196 func = speinsn & 0x7ff;
201 fc = (speinsn >> 21) & 0x1f; 197 fc = (speinsn >> 21) & 0x1f;
@@ -212,12 +208,10 @@ int do_spe_mathemu(struct pt_regs *regs)
212 208
213 __FPU_FPSCR = mfspr(SPRN_SPEFSCR); 209 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
214 210
215#ifdef DEBUG 211 pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
216 printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); 212 pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
217 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); 213 pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]);
218 printk("va: %08x %08x\n", va.wp[0], va.wp[1]); 214 pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
219 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
220#endif
221 215
222 switch (src) { 216 switch (src) {
223 case SPFP: { 217 case SPFP: {
@@ -235,10 +229,8 @@ int do_spe_mathemu(struct pt_regs *regs)
235 break; 229 break;
236 } 230 }
237 231
238#ifdef DEBUG 232 pr_debug("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
239 printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c); 233 pr_debug("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
240 printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
241#endif
242 234
243 switch (func) { 235 switch (func) {
244 case EFSABS: 236 case EFSABS:
@@ -305,10 +297,10 @@ int do_spe_mathemu(struct pt_regs *regs)
305 FP_DECL_D(DB); 297 FP_DECL_D(DB);
306 FP_CLEAR_EXCEPTIONS; 298 FP_CLEAR_EXCEPTIONS;
307 FP_UNPACK_DP(DB, vb.dp); 299 FP_UNPACK_DP(DB, vb.dp);
308#ifdef DEBUG 300
309 printk("DB: %ld %08lx %08lx %ld (%ld)\n", 301 pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
310 DB_s, DB_f1, DB_f0, DB_e, DB_c); 302 DB_s, DB_f1, DB_f0, DB_e, DB_c);
311#endif 303
312 FP_CONV(S, D, 1, 2, SR, DB); 304 FP_CONV(S, D, 1, 2, SR, DB);
313 goto pack_s; 305 goto pack_s;
314 } 306 }
@@ -332,9 +324,8 @@ int do_spe_mathemu(struct pt_regs *regs)
332 break; 324 break;
333 325
334pack_s: 326pack_s:
335#ifdef DEBUG 327 pr_debug("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
336 printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c); 328
337#endif
338 FP_PACK_SP(vc.wp + 1, SR); 329 FP_PACK_SP(vc.wp + 1, SR);
339 goto update_regs; 330 goto update_regs;
340 331
@@ -365,12 +356,10 @@ cmp_s:
365 break; 356 break;
366 } 357 }
367 358
368#ifdef DEBUG 359 pr_debug("DA: %ld %08lx %08lx %ld (%ld)\n",
369 printk("DA: %ld %08lx %08lx %ld (%ld)\n",
370 DA_s, DA_f1, DA_f0, DA_e, DA_c); 360 DA_s, DA_f1, DA_f0, DA_e, DA_c);
371 printk("DB: %ld %08lx %08lx %ld (%ld)\n", 361 pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
372 DB_s, DB_f1, DB_f0, DB_e, DB_c); 362 DB_s, DB_f1, DB_f0, DB_e, DB_c);
373#endif
374 363
375 switch (func) { 364 switch (func) {
376 case EFDABS: 365 case EFDABS:
@@ -438,10 +427,10 @@ cmp_s:
438 FP_DECL_S(SB); 427 FP_DECL_S(SB);
439 FP_CLEAR_EXCEPTIONS; 428 FP_CLEAR_EXCEPTIONS;
440 FP_UNPACK_SP(SB, vb.wp + 1); 429 FP_UNPACK_SP(SB, vb.wp + 1);
441#ifdef DEBUG 430
442 printk("SB: %ld %08lx %ld (%ld)\n", 431 pr_debug("SB: %ld %08lx %ld (%ld)\n",
443 SB_s, SB_f, SB_e, SB_c); 432 SB_s, SB_f, SB_e, SB_c);
444#endif 433
445 FP_CONV(D, S, 2, 1, DR, SB); 434 FP_CONV(D, S, 2, 1, DR, SB);
446 goto pack_d; 435 goto pack_d;
447 } 436 }
@@ -471,10 +460,9 @@ cmp_s:
471 break; 460 break;
472 461
473pack_d: 462pack_d:
474#ifdef DEBUG 463 pr_debug("DR: %ld %08lx %08lx %ld (%ld)\n",
475 printk("DR: %ld %08lx %08lx %ld (%ld)\n",
476 DR_s, DR_f1, DR_f0, DR_e, DR_c); 464 DR_s, DR_f1, DR_f0, DR_e, DR_c);
477#endif 465
478 FP_PACK_DP(vc.dp, DR); 466 FP_PACK_DP(vc.dp, DR);
479 goto update_regs; 467 goto update_regs;
480 468
@@ -511,12 +499,14 @@ cmp_d:
511 break; 499 break;
512 } 500 }
513 501
514#ifdef DEBUG 502 pr_debug("SA0: %ld %08lx %ld (%ld)\n",
515 printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c); 503 SA0_s, SA0_f, SA0_e, SA0_c);
516 printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c); 504 pr_debug("SA1: %ld %08lx %ld (%ld)\n",
517 printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c); 505 SA1_s, SA1_f, SA1_e, SA1_c);
518 printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c); 506 pr_debug("SB0: %ld %08lx %ld (%ld)\n",
519#endif 507 SB0_s, SB0_f, SB0_e, SB0_c);
508 pr_debug("SB1: %ld %08lx %ld (%ld)\n",
509 SB1_s, SB1_f, SB1_e, SB1_c);
520 510
521 switch (func) { 511 switch (func) {
522 case EVFSABS: 512 case EVFSABS:
@@ -605,10 +595,11 @@ cmp_d:
605 break; 595 break;
606 596
607pack_vs: 597pack_vs:
608#ifdef DEBUG 598 pr_debug("SR0: %ld %08lx %ld (%ld)\n",
609 printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c); 599 SR0_s, SR0_f, SR0_e, SR0_c);
610 printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c); 600 pr_debug("SR1: %ld %08lx %ld (%ld)\n",
611#endif 601 SR1_s, SR1_f, SR1_e, SR1_c);
602
612 FP_PACK_SP(vc.wp, SR0); 603 FP_PACK_SP(vc.wp, SR0);
613 FP_PACK_SP(vc.wp + 1, SR1); 604 FP_PACK_SP(vc.wp + 1, SR1);
614 goto update_regs; 605 goto update_regs;
@@ -646,14 +637,12 @@ update_regs:
646 current->thread.evr[fc] = vc.wp[0]; 637 current->thread.evr[fc] = vc.wp[0];
647 regs->gpr[fc] = vc.wp[1]; 638 regs->gpr[fc] = vc.wp[1];
648 639
649#ifdef DEBUG 640 pr_debug("ccr = %08lx\n", regs->ccr);
650 printk("ccr = %08lx\n", regs->ccr); 641 pr_debug("cur exceptions = %08x spefscr = %08lx\n",
651 printk("cur exceptions = %08x spefscr = %08lx\n",
652 FP_CUR_EXCEPTIONS, __FPU_FPSCR); 642 FP_CUR_EXCEPTIONS, __FPU_FPSCR);
653 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); 643 pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
654 printk("va: %08x %08x\n", va.wp[0], va.wp[1]); 644 pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]);
655 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); 645 pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
656#endif
657 646
658 return 0; 647 return 0;
659 648
@@ -661,9 +650,7 @@ illegal:
661 if (have_e500_cpu_a005_erratum) { 650 if (have_e500_cpu_a005_erratum) {
662 /* according to e500 cpu a005 erratum, reissue efp inst */ 651 /* according to e500 cpu a005 erratum, reissue efp inst */
663 regs->nip -= 4; 652 regs->nip -= 4;
664#ifdef DEBUG 653 pr_debug("re-issue efp inst: %08lx\n", speinsn);
665 printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
666#endif
667 return 0; 654 return 0;
668 } 655 }
669 656
@@ -685,13 +672,20 @@ int speround_handler(struct pt_regs *regs)
685 type = insn_type(speinsn & 0x7ff); 672 type = insn_type(speinsn & 0x7ff);
686 if (type == XCR) return -ENOSYS; 673 if (type == XCR) return -ENOSYS;
687 674
675 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
676 pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
677
678 /* No need to round if the result is exact */
679 if (!(__FPU_FPSCR & FP_EX_INEXACT))
680 return 0;
681
688 fc = (speinsn >> 21) & 0x1f; 682 fc = (speinsn >> 21) & 0x1f;
689 s_lo = regs->gpr[fc] & SIGN_BIT_S; 683 s_lo = regs->gpr[fc] & SIGN_BIT_S;
690 s_hi = current->thread.evr[fc] & SIGN_BIT_S; 684 s_hi = current->thread.evr[fc] & SIGN_BIT_S;
691 fgpr.wp[0] = current->thread.evr[fc]; 685 fgpr.wp[0] = current->thread.evr[fc];
692 fgpr.wp[1] = regs->gpr[fc]; 686 fgpr.wp[1] = regs->gpr[fc];
693 687
694 __FPU_FPSCR = mfspr(SPRN_SPEFSCR); 688 pr_debug("round fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
695 689
696 switch ((speinsn >> 5) & 0x7) { 690 switch ((speinsn >> 5) & 0x7) {
697 /* Since SPE instructions on E500 core can handle round to nearest 691 /* Since SPE instructions on E500 core can handle round to nearest
@@ -731,6 +725,8 @@ int speround_handler(struct pt_regs *regs)
731 current->thread.evr[fc] = fgpr.wp[0]; 725 current->thread.evr[fc] = fgpr.wp[0];
732 regs->gpr[fc] = fgpr.wp[1]; 726 regs->gpr[fc] = fgpr.wp[1];
733 727
728 pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
729
734 return 0; 730 return 0;
735} 731}
736 732