diff options
author | Liu Yu <yu.liu@freescale.com> | 2008-10-28 11:50:21 +0800 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2008-12-03 08:19:16 -0600 |
commit | 6a800f36acd5bf06b5fe2cb27c4d0524d60c3df5 (patch) | |
tree | fe5611ddb3a92d5609736618aed5eb8d9e65ce7a /arch/powerpc/include/asm | |
parent | 033b8a333c66e0a7dc63132c1bd65175dc98bc25 (diff) |
powerpc: Add SPE/EFP math emulation for E500v1/v2 processors.
This patch add the handlers of SPE/EFP exceptions.
The code is used to emulate float point arithmetic,
when MSR(SPE) is enabled and receive EFP data interrupt or EFP round interrupt.
This patch has no conflict with or dependence on FP math-emu.
The code has been tested by TestFloat.
Now the code doesn't support SPE/EFP instructions emulation
(it won't be called when receive program interrupt),
but it could be easily added.
Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/include/asm')
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 6 | ||||
-rw-r--r-- | arch/powerpc/include/asm/sfp-machine.h | 36 |
2 files changed, 32 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 101ed87f7d8..cd7a47860e5 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -207,6 +207,11 @@ struct thread_struct { #define INIT_SP_LIMIT \ (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack) +#ifdef CONFIG_SPE +#define SPEFSCR_INIT .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, +#else +#define SPEFSCR_INIT +#endif #ifdef CONFIG_PPC32 #define INIT_THREAD { \ @@ -215,6 +220,7 @@ struct thread_struct { .fs = KERNEL_DS, \ .pgdir = swapper_pg_dir, \ .fpexc_mode = MSR_FE0 | MSR_FE1, \ + SPEFSCR_INIT \ } #else #define INIT_THREAD { \ diff --git a/arch/powerpc/include/asm/sfp-machine.h b/arch/powerpc/include/asm/sfp-machine.h index 88af036b1fe..3d9f831c3c5 100644 --- a/arch/powerpc/include/asm/sfp-machine.h +++ b/arch/powerpc/include/asm/sfp-machine.h @@ -97,6 +97,20 @@ #define _FP_KEEPNANFRACP 1 +#ifdef FP_EX_BOOKE_E500_SPE +#define FP_EX_INEXACT (1 << 21) +#define FP_EX_INVALID (1 << 20) +#define FP_EX_DIVZERO (1 << 19) +#define FP_EX_UNDERFLOW (1 << 18) +#define FP_EX_OVERFLOW (1 << 17) +#define FP_INHIBIT_RESULTS 0 + +#define __FPU_FPSCR (current->thread.spefscr) +#define __FPU_ENABLED_EXC \ +({ \ + (__FPU_FPSCR >> 2) & 0x1f; \ +}) +#else /* Exception flags. We use the bit positions of the appropriate bits in the FPSCR, which also correspond to the FE_* bits. This makes everything easier ;-). */ @@ -111,6 +125,18 @@ #define FP_EX_DIVZERO (1 << (31 - 5)) #define FP_EX_INEXACT (1 << (31 - 6)) +#define __FPU_FPSCR (current->thread.fpscr.val) + +/* We only actually write to the destination register + * if exceptions signalled (if any) will not trap. + */ +#define __FPU_ENABLED_EXC \ +({ \ + (__FPU_FPSCR >> 3) & 0x1f; \ +}) + +#endif + /* * If one NaN is signaling and the other is not, * we choose that one, otherwise we choose X. @@ -135,16 +161,6 @@ #include <linux/kernel.h> #include <linux/sched.h> -#define __FPU_FPSCR (current->thread.fpscr.val) - -/* We only actually write to the destination register - * if exceptions signalled (if any) will not trap. - */ -#define __FPU_ENABLED_EXC \ -({ \ - (__FPU_FPSCR >> 3) & 0x1f; \ -}) - #define __FPU_TRAP_P(bits) \ ((__FPU_ENABLED_EXC & (bits)) != 0) |