Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 123061
b: refs/heads/master
c: 6a800f3
h: refs/heads/master
i:
  123059: cbc9ba7
v: v3
  • Loading branch information
Liu Yu authored and Kumar Gala committed Dec 3, 2008
1 parent 9786282 commit 349dea8
Show file tree
Hide file tree
Showing 7 changed files with 814 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 033b8a333c66e0a7dc63132c1bd65175dc98bc25
refs/heads/master: 6a800f36acd5bf06b5fe2cb27c4d0524d60c3df5
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 { \
Expand All @@ -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 { \
Expand Down
36 changes: 26 additions & 10 deletions trunk/arch/powerpc/include/asm/sfp-machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;-). */
Expand All @@ -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.
Expand All @@ -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)

Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/powerpc/kernel/head_fsl_booke.S
Original file line number Diff line number Diff line change
Expand Up @@ -685,12 +685,13 @@ interrupt_base:
/* SPE Floating Point Data */
#ifdef CONFIG_SPE
EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
#else
EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */

/* SPE Floating Point Round */
EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointRoundException, EXC_XFER_EE)
#else
EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */

/* Performance Monitor */
EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
Expand Down
62 changes: 55 additions & 7 deletions trunk/arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1160,37 +1160,85 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address,
#ifdef CONFIG_SPE
void SPEFloatingPointException(struct pt_regs *regs)
{
extern int do_spe_mathemu(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;

/* Hardware does not neccessarily set sticky
* underflow/overflow/invalid flags */
if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
code = FPE_FLTOVF;
spefscr |= SPEFSCR_FOVFS;
}
else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
code = FPE_FLTUND;
spefscr |= SPEFSCR_FUNFS;
}
else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
code = FPE_FLTDIV;
else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
code = FPE_FLTINV;
spefscr |= SPEFSCR_FINVS;
}
else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
code = FPE_FLTRES;

current->thread.spefscr = spefscr;
err = do_spe_mathemu(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, code, regs->nip);
}

_exception(SIGFPE, regs, code, regs->nip);
return;
}

void SPEFloatingPointRoundException(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

/*
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/math-emu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
mtfsf.o mtfsfi.o stfiwx.o stfs.o

obj-$(CONFIG_SPE) += math_efp.o

CFLAGS_fabs.o = -fno-builtin-fabs
CFLAGS_math.o = -fno-builtin-fabs

Expand Down
Loading

0 comments on commit 349dea8

Please sign in to comment.