* [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
@ 2007-02-08 3:55 ebony.zhu
2007-02-08 7:32 ` Kumar Gala
2007-02-22 12:48 ` Sergei Shtylyov
0 siblings, 2 replies; 17+ messages in thread
From: ebony.zhu @ 2007-02-08 3:55 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Add the general support for Embedded Floating-Point instructions
to fully comply with IEEE-754.
Signed-off-by:Ebony Zhu <ebony.zhu@freescale.com>
---
arch/powerpc/kernel/head_fsl_booke.S | 4
arch/powerpc/kernel/traps.c | 57 +++++
arch/powerpc/math-emu/Makefile | 25 ++
arch/powerpc/math-emu/sfp-machine.h | 2
arch/powerpc/math-emu/spe.h | 1
arch/powerpc/sysdev/Makefile | 1
arch/powerpc/sysdev/sigfpe_handler.c | 361 ++++++++++++++++++++++++++++++++++
7 files changed, 442 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 66877bd..0d05db0 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -705,7 +705,7 @@ #else
#endif /* CONFIG_SPE */
/* SPE Floating Point Round */
- EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointException_Round, EXC_XFER_EE)
/* Performance Monitor */
EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
@@ -840,6 +840,8 @@ load_up_spe:
oris r5,r5,MSR_SPE@h
mtmsr r5 /* enable use of SPE now */
isync
+ li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE)
+ mtspr SPRN_SPEFSCR,r5
/*
* For SMP, we don't do lazy SPE switching because it just gets too
* horrendously complex, especially when a task switches from one CPU
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6915b91..30ab0f7 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -986,9 +986,16 @@ #endif /* CONFIG_FSL_BOOKE */
#ifdef CONFIG_SPE
void SPEFloatingPointException(struct pt_regs *regs)
{
+ extern int spedata_handler(struct pt_regs *regs);
unsigned long spefscr;
int fpexc_mode;
int code = 0;
+ int err;
+
+ preempt_disable();
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+ preempt_enable();
spefscr = current->thread.spefscr;
fpexc_mode = current->thread.fpexc_mode;
@@ -1013,9 +1020,55 @@ void SPEFloatingPointException(struct pt
code = FPE_FLTRES;
current->thread.spefscr = spefscr;
+ err = spedata_handler(regs);
+ if (err == 0) {
+ regs->nip += 4; /* skip emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
- _exception(SIGFPE, regs, code, regs->nip);
- return;
+ if (err == -EFAULT) {
+ /* got an error reading the instruction */
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
+ } else if (err == -EINVAL) {
+ /* didn't recognize the instruction */
+ printk(KERN_ERR "unrecognized spe instruction "
+ "in %s at %lx\n", current->comm, regs->nip);
+ } else {
+ _exception(SIGFPE, regs, code, regs->nip);
+ return;
+ }
+}
+
+void SPEFloatingPointException_Round(struct pt_regs *regs)
+{
+ extern int speround_handler(struct pt_regs *regs);
+ int err;
+
+ preempt_disable();
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+ preempt_enable();
+
+ regs->nip -= 4;
+ err = speround_handler(regs);
+ if (err == 0) {
+ regs->nip += 4; /* skip emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ if (err == -EFAULT) {
+ /* got an error reading the instruction */
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
+ } else if (err == -EINVAL) {
+ /* didn't recognize the instruction */
+ printk(KERN_ERR "unrecognized spe instruction "
+ "in %s at %lx\n", current->comm, regs->nip);
+ } else {
+ _exception(SIGFPE, regs, 0, regs->nip);
+ return;
+ }
}
#endif
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 29bc912..2da11ba 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -1,16 +1,29 @@
-obj-y := math.o fmr.o lfd.o stfd.o
-
-obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
+obj-y := fabs.o fneg.o types.o udivmodti4.o
+
+obj-$(CONFIG_MATH_EMULATION) += math.o fmr.o lfd.o stfd.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 \
+ fmul.o fmuls.o fnabs.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
+ mtfsf.o mtfsfi.o stfiwx.o stfs.o
+
+obj-$(CONFIG_SPE) += efsabs.o efsadd.o efscfd.o efscmpeq.o \
+ efscmpgt.o efscmplt.o efsctsf.o efsctsi.o \
+ efsctsiz.o efsctuf.o efsctui.o efsctuiz.o \
+ efsdiv.o efsmul.o efsnabs.o efsneg.o efssub.o \
+ evfsabs.o evfsadd.o evfscmpeq.o evfscmpgt.o \
+ evfscmplt.o evfsctsf.o evfsctsi.o evfsctsiz.o \
+ evfsctuf.o evfsctui.o evfsctuiz.o evfsdiv.o \
+ evfsmul.o evfsnabs.o evfsneg.o evfssub.o \
+ efdadd.o efdcfs.o efdcmpeq.o efdcmpgt.o efdcmplt.o \
+ efdctsf.o efdctsi.o efdctsidz.o efdctsiz.o efdctuf.o \
+ efdctui.o efdctuidz.o efdctuiz.o efddiv.o efdmul.o \
+ efdnabs.o efdsub.o
CFLAGS_fabs.o = -fno-builtin-fabs
CFLAGS_math.o = -fno-builtin-fabs
diff --git a/arch/powerpc/math-emu/sfp-machine.h b/arch/powerpc/math-emu/sfp-machine.h
index 4b17d83..07de8ef 100644
--- a/arch/powerpc/math-emu/sfp-machine.h
+++ b/arch/powerpc/math-emu/sfp-machine.h
@@ -166,7 +166,9 @@ #define __FP_PACK_RAW_2(fs, val, X) \
#include <linux/kernel.h>
#include <linux/sched.h>
+#ifndef __FPU_FPSCR
#define __FPU_FPSCR (current->thread.fpscr.val)
+#endif
/* We only actually write to the destination register
* if exceptions signalled (if any) will not trap.
diff --git a/arch/powerpc/math-emu/spe.h b/arch/powerpc/math-emu/spe.h
new file mode 100644
index 0000000..4f63630
--- /dev/null
+++ b/arch/powerpc/math-emu/spe.h
@@ -0,0 +1 @@
+#define __FPU_FPSCR (current->thread.spefscr)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 2621a7e..47f88b6 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
+obj-$(CONFIG_SPE) += sigfpe_handler.o
ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/powerpc/sysdev/sigfpe_handler.c b/arch/powerpc/sysdev/sigfpe_handler.c
new file mode 100644
index 0000000..8f9cfdb
--- /dev/null
+++ b/arch/powerpc/sysdev/sigfpe_handler.c
@@ -0,0 +1,361 @@
+/*
+ * arch/powerpc/sysdev/sigfpe_handler.c
+ *
+ * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Ebony Zhu, ebony.zhu@freescale.com
+ *
+ * Derived from arch/powerpc/math-emu/math.c
+ * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com)
+ *
+ * Description:
+ * This file is the exception handler to make E500 SPE instructions
+ * fully comply with IEEE-754 floating point standard.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/reg.h>
+
+#define SPEFUNC(x) extern int x(void *, void *, void *, void *)
+#define efdabs fabs
+#define efdneg fneg
+
+/* Scalar SPFP functions */
+SPEFUNC(efsabs);
+SPEFUNC(efsadd);
+SPEFUNC(efscfd);
+SPEFUNC(efscmpeq);
+SPEFUNC(efscmpgt);
+SPEFUNC(efscmplt);
+SPEFUNC(efsctsf);
+SPEFUNC(efsctsi);
+SPEFUNC(efsctsiz);
+SPEFUNC(efsctuf);
+SPEFUNC(efsctui);
+SPEFUNC(efsctuiz);
+SPEFUNC(efsdiv);
+SPEFUNC(efsmul);
+SPEFUNC(efsnabs);
+SPEFUNC(efsneg);
+SPEFUNC(efssub);
+
+/* Vector Floating-Point functions */
+SPEFUNC(evfsabs);
+SPEFUNC(evfsadd);
+SPEFUNC(evfscmpeq);
+SPEFUNC(evfscmpgt);
+SPEFUNC(evfscmplt);
+SPEFUNC(evfsctsf);
+SPEFUNC(evfsctsi);
+SPEFUNC(evfsctsiz);
+SPEFUNC(evfsctuf);
+SPEFUNC(evfsctui);
+SPEFUNC(evfsctuiz);
+SPEFUNC(evfsdiv);
+SPEFUNC(evfsmul);
+SPEFUNC(evfsnabs);
+SPEFUNC(evfsneg);
+SPEFUNC(evfssub);
+
+/* Scalar DPFP functions */
+SPEFUNC(efdabs);
+SPEFUNC(efdadd);
+SPEFUNC(efdcfs);
+SPEFUNC(efdcmpeq);
+SPEFUNC(efdcmpgt);
+SPEFUNC(efdcmplt);
+SPEFUNC(efdctsf);
+SPEFUNC(efdctsi);
+SPEFUNC(efdctsidz);
+SPEFUNC(efdctsiz);
+SPEFUNC(efdctuf);
+SPEFUNC(efdctui);
+SPEFUNC(efdctuidz);
+SPEFUNC(efdctuiz);
+SPEFUNC(efddiv);
+SPEFUNC(efdmul);
+SPEFUNC(efdnabs);
+SPEFUNC(efdneg);
+SPEFUNC(efdsub);
+
+#define VCT 0x4
+#define SPFP 0x6
+#define DPFP 0x7
+#define EFAPU 0x4
+
+#define EFSADD 0x2c0
+#define EFSSUB 0x2c1
+#define EFSABS 0x2c4
+#define EFSNABS 0x2c5
+#define EFSNEG 0x2c6
+#define EFSMUL 0x2c8
+#define EFSDIV 0x2c9
+#define EFSCMPGT 0x2cc
+#define EFSCMPLT 0x2cd
+#define EFSCMPEQ 0x2ce
+#define EFSCFD 0x2cf
+#define EFSCTUI 0x2d4
+#define EFSCTSI 0x2d5
+#define EFSCTUF 0x2d6
+#define EFSCTSF 0x2d7
+#define EFSCTUIZ 0x2d8
+#define EFSCTSIZ 0x2da
+
+#define EVFSADD 0x280
+#define EVFSSUB 0x281
+#define EVFSABS 0x284
+#define EVFSNABS 0x285
+#define EVFSNEG 0x286
+#define EVFSMUL 0x288
+#define EVFSDIV 0x289
+#define EVFSCMPGT 0x28c
+#define EVFSCMPLT 0x28d
+#define EVFSCMPEQ 0x28e
+#define EVFSCTUI 0x294
+#define EVFSCTSI 0x295
+#define EVFSCTUF 0x296
+#define EVFSCTSF 0x297
+#define EVFSCTUIZ 0x298
+#define EVFSCTSIZ 0x29a
+
+#define EFDADD 0x2e0
+#define EFDSUB 0x2e1
+#define EFDABS 0x2e4
+#define EFDNABS 0x2e5
+#define EFDNEG 0x2e6
+#define EFDMUL 0x2e8
+#define EFDDIV 0x2e9
+#define EFDCTUIDZ 0x2ea
+#define EFDCTSIDZ 0x2eb
+#define EFDCMPGT 0x2ec
+#define EFDCMPLT 0x2ed
+#define EFDCMPEQ 0x2ee
+#define EFDCFS 0x2ef
+#define EFDCTUI 0x2f4
+#define EFDCTSI 0x2f5
+#define EFDCTUF 0x2f6
+#define EFDCTSF 0x2f7
+#define EFDCTUIZ 0x2f8
+#define EFDCTSIZ 0x2fa
+
+#define AB 2
+#define XA 3
+#define XB 4
+#define XCR 5
+
+static u64 fullgprs[32];
+static u32 speinsn;
+static int insn_decode(struct pt_regs *regs);
+static int (*func)(void *, void *, void *, void *);
+static void *op0 = 0, *op1 = 0, *op2 = 0, *op3 = 0;
+static int type = 0, flag;
+
+int
+spedata_handler(struct pt_regs *regs)
+{
+ int i;
+
+ if (get_user(speinsn, (unsigned int __user *) regs->nip))
+ return -EFAULT;
+ if ((speinsn >> 26) != 4)
+ return -EINVAL; /* not an spe instruction */
+ switch ((speinsn >> 5) & 0x7 ) {
+ case SPFP:
+ for(i = 0; i < 32; i++) {
+ fullgprs[i] = regs->gpr[i];
+ fullgprs[i] = fullgprs[i] << 32 | current->thread.evr[i];
+ };
+ break;
+ default:
+ for(i = 0; i < 32; i++) {
+ fullgprs[i] = current->thread.evr[i];
+ fullgprs[i] = (fullgprs[i] << 32) | (regs->gpr[i]);
+ };
+ }
+
+ if (insn_decode(regs) == -ENOSYS) return -ENOSYS;
+ flag = func(op0, op1, op2, op3);
+
+ switch ((speinsn >> 5) & 0x7 ) {
+ case SPFP:
+ for (i = 0; i < 32; i++) {
+ regs->gpr[i] = fullgprs[i] >> 32;
+ };
+ break;
+ default:
+ for (i = 0; i < 32; i++) {
+ regs->gpr[i] = fullgprs[i];
+ current->thread.evr[i] = fullgprs[i] >> 32;
+ };
+ }
+ return 0;
+}
+
+int
+speround_handler(struct pt_regs *regs)
+{
+ u32 lsb_lo, lsb_hi;
+ int s_lo, s_hi;
+ int rD;
+
+ if (get_user(speinsn, (unsigned int __user *) regs->nip))
+ return -EFAULT;
+ if ((speinsn >> 26) != 4)
+ return -EINVAL; /* not an spe instruction */
+
+ rD = (speinsn >> 21) & 0x1f;
+ flag = insn_decode(regs);
+ if (type == XCR) return -ENOSYS;
+
+ s_lo = (regs->gpr[rD] & 0x80000000) >> 31;
+ s_hi = (current->thread.evr[rD] & 0x80000000) >> 31;
+ lsb_lo = regs->gpr[rD];
+ lsb_hi = current->thread.evr[rD];
+ switch ((speinsn >> 5) & 0x7 ) {
+ /* Since SPE instructions on E500 core can handle round to nearest
+ * and round toward zero with IEEE-754 complied, we just need
+ * to handle round toward +Inf and round toward -Inf by software.
+ */
+ case SPFP:
+ if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
+ if (!s_lo) lsb_lo++; /* Z > 0, choose Z1 */
+ } else { /* round to -Inf */
+ if (s_lo) lsb_lo++; /* Z < 0, choose Z2 */
+ }
+ regs->gpr[rD] = lsb_lo;
+ break;
+ case DPFP:
+ fullgprs[rD] = current->thread.evr[rD];
+ fullgprs[rD] = (fullgprs[rD] << 32) | (regs->gpr[rD]);
+
+ if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
+ if (!s_hi) fullgprs[rD]++; /* Z > 0, choose Z1 */
+ } else { /* round to -Inf */
+ if (s_hi) fullgprs[rD]++; /* Z < 0, choose Z2 */
+ }
+ regs->gpr[rD] = fullgprs[rD];
+ current->thread.evr[rD] = fullgprs[rD] >> 32;
+ break;
+ case VCT:
+ if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
+ if (!s_lo) lsb_lo++; /* Z_low > 0, choose Z1 */
+ if (!s_hi) lsb_hi++; /* Z_high word > 0, choose Z1 */
+ } else { /* round to -Inf */
+ if (s_lo) lsb_lo++; /* Z_low < 0, choose Z2 */
+ if (s_hi) lsb_hi++; /* Z_high < 0, choose Z2 */
+ }
+ regs->gpr[rD] = lsb_lo;
+ current->thread.evr[rD] = lsb_hi;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int insn_decode(struct pt_regs *regs)
+{
+ switch (speinsn >> 26) {
+
+ case EFAPU:
+ switch (speinsn & 0x7ff) {
+ case EFSABS: func = efsabs; type = XA; break;
+ case EFSADD: func = efsadd; type = AB; break;
+ case EFSCFD: func = efscfd; type = XB; break;
+ case EFSCMPEQ: func = efscmpeq; type = XCR; break;
+ case EFSCMPGT: func = efscmpgt; type = XCR; break;
+ case EFSCMPLT: func = efscmplt; type = XCR; break;
+ case EFSCTSF: func = efsctsf; type = XB; break;
+ case EFSCTSI: func = efsctsi; type = XB; break;
+ case EFSCTSIZ: func = efsctsiz; type = XB; break;
+ case EFSCTUF: func = efsctuf; type = XB; break;
+ case EFSCTUI: func = efsctui; type = XB; break;
+ case EFSCTUIZ: func = efsctuiz; type = XB; break;
+ case EFSDIV: func = efsdiv; type = AB; break;
+ case EFSMUL: func = efsmul; type = AB; break;
+ case EFSNABS: func = efsnabs; type = XA; break;
+ case EFSNEG: func = efsneg; type = XA; break;
+ case EFSSUB: func = efssub; type = AB; break;
+
+ case EVFSABS: func = evfsabs; type = XA; break;
+ case EVFSADD: func = evfsadd; type = AB; break;
+ case EVFSCMPEQ: func = evfscmpeq; type = XCR; break;
+ case EVFSCMPGT: func = evfscmpgt; type = XCR; break;
+ case EVFSCMPLT: func = evfscmplt; type = XCR; break;
+ case EVFSCTSF: func = evfsctsf; type = XB; break;
+ case EVFSCTSI: func = evfsctsi; type = XB; break;
+ case EVFSCTSIZ: func = evfsctsiz; type = XB; break;
+ case EVFSCTUF: func = evfsctuf; type = XB; break;
+ case EVFSCTUI: func = evfsctui; type = XB; break;
+ case EVFSCTUIZ: func = evfsctuiz; type = XB; break;
+ case EVFSDIV: func = evfsdiv; type = AB; break;
+ case EVFSMUL: func = evfsmul; type = AB; break;
+ case EVFSNABS: func = evfsnabs; type = XA; break;
+ case EVFSNEG: func = evfsneg; type = XA; break;
+ case EVFSSUB: func = evfssub; type = AB; break;
+
+ case EFDABS: func = efdabs; type = XA; break;
+ case EFDADD: func = efdadd; type = AB; break;
+ case EFDCFS: func = efdcfs; type = XB; break;
+ case EFDCMPEQ: func = efdcmpeq; type = XCR; break;
+ case EFDCMPGT: func = efdcmpgt; type = XCR; break;
+ case EFDCMPLT: func = efdcmplt; type = XCR; break;
+ case EFDCTSF: func = efdctsf; type = XB; break;
+ case EFDCTSI: func = efdctsi; type = XB; break;
+ case EFDCTSIDZ: func = efdctsidz; type = XB; break;
+ case EFDCTSIZ: func = efdctsiz; type = XB; break;
+ case EFDCTUF: func = efdctuf; type = XB; break;
+ case EFDCTUI: func = efdctui; type = XB; break;
+ case EFDCTUIDZ: func = efdctuidz; type = XB; break;
+ case EFDCTUIZ: func = efdctuiz; type = XB; break;
+ case EFDDIV: func = efddiv; type = AB; break;
+ case EFDMUL: func = efdmul; type = AB; break;
+ case EFDNABS: func = efdnabs; type = XA; break;
+ case EFDNEG: func = efdneg; type = XA; break;
+ case EFDSUB: func = efdsub; type = AB; break;
+ default:
+ goto illegal;
+ }
+ break;
+ default:
+ goto illegal;
+ }
+
+ switch (type) {
+ case AB:
+ op0 = &fullgprs[(speinsn >> 21) & 0x1f];
+ op1 = &fullgprs[(speinsn >> 16) & 0x1f];
+ op2 = &fullgprs[(speinsn >> 11) & 0x1f];
+ break;
+
+ case XA:
+ op0 = &fullgprs[(speinsn >> 21) & 0x1f];
+ op1 = &fullgprs[(speinsn >> 16) & 0x1f];
+ break;
+
+ case XB:
+ op0 = &fullgprs[(speinsn >> 21) & 0x1f];
+ op1 = &fullgprs[(speinsn >> 11) & 0x1f];
+ break;
+
+ case XCR:
+ op0 = (void *)®s->ccr;
+ op1 = (void *)((speinsn >> 23) & 0x7);
+ op2 = &fullgprs[(speinsn >> 16) & 0x1f];
+ op3 = &fullgprs[(speinsn >> 11) & 0x1f];
+ break;
+
+ default:
+ goto illegal;
+ }
+ return 0;
+illegal:
+ printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\n");
+ return -ENOSYS;
+}
--
1.4.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 3:55 [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions ebony.zhu
@ 2007-02-08 7:32 ` Kumar Gala
2007-02-08 9:06 ` Zhu Ebony-r57400
2007-02-22 12:48 ` Sergei Shtylyov
1 sibling, 1 reply; 17+ messages in thread
From: Kumar Gala @ 2007-02-08 7:32 UTC (permalink / raw)
To: ebony.zhu; +Cc: linuxppc-dev, paulus
On Feb 7, 2007, at 9:55 PM, ebony.zhu@freescale.com wrote:
> Add the general support for Embedded Floating-Point instructions
> to fully comply with IEEE-754.
>
> Signed-off-by:Ebony Zhu <ebony.zhu@freescale.com>
> ---
> arch/powerpc/kernel/head_fsl_booke.S | 4
> arch/powerpc/kernel/traps.c | 57 +++++
> arch/powerpc/math-emu/Makefile | 25 ++
> arch/powerpc/math-emu/sfp-machine.h | 2
> arch/powerpc/math-emu/spe.h | 1
> arch/powerpc/sysdev/Makefile | 1
> arch/powerpc/sysdev/sigfpe_handler.c | 361 +++++++++++++++++++++++
> +++++++++++
> 7 files changed, 442 insertions(+), 9 deletions(-)
I thought we were going to have some general Kconfig option to enable
all this? EMDEDDED_FP_IEEE or something like that
>
> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/
> kernel/head_fsl_booke.S
> index 66877bd..0d05db0 100644
> --- a/arch/powerpc/kernel/head_fsl_booke.S
> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> @@ -705,7 +705,7 @@ #else
> #endif /* CONFIG_SPE */
>
> /* SPE Floating Point Round */
> - EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception,
> EXC_XFER_EE)
> + EXCEPTION(0x2050, SPEFloatingPointRound,
> SPEFloatingPointException_Round, EXC_XFER_EE)
>
> /* Performance Monitor */
> EXCEPTION(0x2060, PerformanceMonitor,
> performance_monitor_exception, EXC_XFER_STD)
> @@ -840,6 +840,8 @@ load_up_spe:
> oris r5,r5,MSR_SPE@h
> mtmsr r5 /* enable use of SPE now */
> isync
> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE |
> SPEFSCR_FOVFE)
> + mtspr SPRN_SPEFSCR,r5
We should do this via INIT_THREAD, is there a reason that you want to
set these always?
> /*
> * For SMP, we don't do lazy SPE switching because it just gets too
> * horrendously complex, especially when a task switches from one CPU
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 6915b91..30ab0f7 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -986,9 +986,16 @@ #endif /* CONFIG_FSL_BOOKE */
> #ifdef CONFIG_SPE
> void SPEFloatingPointException(struct pt_regs *regs)
> {
> + extern int spedata_handler(struct pt_regs *regs);
> unsigned long spefscr;
> int fpexc_mode;
> int code = 0;
> + int err;
> +
> + preempt_disable();
> + if (regs->msr & MSR_SPE)
> + giveup_spe(current);
> + preempt_enable();
use flush_spe_to_thread(current);
>
> spefscr = current->thread.spefscr;
> fpexc_mode = current->thread.fpexc_mode;
> @@ -1013,9 +1020,55 @@ void SPEFloatingPointException(struct pt
> code = FPE_FLTRES;
>
> current->thread.spefscr = spefscr;
> + err = spedata_handler(regs);
> + if (err == 0) {
> + regs->nip += 4; /* skip emulated instruction */
> + emulate_single_step(regs);
> + return;
> + }
Take a look at the path I put up that reworks the error handling from
do_mathemu() we need to be doing something similar (in parsing
spefscr/fpexc_mode to setup code properly)
> - _exception(SIGFPE, regs, code, regs->nip);
> - return;
> + if (err == -EFAULT) {
> + /* got an error reading the instruction */
> + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
> + } else if (err == -EINVAL) {
> + /* didn't recognize the instruction */
> + printk(KERN_ERR "unrecognized spe instruction "
> + "in %s at %lx\n", current->comm, regs->nip);
We should probably just SIGSEGV in this case since will never make
forward progress once we hit this case.
> + } else {
> + _exception(SIGFPE, regs, code, regs->nip);
> + return;
> + }
> +}
> +
> +void SPEFloatingPointException_Round(struct pt_regs *regs)
> +{
> + extern int speround_handler(struct pt_regs *regs);
> + int err;
> +
> + preempt_disable();
> + if (regs->msr & MSR_SPE)
> + giveup_spe(current);
> + preempt_enable();
use flush_spe_to_thread(current);
> +
> + regs->nip -= 4;
uugh, just handle this in speround_handler()
> + err = speround_handler(regs);
> + if (err == 0) {
> + regs->nip += 4; /* skip emulated instruction */
> + emulate_single_step(regs);
I don't think this emulate_single_step() needed since we really
aren't changing NIP from the HW point of view.
> + return;
> + }
> +
> + if (err == -EFAULT) {
> + /* got an error reading the instruction */
> + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
> + } else if (err == -EINVAL) {
> + /* didn't recognize the instruction */
> + printk(KERN_ERR "unrecognized spe instruction "
> + "in %s at %lx\n", current->comm, regs->nip);
similar comment as above
> + } else {
> + _exception(SIGFPE, regs, 0, regs->nip);
> + return;
> + }
> }
> #endif
>
> diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/
> Makefile
> index 29bc912..2da11ba 100644
> --- a/arch/powerpc/math-emu/Makefile
> +++ b/arch/powerpc/math-emu/Makefile
> @@ -1,16 +1,29 @@
>
> -obj-y := math.o fmr.o lfd.o stfd.o
> -
> -obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o
> fcmpu.o \
> +obj-y := fabs.o fneg.o types.o udivmodti4.o
This isn't right, we don't want to always build these files.
> +
> +obj-$(CONFIG_MATH_EMULATION) += math.o fmr.o lfd.o stfd.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 \
> + fmul.o fmuls.o fnabs.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
> + mtfsf.o mtfsfi.o stfiwx.o stfs.o
> +
> +obj-$(CONFIG_SPE) += efsabs.o efsadd.o efscfd.o efscmpeq.o \
> + efscmpgt.o efscmplt.o efsctsf.o efsctsi.o \
> + efsctsiz.o efsctuf.o efsctui.o efsctuiz.o \
> + efsdiv.o efsmul.o efsnabs.o efsneg.o efssub.o \
> + evfsabs.o evfsadd.o evfscmpeq.o evfscmpgt.o \
> + evfscmplt.o evfsctsf.o evfsctsi.o evfsctsiz.o \
> + evfsctuf.o evfsctui.o evfsctuiz.o evfsdiv.o \
> + evfsmul.o evfsnabs.o evfsneg.o evfssub.o \
> + efdadd.o efdcfs.o efdcmpeq.o efdcmpgt.o efdcmplt.o \
> + efdctsf.o efdctsi.o efdctsidz.o efdctsiz.o efdctuf.o \
> + efdctui.o efdctuidz.o efdctuiz.o efddiv.o efdmul.o \
> + efdnabs.o efdsub.o
>
> CFLAGS_fabs.o = -fno-builtin-fabs
> CFLAGS_math.o = -fno-builtin-fabs
> diff --git a/arch/powerpc/math-emu/sfp-machine.h b/arch/powerpc/
> math-emu/sfp-machine.h
> index 4b17d83..07de8ef 100644
> --- a/arch/powerpc/math-emu/sfp-machine.h
> +++ b/arch/powerpc/math-emu/sfp-machine.h
> @@ -166,7 +166,9 @@ #define __FP_PACK_RAW_2(fs, val, X) \
> #include <linux/kernel.h>
> #include <linux/sched.h>
>
> +#ifndef __FPU_FPSCR
> #define __FPU_FPSCR (current->thread.fpscr.val)
> +#endif
>
> /* We only actually write to the destination register
> * if exceptions signalled (if any) will not trap.
> diff --git a/arch/powerpc/math-emu/spe.h b/arch/powerpc/math-emu/spe.h
> new file mode 100644
> index 0000000..4f63630
> --- /dev/null
> +++ b/arch/powerpc/math-emu/spe.h
> @@ -0,0 +1 @@
> +#define __FPU_FPSCR (current->thread.spefscr)
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/
> Makefile
> index 2621a7e..47f88b6 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
> obj-$(CONFIG_FSL_SOC) += fsl_soc.o
> obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
> obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
> +obj-$(CONFIG_SPE) += sigfpe_handler.o
>
> ifeq ($(CONFIG_PPC_MERGE),y)
> obj-$(CONFIG_PPC_I8259) += i8259.o
> diff --git a/arch/powerpc/sysdev/sigfpe_handler.c b/arch/powerpc/
> sysdev/sigfpe_handler.c
> new file mode 100644
> index 0000000..8f9cfdb
> --- /dev/null
> +++ b/arch/powerpc/sysdev/sigfpe_handler.c
> @@ -0,0 +1,361 @@
> +/*
> + * arch/powerpc/sysdev/sigfpe_handler.c
> + *
> + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights
> reserved.
> + *
> + * Author: Ebony Zhu, ebony.zhu@freescale.com
> + *
> + * Derived from arch/powerpc/math-emu/math.c
> + * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com)
> + *
> + * Description:
> + * This file is the exception handler to make E500 SPE instructions
> + * fully comply with IEEE-754 floating point standard.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/types.h>
> +#include <asm/uaccess.h>
> +#include <asm/reg.h>
> +
> +#define SPEFUNC(x) extern int x(void *, void *, void *, void *)
> +#define efdabs fabs
> +#define efdneg fneg
> +
> +/* Scalar SPFP functions */
> +SPEFUNC(efsabs);
> +SPEFUNC(efsadd);
> +SPEFUNC(efscfd);
> +SPEFUNC(efscmpeq);
> +SPEFUNC(efscmpgt);
> +SPEFUNC(efscmplt);
> +SPEFUNC(efsctsf);
> +SPEFUNC(efsctsi);
> +SPEFUNC(efsctsiz);
> +SPEFUNC(efsctuf);
> +SPEFUNC(efsctui);
> +SPEFUNC(efsctuiz);
> +SPEFUNC(efsdiv);
> +SPEFUNC(efsmul);
> +SPEFUNC(efsnabs);
> +SPEFUNC(efsneg);
> +SPEFUNC(efssub);
> +
> +/* Vector Floating-Point functions */
> +SPEFUNC(evfsabs);
> +SPEFUNC(evfsadd);
> +SPEFUNC(evfscmpeq);
> +SPEFUNC(evfscmpgt);
> +SPEFUNC(evfscmplt);
> +SPEFUNC(evfsctsf);
> +SPEFUNC(evfsctsi);
> +SPEFUNC(evfsctsiz);
> +SPEFUNC(evfsctuf);
> +SPEFUNC(evfsctui);
> +SPEFUNC(evfsctuiz);
> +SPEFUNC(evfsdiv);
> +SPEFUNC(evfsmul);
> +SPEFUNC(evfsnabs);
> +SPEFUNC(evfsneg);
> +SPEFUNC(evfssub);
> +
> +/* Scalar DPFP functions */
> +SPEFUNC(efdabs);
> +SPEFUNC(efdadd);
> +SPEFUNC(efdcfs);
> +SPEFUNC(efdcmpeq);
> +SPEFUNC(efdcmpgt);
> +SPEFUNC(efdcmplt);
> +SPEFUNC(efdctsf);
> +SPEFUNC(efdctsi);
> +SPEFUNC(efdctsidz);
> +SPEFUNC(efdctsiz);
> +SPEFUNC(efdctuf);
> +SPEFUNC(efdctui);
> +SPEFUNC(efdctuidz);
> +SPEFUNC(efdctuiz);
> +SPEFUNC(efddiv);
> +SPEFUNC(efdmul);
> +SPEFUNC(efdnabs);
> +SPEFUNC(efdneg);
> +SPEFUNC(efdsub);
> +
> +#define VCT 0x4
> +#define SPFP 0x6
> +#define DPFP 0x7
> +#define EFAPU 0x4
> +
> +#define EFSADD 0x2c0
> +#define EFSSUB 0x2c1
> +#define EFSABS 0x2c4
> +#define EFSNABS 0x2c5
> +#define EFSNEG 0x2c6
> +#define EFSMUL 0x2c8
> +#define EFSDIV 0x2c9
> +#define EFSCMPGT 0x2cc
> +#define EFSCMPLT 0x2cd
> +#define EFSCMPEQ 0x2ce
> +#define EFSCFD 0x2cf
> +#define EFSCTUI 0x2d4
> +#define EFSCTSI 0x2d5
> +#define EFSCTUF 0x2d6
> +#define EFSCTSF 0x2d7
> +#define EFSCTUIZ 0x2d8
> +#define EFSCTSIZ 0x2da
> +
> +#define EVFSADD 0x280
> +#define EVFSSUB 0x281
> +#define EVFSABS 0x284
> +#define EVFSNABS 0x285
> +#define EVFSNEG 0x286
> +#define EVFSMUL 0x288
> +#define EVFSDIV 0x289
> +#define EVFSCMPGT 0x28c
> +#define EVFSCMPLT 0x28d
> +#define EVFSCMPEQ 0x28e
> +#define EVFSCTUI 0x294
> +#define EVFSCTSI 0x295
> +#define EVFSCTUF 0x296
> +#define EVFSCTSF 0x297
> +#define EVFSCTUIZ 0x298
> +#define EVFSCTSIZ 0x29a
> +
> +#define EFDADD 0x2e0
> +#define EFDSUB 0x2e1
> +#define EFDABS 0x2e4
> +#define EFDNABS 0x2e5
> +#define EFDNEG 0x2e6
> +#define EFDMUL 0x2e8
> +#define EFDDIV 0x2e9
> +#define EFDCTUIDZ 0x2ea
> +#define EFDCTSIDZ 0x2eb
> +#define EFDCMPGT 0x2ec
> +#define EFDCMPLT 0x2ed
> +#define EFDCMPEQ 0x2ee
> +#define EFDCFS 0x2ef
> +#define EFDCTUI 0x2f4
> +#define EFDCTSI 0x2f5
> +#define EFDCTUF 0x2f6
> +#define EFDCTSF 0x2f7
> +#define EFDCTUIZ 0x2f8
> +#define EFDCTSIZ 0x2fa
> +
> +#define AB 2
> +#define XA 3
> +#define XB 4
> +#define XCR 5
> +
> +static u64 fullgprs[32];
> +static u32 speinsn;
> +static int insn_decode(struct pt_regs *regs);
> +static int (*func)(void *, void *, void *, void *);
> +static void *op0 = 0, *op1 = 0, *op2 = 0, *op3 = 0;
> +static int type = 0, flag;
> +
> +int
> +spedata_handler(struct pt_regs *regs)
> +{
> + int i;
> +
> + if (get_user(speinsn, (unsigned int __user *) regs->nip))
> + return -EFAULT;
> + if ((speinsn >> 26) != 4)
> + return -EINVAL; /* not an spe instruction */
> + switch ((speinsn >> 5) & 0x7 ) {
> + case SPFP:
> + for(i = 0; i < 32; i++) {
> + fullgprs[i] = regs->gpr[i];
> + fullgprs[i] = fullgprs[i] << 32 | current->thread.evr[i];
> + };
> + break;
> + default:
> + for(i = 0; i < 32; i++) {
> + fullgprs[i] = current->thread.evr[i];
> + fullgprs[i] = (fullgprs[i] << 32) | (regs->gpr[i]);
> + };
> + }
> +
> + if (insn_decode(regs) == -ENOSYS) return -ENOSYS;
> + flag = func(op0, op1, op2, op3);
> +
> + switch ((speinsn >> 5) & 0x7 ) {
> + case SPFP:
> + for (i = 0; i < 32; i++) {
> + regs->gpr[i] = fullgprs[i] >> 32;
> + };
> + break;
> + default:
> + for (i = 0; i < 32; i++) {
> + regs->gpr[i] = fullgprs[i];
> + current->thread.evr[i] = fullgprs[i] >> 32;
> + };
> + }
> + return 0;
> +}
> +
> +int
> +speround_handler(struct pt_regs *regs)
> +{
> + u32 lsb_lo, lsb_hi;
> + int s_lo, s_hi;
> + int rD;
> +
> + if (get_user(speinsn, (unsigned int __user *) regs->nip))
> + return -EFAULT;
> + if ((speinsn >> 26) != 4)
> + return -EINVAL; /* not an spe instruction */
> +
> + rD = (speinsn >> 21) & 0x1f;
> + flag = insn_decode(regs);
> + if (type == XCR) return -ENOSYS;
> +
> + s_lo = (regs->gpr[rD] & 0x80000000) >> 31;
> + s_hi = (current->thread.evr[rD] & 0x80000000) >> 31;
> + lsb_lo = regs->gpr[rD];
> + lsb_hi = current->thread.evr[rD];
> + switch ((speinsn >> 5) & 0x7 ) {
> + /* Since SPE instructions on E500 core can handle round to nearest
> + * and round toward zero with IEEE-754 complied, we just need
> + * to handle round toward +Inf and round toward -Inf by software.
> + */
> + case SPFP:
> + if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
> + if (!s_lo) lsb_lo++; /* Z > 0, choose Z1 */
> + } else { /* round to -Inf */
> + if (s_lo) lsb_lo++; /* Z < 0, choose Z2 */
> + }
> + regs->gpr[rD] = lsb_lo;
> + break;
> + case DPFP:
> + fullgprs[rD] = current->thread.evr[rD];
> + fullgprs[rD] = (fullgprs[rD] << 32) | (regs->gpr[rD]);
> +
> + if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
> + if (!s_hi) fullgprs[rD]++; /* Z > 0, choose Z1 */
> + } else { /* round to -Inf */
> + if (s_hi) fullgprs[rD]++; /* Z < 0, choose Z2 */
> + }
> + regs->gpr[rD] = fullgprs[rD];
> + current->thread.evr[rD] = fullgprs[rD] >> 32;
> + break;
> + case VCT:
> + if ((current->thread.spefscr & 0x3) == 0x2) { /* round to +Inf */
> + if (!s_lo) lsb_lo++; /* Z_low > 0, choose Z1 */
> + if (!s_hi) lsb_hi++; /* Z_high word > 0, choose Z1 */
> + } else { /* round to -Inf */
> + if (s_lo) lsb_lo++; /* Z_low < 0, choose Z2 */
> + if (s_hi) lsb_hi++; /* Z_high < 0, choose Z2 */
> + }
> + regs->gpr[rD] = lsb_lo;
> + current->thread.evr[rD] = lsb_hi;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int insn_decode(struct pt_regs *regs)
> +{
> + switch (speinsn >> 26) {
> +
> + case EFAPU:
> + switch (speinsn & 0x7ff) {
> + case EFSABS: func = efsabs; type = XA; break;
> + case EFSADD: func = efsadd; type = AB; break;
> + case EFSCFD: func = efscfd; type = XB; break;
> + case EFSCMPEQ: func = efscmpeq; type = XCR; break;
> + case EFSCMPGT: func = efscmpgt; type = XCR; break;
> + case EFSCMPLT: func = efscmplt; type = XCR; break;
> + case EFSCTSF: func = efsctsf; type = XB; break;
> + case EFSCTSI: func = efsctsi; type = XB; break;
> + case EFSCTSIZ: func = efsctsiz; type = XB; break;
> + case EFSCTUF: func = efsctuf; type = XB; break;
> + case EFSCTUI: func = efsctui; type = XB; break;
> + case EFSCTUIZ: func = efsctuiz; type = XB; break;
> + case EFSDIV: func = efsdiv; type = AB; break;
> + case EFSMUL: func = efsmul; type = AB; break;
> + case EFSNABS: func = efsnabs; type = XA; break;
> + case EFSNEG: func = efsneg; type = XA; break;
> + case EFSSUB: func = efssub; type = AB; break;
> +
> + case EVFSABS: func = evfsabs; type = XA; break;
> + case EVFSADD: func = evfsadd; type = AB; break;
> + case EVFSCMPEQ: func = evfscmpeq; type = XCR; break;
> + case EVFSCMPGT: func = evfscmpgt; type = XCR; break;
> + case EVFSCMPLT: func = evfscmplt; type = XCR; break;
> + case EVFSCTSF: func = evfsctsf; type = XB; break;
> + case EVFSCTSI: func = evfsctsi; type = XB; break;
> + case EVFSCTSIZ: func = evfsctsiz; type = XB; break;
> + case EVFSCTUF: func = evfsctuf; type = XB; break;
> + case EVFSCTUI: func = evfsctui; type = XB; break;
> + case EVFSCTUIZ: func = evfsctuiz; type = XB; break;
> + case EVFSDIV: func = evfsdiv; type = AB; break;
> + case EVFSMUL: func = evfsmul; type = AB; break;
> + case EVFSNABS: func = evfsnabs; type = XA; break;
> + case EVFSNEG: func = evfsneg; type = XA; break;
> + case EVFSSUB: func = evfssub; type = AB; break;
> +
> + case EFDABS: func = efdabs; type = XA; break;
> + case EFDADD: func = efdadd; type = AB; break;
> + case EFDCFS: func = efdcfs; type = XB; break;
> + case EFDCMPEQ: func = efdcmpeq; type = XCR; break;
> + case EFDCMPGT: func = efdcmpgt; type = XCR; break;
> + case EFDCMPLT: func = efdcmplt; type = XCR; break;
> + case EFDCTSF: func = efdctsf; type = XB; break;
> + case EFDCTSI: func = efdctsi; type = XB; break;
> + case EFDCTSIDZ: func = efdctsidz; type = XB; break;
> + case EFDCTSIZ: func = efdctsiz; type = XB; break;
> + case EFDCTUF: func = efdctuf; type = XB; break;
> + case EFDCTUI: func = efdctui; type = XB; break;
> + case EFDCTUIDZ: func = efdctuidz; type = XB; break;
> + case EFDCTUIZ: func = efdctuiz; type = XB; break;
> + case EFDDIV: func = efddiv; type = AB; break;
> + case EFDMUL: func = efdmul; type = AB; break;
> + case EFDNABS: func = efdnabs; type = XA; break;
> + case EFDNEG: func = efdneg; type = XA; break;
> + case EFDSUB: func = efdsub; type = AB; break;
> + default:
> + goto illegal;
> + }
> + break;
> + default:
> + goto illegal;
> + }
> +
> + switch (type) {
> + case AB:
> + op0 = &fullgprs[(speinsn >> 21) & 0x1f];
> + op1 = &fullgprs[(speinsn >> 16) & 0x1f];
> + op2 = &fullgprs[(speinsn >> 11) & 0x1f];
> + break;
> +
> + case XA:
> + op0 = &fullgprs[(speinsn >> 21) & 0x1f];
> + op1 = &fullgprs[(speinsn >> 16) & 0x1f];
> + break;
> +
> + case XB:
> + op0 = &fullgprs[(speinsn >> 21) & 0x1f];
> + op1 = &fullgprs[(speinsn >> 11) & 0x1f];
> + break;
> +
> + case XCR:
> + op0 = (void *)®s->ccr;
> + op1 = (void *)((speinsn >> 23) & 0x7);
> + op2 = &fullgprs[(speinsn >> 16) & 0x1f];
> + op3 = &fullgprs[(speinsn >> 11) & 0x1f];
> + break;
> +
> + default:
> + goto illegal;
> + }
> + return 0;
> +illegal:
> + printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered
> un-supported instruction.\n");
> + return -ENOSYS;
> +}
> --
> 1.4.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 7:32 ` Kumar Gala
@ 2007-02-08 9:06 ` Zhu Ebony-r57400
2007-02-08 17:31 ` Kumar Gala
0 siblings, 1 reply; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-02-08 9:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
=20
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Thursday, February 08, 2007 3:33 PM
> To: Zhu Ebony-r57400
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [patch][5/5] powerpc V2: Add the general support=20
> for Embedded Floating-Point instructions
>=20
>=20
> On Feb 7, 2007, at 9:55 PM, ebony.zhu@freescale.com wrote:
>=20
> > Add the general support for Embedded Floating-Point instructions to=20
> > fully comply with IEEE-754.
> >
> > Signed-off-by:Ebony Zhu <ebony.zhu@freescale.com>
> > ---
> > arch/powerpc/kernel/head_fsl_booke.S | 4
> > arch/powerpc/kernel/traps.c | 57 +++++
> > arch/powerpc/math-emu/Makefile | 25 ++
> > arch/powerpc/math-emu/sfp-machine.h | 2
> > arch/powerpc/math-emu/spe.h | 1
> > arch/powerpc/sysdev/Makefile | 1
> > arch/powerpc/sysdev/sigfpe_handler.c | 361 +++++++++++++++++++++++
> > +++++++++++
> > 7 files changed, 442 insertions(+), 9 deletions(-)
>=20
> I thought we were going to have some general Kconfig option=20
> to enable all this? EMDEDDED_FP_IEEE or something like that
So that users have chance to enable/disable fully IEEE compliance?
Segher
had mentioned this, and it sounds reasonable.=20
>=20
> >
> > diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/=20
> > kernel/head_fsl_booke.S
> > index 66877bd..0d05db0 100644
> > --- a/arch/powerpc/kernel/head_fsl_booke.S
> > +++ b/arch/powerpc/kernel/head_fsl_booke.S
> > @@ -705,7 +705,7 @@ #else
> > #endif /* CONFIG_SPE */
> >
> > /* SPE Floating Point Round */
> > - EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, =20
> > EXC_XFER_EE)
> > + EXCEPTION(0x2050, SPEFloatingPointRound, =20
> > SPEFloatingPointException_Round, EXC_XFER_EE)
> >
> > /* Performance Monitor */
> > EXCEPTION(0x2060, PerformanceMonitor, =20
> > performance_monitor_exception, EXC_XFER_STD)
> > @@ -840,6 +840,8 @@ load_up_spe:
> > oris r5,r5,MSR_SPE@h
> > mtmsr r5 /* enable use of SPE now */
> > isync
> > + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | =20
> > SPEFSCR_FOVFE)
> > + mtspr SPRN_SPEFSCR,r5
>=20
> We should do this via INIT_THREAD, is there a reason that you=20
> want to =20
> set these always?
I just thought it's the first time that an SPE instruction is
encountered, so I
enable the exceptions here.
>=20
> > /*
> > * For SMP, we don't do lazy SPE switching because it just gets too
> > * horrendously complex, especially when a task switches=20
> from one CPU
> > diff --git a/arch/powerpc/kernel/traps.c=20
> b/arch/powerpc/kernel/traps.c
> > index 6915b91..30ab0f7 100644
> > --- a/arch/powerpc/kernel/traps.c
> > +++ b/arch/powerpc/kernel/traps.c
> > @@ -986,9 +986,16 @@ #endif /* CONFIG_FSL_BOOKE */
> > #ifdef CONFIG_SPE
> > void SPEFloatingPointException(struct pt_regs *regs)
> > {
> > + extern int spedata_handler(struct pt_regs *regs);
> > unsigned long spefscr;
> > int fpexc_mode;
> > int code =3D 0;
> > + int err;
> > +=09
> > + preempt_disable();
> > + if (regs->msr & MSR_SPE)
> > + giveup_spe(current);
> > + preempt_enable();
>=20
> use flush_spe_to_thread(current);
OK. It works, and I'll change it.
>=20
> >
> > spefscr =3D current->thread.spefscr;
> > fpexc_mode =3D current->thread.fpexc_mode;
> > @@ -1013,9 +1020,55 @@ void SPEFloatingPointException(struct pt
> > code =3D FPE_FLTRES;
> >
> > current->thread.spefscr =3D spefscr;
> > + err =3D spedata_handler(regs);
> > + if (err =3D=3D 0) {
> > + regs->nip +=3D 4; /* skip emulated instruction */
> > + emulate_single_step(regs);
> > + return;
> > + }
>=20
> Take a look at the path I put up that reworks the error=20
> handling from =20
> do_mathemu() we need to be doing something similar (in parsing =20
> spefscr/fpexc_mode to setup code properly)
It's new in trap.c? I'll look into it.
>=20
> > - _exception(SIGFPE, regs, code, regs->nip);
> > - return;
> > + if (err =3D=3D -EFAULT) {
> > + /* got an error reading the instruction */
> > + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
> > + } else if (err =3D=3D -EINVAL) {
> > + /* didn't recognize the instruction */
> > + printk(KERN_ERR "unrecognized spe instruction "
> > + "in %s at %lx\n", current->comm, regs->nip);
>=20
> We should probably just SIGSEGV in this case since will never make =20
> forward progress once we hit this case.
Won't it hit the case that the instruction is not an spe instruction?
> >
> > diff --git a/arch/powerpc/math-emu/Makefile=20
> b/arch/powerpc/math-emu/=20
> > Makefile
> > index 29bc912..2da11ba 100644
> > --- a/arch/powerpc/math-emu/Makefile
> > +++ b/arch/powerpc/math-emu/Makefile
> > @@ -1,16 +1,29 @@
> >
> > -obj-y :=3D math.o fmr.o lfd.o stfd.o
> > -
> > -obj-$(CONFIG_MATH_EMULATION) +=3D fabs.o fadd.o=20
> fadds.o fcmpo.o =20
> > fcmpu.o \
> > +obj-y :=3D fabs.o fneg.o=20
> types.o udivmodti4.o
>=20
> This isn't right, we don't want to always build these files.
>=20
fabs.o/fneg.o should be built in the case
that CONFIG_MATH_EMULATION or CONFIG_SPE or both are
enabled. Because I reused fabs.c and fneg.c to implement instruction
efdabs and
efdneg. Therefore, these two files should be build once we have chance
to build the files in directory math-emu. Types.c and udivmodti4.c
contain the function
that both math emulation instructions and spe instructions may call, so
they always need
to be built.
B.R
Ebony
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 9:06 ` Zhu Ebony-r57400
@ 2007-02-08 17:31 ` Kumar Gala
2007-02-09 5:15 ` Zhu Ebony-r57400
2007-02-09 14:40 ` Segher Boessenkool
0 siblings, 2 replies; 17+ messages in thread
From: Kumar Gala @ 2007-02-08 17:31 UTC (permalink / raw)
To: Zhu Ebony-r57400; +Cc: linuxppc-dev, paulus
On Feb 8, 2007, at 3:06 AM, Zhu Ebony-r57400 wrote:
>
>
>> -----Original Message-----
>> From: Kumar Gala [mailto:galak@kernel.crashing.org]
>> Sent: Thursday, February 08, 2007 3:33 PM
>> To: Zhu Ebony-r57400
>> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
>> Subject: Re: [patch][5/5] powerpc V2: Add the general support
>> for Embedded Floating-Point instructions
>>
>>
>> On Feb 7, 2007, at 9:55 PM, ebony.zhu@freescale.com wrote:
>>
>>> Add the general support for Embedded Floating-Point instructions to
>>> fully comply with IEEE-754.
>>>
>>> Signed-off-by:Ebony Zhu <ebony.zhu@freescale.com>
>>> ---
>>> arch/powerpc/kernel/head_fsl_booke.S | 4
>>> arch/powerpc/kernel/traps.c | 57 +++++
>>> arch/powerpc/math-emu/Makefile | 25 ++
>>> arch/powerpc/math-emu/sfp-machine.h | 2
>>> arch/powerpc/math-emu/spe.h | 1
>>> arch/powerpc/sysdev/Makefile | 1
>>> arch/powerpc/sysdev/sigfpe_handler.c | 361 +++++++++++++++++++++++
>>> +++++++++++
>>> 7 files changed, 442 insertions(+), 9 deletions(-)
>>
>> I thought we were going to have some general Kconfig option
>> to enable all this? EMDEDDED_FP_IEEE or something like that
>
> So that users have chance to enable/disable fully IEEE compliance?
> Segher
> had mentioned this, and it sounds reasonable.
Its alot of code to bring in if you don't care about IEEE compliance.
>>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/
>>> kernel/head_fsl_booke.S
>>> index 66877bd..0d05db0 100644
>>> --- a/arch/powerpc/kernel/head_fsl_booke.S
>>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
>>> @@ -705,7 +705,7 @@ #else
>>> #endif /* CONFIG_SPE */
>>>
>>> /* SPE Floating Point Round */
>>> - EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception,
>>> EXC_XFER_EE)
>>> + EXCEPTION(0x2050, SPEFloatingPointRound,
>>> SPEFloatingPointException_Round, EXC_XFER_EE)
>>>
>>> /* Performance Monitor */
>>> EXCEPTION(0x2060, PerformanceMonitor,
>>> performance_monitor_exception, EXC_XFER_STD)
>>> @@ -840,6 +840,8 @@ load_up_spe:
>>> oris r5,r5,MSR_SPE@h
>>> mtmsr r5 /* enable use of SPE now */
>>> isync
>>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE |
>>> SPEFSCR_FOVFE)
>>> + mtspr SPRN_SPEFSCR,r5
>>
>> We should do this via INIT_THREAD, is there a reason that you
>> want to
>> set these always?
>
> I just thought it's the first time that an SPE instruction is
> encountered, so I
> enable the exceptions here.
Lets do this via INIT_THREAD instead, its cleaner. (just remember to
add the proper ifdef protection for SPE_IEEE
>>> /*
>>> * For SMP, we don't do lazy SPE switching because it just gets too
>>> * horrendously complex, especially when a task switches
>> from one CPU
>>> diff --git a/arch/powerpc/kernel/traps.c
>> b/arch/powerpc/kernel/traps.c
>>> index 6915b91..30ab0f7 100644
>>> --- a/arch/powerpc/kernel/traps.c
>>> +++ b/arch/powerpc/kernel/traps.c
>>> @@ -986,9 +986,16 @@ #endif /* CONFIG_FSL_BOOKE */
>>> #ifdef CONFIG_SPE
>>> void SPEFloatingPointException(struct pt_regs *regs)
>>> {
>>> + extern int spedata_handler(struct pt_regs *regs);
>>> unsigned long spefscr;
>>> int fpexc_mode;
>>> int code = 0;
>>> + int err;
>>> +
>>> + preempt_disable();
>>> + if (regs->msr & MSR_SPE)
>>> + giveup_spe(current);
>>> + preempt_enable();
>>
>> use flush_spe_to_thread(current);
>
> OK. It works, and I'll change it.
>
>>
>>>
>>> spefscr = current->thread.spefscr;
>>> fpexc_mode = current->thread.fpexc_mode;
>>> @@ -1013,9 +1020,55 @@ void SPEFloatingPointException(struct pt
>>> code = FPE_FLTRES;
>>>
>>> current->thread.spefscr = spefscr;
>>> + err = spedata_handler(regs);
>>> + if (err == 0) {
>>> + regs->nip += 4; /* skip emulated instruction */
>>> + emulate_single_step(regs);
>>> + return;
>>> + }
>>
>> Take a look at the path I put up that reworks the error
>> handling from
>> do_mathemu() we need to be doing something similar (in parsing
>> spefscr/fpexc_mode to setup code properly)
>
> It's new in trap.c? I'll look into it.
Pretty recent commit, in Paul's tree, not yet in linus's.
(or look at my last pull request email to paul)
>>> - _exception(SIGFPE, regs, code, regs->nip);
>>> - return;
>>> + if (err == -EFAULT) {
>>> + /* got an error reading the instruction */
>>> + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
>>> + } else if (err == -EINVAL) {
>>> + /* didn't recognize the instruction */
>>> + printk(KERN_ERR "unrecognized spe instruction "
>>> + "in %s at %lx\n", current->comm, regs->nip);
>>
>> We should probably just SIGSEGV in this case since will never make
>> forward progress once we hit this case.
>
> Won't it hit the case that the instruction is not an spe instruction?
No, since we will not get this exception on something that's not an
SPE instruction.
>>> diff --git a/arch/powerpc/math-emu/Makefile
>> b/arch/powerpc/math-emu/
>>> Makefile
>>> index 29bc912..2da11ba 100644
>>> --- a/arch/powerpc/math-emu/Makefile
>>> +++ b/arch/powerpc/math-emu/Makefile
>>> @@ -1,16 +1,29 @@
>>>
>>> -obj-y := math.o fmr.o lfd.o stfd.o
>>> -
>>> -obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o
>> fadds.o fcmpo.o
>>> fcmpu.o \
>>> +obj-y := fabs.o fneg.o
>> types.o udivmodti4.o
>>
>> This isn't right, we don't want to always build these files.
>>
> fabs.o/fneg.o should be built in the case
> that CONFIG_MATH_EMULATION or CONFIG_SPE or both are
> enabled. Because I reused fabs.c and fneg.c to implement instruction
> efdabs and
> efdneg. Therefore, these two files should be build once we have chance
> to build the files in directory math-emu. Types.c and udivmodti4.c
> contain the function
> that both math emulation instructions and spe instructions may
> call, so
> they always need
> to be built.
Right, but doesn't the new rule say to always build, regardless if
CONFIG_MATH_EMULATION or CONFIG_SPE are set?
Why not just duplicate fabs.o fneg.o ... in both lists. I don't
think that will cause any harm.
- k
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 17:31 ` Kumar Gala
@ 2007-02-09 5:15 ` Zhu Ebony-r57400
2007-02-09 5:28 ` Kumar Gala
2007-02-09 14:40 ` Segher Boessenkool
1 sibling, 1 reply; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-02-09 5:15 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
=20
> >>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/=20
> >>> kernel/head_fsl_booke.S index 66877bd..0d05db0 100644
> >>> --- a/arch/powerpc/kernel/head_fsl_booke.S
> >>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> >>> @@ -705,7 +705,7 @@ #else
> >>> #endif /* CONFIG_SPE */
> >>>
> >>> /* SPE Floating Point Round */
> >>> - EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception,
> >>> EXC_XFER_EE)
> >>> + EXCEPTION(0x2050, SPEFloatingPointRound,
> >>> SPEFloatingPointException_Round, EXC_XFER_EE)
> >>>
> >>> /* Performance Monitor */
> >>> EXCEPTION(0x2060, PerformanceMonitor,=20
> >>> performance_monitor_exception, EXC_XFER_STD) @@ -840,6 +840,8 @@=20
> >>> load_up_spe:
> >>> oris r5,r5,MSR_SPE@h
> >>> mtmsr r5 /* enable use of SPE now */
> >>> isync
> >>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE |
> >>> SPEFSCR_FOVFE)
> >>> + mtspr SPRN_SPEFSCR,r5
> >>
> >> We should do this via INIT_THREAD, is there a reason that=20
> you want to=20
> >> set these always?
> >
> > I just thought it's the first time that an SPE instruction is=20
> > encountered, so I enable the exceptions here.
>=20
> Lets do this via INIT_THREAD instead, its cleaner. (just=20
> remember to add the proper ifdef protection for SPE_IEEE
Talking about INIT_THREAD, I'm wondering where is the best place to
enble the exceptions? Please advice!
And also, I will put all of your other suggestions into next patches.
Thank you!
B.R.
Ebony
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-09 5:15 ` Zhu Ebony-r57400
@ 2007-02-09 5:28 ` Kumar Gala
2007-02-09 5:48 ` Zhu Ebony-r57400
0 siblings, 1 reply; 17+ messages in thread
From: Kumar Gala @ 2007-02-09 5:28 UTC (permalink / raw)
To: Zhu Ebony-r57400; +Cc: linuxppc-dev, paulus
On Feb 8, 2007, at 11:15 PM, Zhu Ebony-r57400 wrote:
>
>>>>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/
>>>>> kernel/head_fsl_booke.S index 66877bd..0d05db0 100644
>>>>> --- a/arch/powerpc/kernel/head_fsl_booke.S
>>>>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
>>>>> @@ -705,7 +705,7 @@ #else
>>>>> #endif /* CONFIG_SPE */
>>>>>
>>>>> /* SPE Floating Point Round */
>>>>> - EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception,
>>>>> EXC_XFER_EE)
>>>>> + EXCEPTION(0x2050, SPEFloatingPointRound,
>>>>> SPEFloatingPointException_Round, EXC_XFER_EE)
>>>>>
>>>>> /* Performance Monitor */
>>>>> EXCEPTION(0x2060, PerformanceMonitor,
>>>>> performance_monitor_exception, EXC_XFER_STD) @@ -840,6 +840,8 @@
>>>>> load_up_spe:
>>>>> oris r5,r5,MSR_SPE@h
>>>>> mtmsr r5 /* enable use of SPE now */
>>>>> isync
>>>>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE |
>>>>> SPEFSCR_FOVFE)
>>>>> + mtspr SPRN_SPEFSCR,r5
>>>>
>>>> We should do this via INIT_THREAD, is there a reason that
>> you want to
>>>> set these always?
>>>
>>> I just thought it's the first time that an SPE instruction is
>>> encountered, so I enable the exceptions here.
>>
>> Lets do this via INIT_THREAD instead, its cleaner. (just
>> remember to add the proper ifdef protection for SPE_IEEE
>
> Talking about INIT_THREAD, I'm wondering where is the best place to
> enble the exceptions? Please advice!
What's the issue with enabling via INIT_THREAD? am I missing something?
> And also, I will put all of your other suggestions into next patches.
> Thank you!
Ok.
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-09 5:28 ` Kumar Gala
@ 2007-02-09 5:48 ` Zhu Ebony-r57400
2007-02-09 6:03 ` Kumar Gala
0 siblings, 1 reply; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-02-09 5:48 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
=20
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Friday, February 09, 2007 1:29 PM
> To: Zhu Ebony-r57400
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [patch][5/5] powerpc V2: Add the general support=20
> for Embedded Floating-Point instructions
>=20
>=20
> On Feb 8, 2007, at 11:15 PM, Zhu Ebony-r57400 wrote:
>=20
> >
> >>>>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S=20
> b/arch/powerpc/=20
> >>>>> kernel/head_fsl_booke.S index 66877bd..0d05db0 100644
> >>>>> --- a/arch/powerpc/kernel/head_fsl_booke.S
> >>>>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> >>>>> @@ -705,7 +705,7 @@ #else
> >>>>> #endif /* CONFIG_SPE */
> >>>>>
> >>>>> /* SPE Floating Point Round */
> >>>>> - EXCEPTION(0x2050, SPEFloatingPointRound,=20
> unknown_exception,
> >>>>> EXC_XFER_EE)
> >>>>> + EXCEPTION(0x2050, SPEFloatingPointRound,
> >>>>> SPEFloatingPointException_Round, EXC_XFER_EE)
> >>>>>
> >>>>> /* Performance Monitor */
> >>>>> EXCEPTION(0x2060, PerformanceMonitor,=20
> >>>>> performance_monitor_exception, EXC_XFER_STD) @@ -840,6 +840,8 @@
> >>>>> load_up_spe:
> >>>>> oris r5,r5,MSR_SPE@h
> >>>>> mtmsr r5 /* enable use=20
> of SPE now */
> >>>>> isync
> >>>>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE |=20
> SPEFSCR_FUNFE |
> >>>>> SPEFSCR_FOVFE)
> >>>>> + mtspr SPRN_SPEFSCR,r5
> >>>>
> >>>> We should do this via INIT_THREAD, is there a reason that
> >> you want to
> >>>> set these always?
> >>>
> >>> I just thought it's the first time that an SPE instruction is=20
> >>> encountered, so I enable the exceptions here.
> >>
> >> Lets do this via INIT_THREAD instead, its cleaner. (just=20
> remember to=20
> >> add the proper ifdef protection for SPE_IEEE
> >
> > Talking about INIT_THREAD, I'm wondering where is the best place to=20
> > enble the exceptions? Please advice!
>=20
> What's the issue with enabling via INIT_THREAD? am I missing=20
> something?
Do you mean that add=20
".spefscr =3D SPEFSCR_FINV| SPEFSCR_FDBZE|SPEFSCR_FUNFE|SPEFSCR_FOVFE"
In the defination of INIT_THREAD?
I think it should work.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-09 5:48 ` Zhu Ebony-r57400
@ 2007-02-09 6:03 ` Kumar Gala
2007-02-09 6:27 ` Zhu Ebony-r57400
0 siblings, 1 reply; 17+ messages in thread
From: Kumar Gala @ 2007-02-09 6:03 UTC (permalink / raw)
To: Zhu Ebony-r57400; +Cc: linuxppc-dev, paulus
On Feb 8, 2007, at 11:48 PM, Zhu Ebony-r57400 wrote:
>
>
>> -----Original Message-----
>> From: Kumar Gala [mailto:galak@kernel.crashing.org]
>> Sent: Friday, February 09, 2007 1:29 PM
>> To: Zhu Ebony-r57400
>> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
>> Subject: Re: [patch][5/5] powerpc V2: Add the general support
>> for Embedded Floating-Point instructions
>>
>>
>> On Feb 8, 2007, at 11:15 PM, Zhu Ebony-r57400 wrote:
>>
>>>
>>>>>>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S
>> b/arch/powerpc/
>>>>>>> kernel/head_fsl_booke.S index 66877bd..0d05db0 100644
>>>>>>> --- a/arch/powerpc/kernel/head_fsl_booke.S
>>>>>>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
>>>>>>> @@ -705,7 +705,7 @@ #else
>>>>>>> #endif /* CONFIG_SPE */
>>>>>>>
>>>>>>> /* SPE Floating Point Round */
>>>>>>> - EXCEPTION(0x2050, SPEFloatingPointRound,
>> unknown_exception,
>>>>>>> EXC_XFER_EE)
>>>>>>> + EXCEPTION(0x2050, SPEFloatingPointRound,
>>>>>>> SPEFloatingPointException_Round, EXC_XFER_EE)
>>>>>>>
>>>>>>> /* Performance Monitor */
>>>>>>> EXCEPTION(0x2060, PerformanceMonitor,
>>>>>>> performance_monitor_exception, EXC_XFER_STD) @@ -840,6 +840,8 @@
>>>>>>> load_up_spe:
>>>>>>> oris r5,r5,MSR_SPE@h
>>>>>>> mtmsr r5 /* enable use
>> of SPE now */
>>>>>>> isync
>>>>>>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE |
>> SPEFSCR_FUNFE |
>>>>>>> SPEFSCR_FOVFE)
>>>>>>> + mtspr SPRN_SPEFSCR,r5
>>>>>>
>>>>>> We should do this via INIT_THREAD, is there a reason that
>>>> you want to
>>>>>> set these always?
>>>>>
>>>>> I just thought it's the first time that an SPE instruction is
>>>>> encountered, so I enable the exceptions here.
>>>>
>>>> Lets do this via INIT_THREAD instead, its cleaner. (just
>> remember to
>>>> add the proper ifdef protection for SPE_IEEE
>>>
>>> Talking about INIT_THREAD, I'm wondering where is the best place to
>>> enble the exceptions? Please advice!
>>
>> What's the issue with enabling via INIT_THREAD? am I missing
>> something?
>
> Do you mean that add
> ".spefscr = SPEFSCR_FINV| SPEFSCR_FDBZE|SPEFSCR_FUNFE|SPEFSCR_FOVFE"
> In the defination of INIT_THREAD?
You may want to have something like #define SPE_EXCEPTION_ENABLE
(SPEFSCR_FINV| SPEFSCR_FDBZE|SPEFSCR_FUNFE|SPEFSCR_FOVFE)
Yep, with the proper #ifdef CONFIG_ protection.
- k
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-09 6:03 ` Kumar Gala
@ 2007-02-09 6:27 ` Zhu Ebony-r57400
0 siblings, 0 replies; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-02-09 6:27 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
=20
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Friday, February 09, 2007 2:04 PM
> To: Zhu Ebony-r57400
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [patch][5/5] powerpc V2: Add the general support=20
> for Embedded Floating-Point instructions
>=20
>=20
> On Feb 8, 2007, at 11:48 PM, Zhu Ebony-r57400 wrote:
>=20
> >
> >
> >> -----Original Message-----
> >> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> >> Sent: Friday, February 09, 2007 1:29 PM
> >> To: Zhu Ebony-r57400
> >> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> >> Subject: Re: [patch][5/5] powerpc V2: Add the general support for=20
> >> Embedded Floating-Point instructions
> >>
> >>
> >> On Feb 8, 2007, at 11:15 PM, Zhu Ebony-r57400 wrote:
> >>
> >>>
> >>>>>>> diff --git a/arch/powerpc/kernel/head_fsl_booke.S
> >> b/arch/powerpc/
> >>>>>>> kernel/head_fsl_booke.S index 66877bd..0d05db0 100644
> >>>>>>> --- a/arch/powerpc/kernel/head_fsl_booke.S
> >>>>>>> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> >>>>>>> @@ -705,7 +705,7 @@ #else
> >>>>>>> #endif /* CONFIG_SPE */
> >>>>>>>
> >>>>>>> /* SPE Floating Point Round */
> >>>>>>> - EXCEPTION(0x2050, SPEFloatingPointRound,
> >> unknown_exception,
> >>>>>>> EXC_XFER_EE)
> >>>>>>> + EXCEPTION(0x2050, SPEFloatingPointRound,
> >>>>>>> SPEFloatingPointException_Round, EXC_XFER_EE)
> >>>>>>>
> >>>>>>> /* Performance Monitor */
> >>>>>>> EXCEPTION(0x2060, PerformanceMonitor,=20
> >>>>>>> performance_monitor_exception, EXC_XFER_STD) @@=20
> -840,6 +840,8 @@
> >>>>>>> load_up_spe:
> >>>>>>> oris r5,r5,MSR_SPE@h
> >>>>>>> mtmsr r5 /* enable use
> >> of SPE now */
> >>>>>>> isync
> >>>>>>> + li r5,(SPEFSCR_FINVE | SPEFSCR_FDBZE |
> >> SPEFSCR_FUNFE |
> >>>>>>> SPEFSCR_FOVFE)
> >>>>>>> + mtspr SPRN_SPEFSCR,r5
> >>>>>>
> >>>>>> We should do this via INIT_THREAD, is there a reason that
> >>>> you want to
> >>>>>> set these always?
> >>>>>
> >>>>> I just thought it's the first time that an SPE instruction is=20
> >>>>> encountered, so I enable the exceptions here.
> >>>>
> >>>> Lets do this via INIT_THREAD instead, its cleaner. (just
> >> remember to
> >>>> add the proper ifdef protection for SPE_IEEE
> >>>
> >>> Talking about INIT_THREAD, I'm wondering where is the=20
> best place to=20
> >>> enble the exceptions? Please advice!
> >>
> >> What's the issue with enabling via INIT_THREAD? am I missing=20
> >> something?
> >
> > Do you mean that add
> > ".spefscr =3D SPEFSCR_FINV| =
SPEFSCR_FDBZE|SPEFSCR_FUNFE|SPEFSCR_FOVFE"
> > In the defination of INIT_THREAD?
>=20
> You may want to have something like #define=20
> SPE_EXCEPTION_ENABLE (SPEFSCR_FINV|=20
> SPEFSCR_FDBZE|SPEFSCR_FUNFE|SPEFSCR_FOVFE)
>=20
> Yep, with the proper #ifdef CONFIG_ protection.
OK, I got your point.
B.R.
Ebony
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 17:31 ` Kumar Gala
2007-02-09 5:15 ` Zhu Ebony-r57400
@ 2007-02-09 14:40 ` Segher Boessenkool
2007-03-08 7:04 ` Zhu Ebony-r57400
1 sibling, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2007-02-09 14:40 UTC (permalink / raw)
To: Kumar Gala; +Cc: paulus, linuxppc-dev
>>> I thought we were going to have some general Kconfig option
>>> to enable all this? EMDEDDED_FP_IEEE or something like that
>>
>> So that users have chance to enable/disable fully IEEE compliance?
>> Segher
>> had mentioned this, and it sounds reasonable.
>
> Its alot of code to bring in if you don't care about IEEE compliance.
Yes certainly, and that's important for embedded applications.
My point however is that this should be selectable *per process*
at runtime. Compare to the AltiVec situation (where processes
can select (non-)IEEE behaviour by themselves); most tasks do
*not* want IEEE behaviour as it is just too expensive (and not
necessary for many applications).
Segher
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-08 3:55 [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions ebony.zhu
2007-02-08 7:32 ` Kumar Gala
@ 2007-02-22 12:48 ` Sergei Shtylyov
2007-02-22 13:43 ` Sergei Shtylyov
1 sibling, 1 reply; 17+ messages in thread
From: Sergei Shtylyov @ 2007-02-22 12:48 UTC (permalink / raw)
To: ebony.zhu; +Cc: linuxppc-dev, paulus
Hello.
ebony.zhu@freescale.com wrote:
> Add the general support for Embedded Floating-Point instructions
> to fully comply with IEEE-754.
> Signed-off-by:Ebony Zhu <ebony.zhu@freescale.com>
> ---
> arch/powerpc/kernel/head_fsl_booke.S | 4
> arch/powerpc/kernel/traps.c | 57 +++++
> arch/powerpc/math-emu/Makefile | 25 ++
> arch/powerpc/math-emu/sfp-machine.h | 2
> arch/powerpc/math-emu/spe.h | 1
> arch/powerpc/sysdev/Makefile | 1
> arch/powerpc/sysdev/sigfpe_handler.c | 361 ++++++++++++++++++++++++++++++++++
I'm sorry, but is sysdev/ really fitting place for this file? Shouldn't it
be under kernel/ or math-emu/ instead?
WBR, Sergei
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-22 12:48 ` Sergei Shtylyov
@ 2007-02-22 13:43 ` Sergei Shtylyov
2007-02-22 16:36 ` Segher Boessenkool
0 siblings, 1 reply; 17+ messages in thread
From: Sergei Shtylyov @ 2007-02-22 13:43 UTC (permalink / raw)
To: ebony.zhu; +Cc: linuxppc-dev, paulus
Hello, I wrote:
>> Add the general support for Embedded Floating-Point instructions
>> to fully comply with IEEE-754.
>> arch/powerpc/sysdev/sigfpe_handler.c | 361
>> ++++++++++++++++++++++++++++++++++
> I'm sorry, but is sysdev/ really fitting place for this file?
> Shouldn't it be under kernel/ or math-emu/ instead?
Also, the name doesn't look fittingto me, since we're not handling
*SIGFPE* here (which is for userland), we're handling SPE exceptions.
WBR, Sergei
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-22 13:43 ` Sergei Shtylyov
@ 2007-02-22 16:36 ` Segher Boessenkool
2007-02-22 16:56 ` Sergei Shtylyov
0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2007-02-22 16:36 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev, paulus
>>> arch/powerpc/sysdev/sigfpe_handler.c | 361
>>> ++++++++++++++++++++++++++++++++++
>
>> I'm sorry, but is sysdev/ really fitting place for this file?
>> Shouldn't it be under kernel/ or math-emu/ instead?
>
> Also, the name doesn't look fittingto me, since we're not handling
> *SIGFPE* here (which is for userland), we're handling SPE exceptions.
arch/powerpc/math-emu/spe/<whatever>.c seems like a good
place?
Segher
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-22 16:36 ` Segher Boessenkool
@ 2007-02-22 16:56 ` Sergei Shtylyov
2007-02-22 18:22 ` Kumar Gala
0 siblings, 1 reply; 17+ messages in thread
From: Sergei Shtylyov @ 2007-02-22 16:56 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, paulus
Hello.
Segher Boessenkool wrote:
>>>> arch/powerpc/sysdev/sigfpe_handler.c | 361
>>>> ++++++++++++++++++++++++++++++++++
>>> I'm sorry, but is sysdev/ really fitting place for this file?
>>> Shouldn't it be under kernel/ or math-emu/ instead?
>> Also, the name doesn't look fittingto me, since we're not handling
>> *SIGFPE* here (which is for userland), we're handling SPE exceptions.
> arch/powerpc/math-emu/spe/<whatever>.c seems like a good
> place?
Yeah, certainly more like it. :-)
> Segher
WBR, Sergei
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-22 16:56 ` Sergei Shtylyov
@ 2007-02-22 18:22 ` Kumar Gala
2007-03-08 7:12 ` [patch][5/5] powerpc V2: Add the general support for EmbeddedFloating-Point instructions Zhu Ebony-r57400
0 siblings, 1 reply; 17+ messages in thread
From: Kumar Gala @ 2007-02-22 18:22 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev, paulus
On Feb 22, 2007, at 10:56 AM, Sergei Shtylyov wrote:
> Hello.
>
> Segher Boessenkool wrote:
>>>>> arch/powerpc/sysdev/sigfpe_handler.c | 361
>>>>> ++++++++++++++++++++++++++++++++++
>
>>>> I'm sorry, but is sysdev/ really fitting place for this file?
>>>> Shouldn't it be under kernel/ or math-emu/ instead?
>
>>> Also, the name doesn't look fittingto me, since we're not
>>> handling
>>> *SIGFPE* here (which is for userland), we're handling SPE
>>> exceptions.
>
>> arch/powerpc/math-emu/spe/<whatever>.c seems like a good
>> place?
>
> Yeah, certainly more like it. :-)
>
>> Segher
Agreed, this shouldn't have been in sysdev, didn't notice that :)
We should probably rename this as well, since its not just handling
the sigfpe part, but the actual fixup/emulation.
- k
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions
2007-02-09 14:40 ` Segher Boessenkool
@ 2007-03-08 7:04 ` Zhu Ebony-r57400
0 siblings, 0 replies; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-03-08 7:04 UTC (permalink / raw)
To: Segher Boessenkool, Kumar Gala; +Cc: linuxppc-dev, paulus
=20
> -----Original Message-----
> From: Segher Boessenkool [mailto:segher@kernel.crashing.org]=20
> Sent: Friday, February 09, 2007 10:40 PM
> To: Kumar Gala
> Cc: paulus@samba.org; Zhu Ebony-r57400; linuxppc-dev@ozlabs.org
> Subject: Re: [patch][5/5] powerpc V2: Add the general support=20
> for Embedded Floating-Point instructions
>=20
> >>> I thought we were going to have some general Kconfig option to=20
> >>> enable all this? EMDEDDED_FP_IEEE or something like that
> >>
> >> So that users have chance to enable/disable fully IEEE compliance?
> >> Segher
> >> had mentioned this, and it sounds reasonable.
> >
> > Its alot of code to bring in if you don't care about IEEE=20
> compliance.
>=20
> Yes certainly, and that's important for embedded applications.
>=20
> My point however is that this should be selectable *per=20
> process* at runtime. Compare to the AltiVec situation (where=20
> processes can select (non-)IEEE behaviour by themselves);=20
> most tasks do
> *not* want IEEE behaviour as it is just too expensive (and=20
> not necessary for many applications).
>=20
>=20
> Segher
Sorry for the delaying response since I just came back from vacation.
Agreed with you that the IEEE handler is expensive for processes. Do
you
think adding a switch to the Kconfig option is not enough? I'm
wondering how
to make it selectable *per process* at runtime.
Ebony
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [patch][5/5] powerpc V2: Add the general support for EmbeddedFloating-Point instructions
2007-02-22 18:22 ` Kumar Gala
@ 2007-03-08 7:12 ` Zhu Ebony-r57400
0 siblings, 0 replies; 17+ messages in thread
From: Zhu Ebony-r57400 @ 2007-03-08 7:12 UTC (permalink / raw)
To: Kumar Gala, Sergei Shtylyov, Segher Boessenkool; +Cc: linuxppc-dev, paulus
=20
> -----Original Message-----
> From: linuxppc-dev-bounces+ebony.zhu=3Dfreescale.com@ozlabs.org=20
> [mailto:linuxppc-dev-bounces+ebony.zhu=3Dfreescale.com@ozlabs.or
> g] On Behalf Of Kumar Gala
> Sent: Friday, February 23, 2007 2:23 AM
> To: Sergei Shtylyov
> Cc: linuxppc-dev@ozlabs.org; paulus@samba.org
> Subject: Re: [patch][5/5] powerpc V2: Add the general support=20
> for EmbeddedFloating-Point instructions
>=20
>=20
> On Feb 22, 2007, at 10:56 AM, Sergei Shtylyov wrote:
>=20
> > Hello.
> >
> > Segher Boessenkool wrote:
> >>>>> arch/powerpc/sysdev/sigfpe_handler.c | 361
> >>>>> ++++++++++++++++++++++++++++++++++
> >
> >>>> I'm sorry, but is sysdev/ really fitting place for this file?
> >>>> Shouldn't it be under kernel/ or math-emu/ instead?
> >
> >>> Also, the name doesn't look fittingto me, since we're not=20
> >>> handling
> >>> *SIGFPE* here (which is for userland), we're handling SPE=20
> >>> exceptions.
> >
> >> arch/powerpc/math-emu/spe/<whatever>.c seems like a good place?
> >
> > Yeah, certainly more like it. :-)
> >
> >> Segher
>=20
> Agreed, this shouldn't have been in sysdev, didn't notice that :)
>=20
> We should probably rename this as well, since its not just=20
> handling the sigfpe part, but the actual fixup/emulation.
>=20
> - k
Hi All,
Base on your suggestion, how about move sigfpe_handler.c to
arch/powerpc/math-emu/spe/spe_handler.c? Or do you have any other
suggestions on file name?
B.R.
Ebony
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2007-03-08 7:12 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-08 3:55 [patch][5/5] powerpc V2: Add the general support for Embedded Floating-Point instructions ebony.zhu
2007-02-08 7:32 ` Kumar Gala
2007-02-08 9:06 ` Zhu Ebony-r57400
2007-02-08 17:31 ` Kumar Gala
2007-02-09 5:15 ` Zhu Ebony-r57400
2007-02-09 5:28 ` Kumar Gala
2007-02-09 5:48 ` Zhu Ebony-r57400
2007-02-09 6:03 ` Kumar Gala
2007-02-09 6:27 ` Zhu Ebony-r57400
2007-02-09 14:40 ` Segher Boessenkool
2007-03-08 7:04 ` Zhu Ebony-r57400
2007-02-22 12:48 ` Sergei Shtylyov
2007-02-22 13:43 ` Sergei Shtylyov
2007-02-22 16:36 ` Segher Boessenkool
2007-02-22 16:56 ` Sergei Shtylyov
2007-02-22 18:22 ` Kumar Gala
2007-03-08 7:12 ` [patch][5/5] powerpc V2: Add the general support for EmbeddedFloating-Point instructions Zhu Ebony-r57400
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.