summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 04:42:38 +0000
committerian <ian@FreeBSD.org>2014-05-14 04:42:38 +0000
commit9277bb1a2b74a398eb2fd572785d2d6db451d8c1 (patch)
tree1db333efac7875c8cb26cb76df9eecc9a08af919
parentd168d59495df2455ad00bf4c5663f265523c3691 (diff)
downloadFreeBSD-src-9277bb1a2b74a398eb2fd572785d2d6db451d8c1.zip
FreeBSD-src-9277bb1a2b74a398eb2fd572785d2d6db451d8c1.tar.gz
MFC r258247, r258250, r258257
Remove a pointless #ifdef AIM. This is just PPC64 specific, including 64-bit Book-E. Make single precision floating point arithmetic actually work Split the function of the PCB_FPU flags into two: PCB_FPU now indicates that the actual FPU is enabled, while PCB_FPREGS indicates that the FPU state structure in the PCB is valid.
-rw-r--r--sys/conf/files.powerpc4
-rw-r--r--sys/powerpc/booke/trap.c5
-rw-r--r--sys/powerpc/fpu/fpu_emu.c15
-rw-r--r--sys/powerpc/fpu/fpu_explode.c1
-rw-r--r--sys/powerpc/include/counter.h6
-rw-r--r--sys/powerpc/include/pcb.h5
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c36
-rw-r--r--sys/powerpc/powerpc/fpu.c5
-rw-r--r--sys/powerpc/powerpc/swtch32.S4
9 files changed, 41 insertions, 40 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index d921a48..5dc582a 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -169,7 +169,7 @@ powerpc/powermac/uninorth.c optional powermac
powerpc/powermac/uninorthpci.c optional powermac pci
powerpc/powermac/vcoregpio.c optional powermac
powerpc/powermac/windtunnel.c optional powermac windtunnel
-powerpc/powerpc/altivec.c optional aim
+powerpc/powerpc/altivec.c standard
powerpc/powerpc/autoconf.c standard
powerpc/powerpc/bcopy.c standard
powerpc/powerpc/bus_machdep.c standard
@@ -186,7 +186,7 @@ powerpc/powerpc/dump_machdep.c standard
powerpc/powerpc/elf32_machdep.c optional powerpc | compat_freebsd32
powerpc/powerpc/elf64_machdep.c optional powerpc64
powerpc/powerpc/exec_machdep.c standard
-powerpc/powerpc/fpu.c optional aim
+powerpc/powerpc/fpu.c standard
powerpc/powerpc/fuswintr.c standard
powerpc/powerpc/gdb_machdep.c optional gdb
powerpc/powerpc/in_cksum.c optional inet | inet6
diff --git a/sys/powerpc/booke/trap.c b/sys/powerpc/booke/trap.c
index 959d8b1..72c4f47 100644
--- a/sys/powerpc/booke/trap.c
+++ b/sys/powerpc/booke/trap.c
@@ -194,6 +194,11 @@ trap(struct trapframe *frame)
case EXC_PGM: /* Program exception */
#ifdef FPU_EMU
+ if (!(td->td_pcb->pcb_flags & PCB_FPREGS)) {
+ bzero(&td->td_pcb->pcb_fpu,
+ sizeof(td->td_pcb->pcb_fpu));
+ td->td_pcb->pcb_flags |= PCB_FPREGS;
+ }
sig = fpu_emulate(frame,
(struct fpreg *)&td->td_pcb->pcb_fpu);
#else
diff --git a/sys/powerpc/fpu/fpu_emu.c b/sys/powerpc/fpu/fpu_emu.c
index 8cfc2a3..33c1f74 100644
--- a/sys/powerpc/fpu/fpu_emu.c
+++ b/sys/powerpc/fpu/fpu_emu.c
@@ -606,9 +606,11 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
rb = instr.i_a.i_frb;
rc = instr.i_a.i_frc;
- type = FTYPE_SNG;
- if (instr.i_any.i_opcd & 0x4)
- type = FTYPE_DBL;
+ /*
+ * All arithmetic operations work on registers, which
+ * are stored as doubles.
+ */
+ type = FTYPE_DBL;
switch ((unsigned int)instr.i_a.i_xo) {
case OPC59_FDIVS:
FPU_EMU_EVCNT_INCR(fdiv);
@@ -725,6 +727,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
return (NOTFPU);
break;
}
+
+ /* If the instruction was single precision, round */
+ if (!(instr.i_any.i_opcd & 0x4)) {
+ fpu_implode(fe, fp, FTYPE_SNG,
+ (u_int *)&fs->fpreg[rt]);
+ fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG, rt);
+ }
}
} else {
return (NOTFPU);
diff --git a/sys/powerpc/fpu/fpu_explode.c b/sys/powerpc/fpu/fpu_explode.c
index d2646fc..91d92b3 100644
--- a/sys/powerpc/fpu/fpu_explode.c
+++ b/sys/powerpc/fpu/fpu_explode.c
@@ -235,6 +235,7 @@ fpu_explode(struct fpemu *fe, struct fpn *fp, int type, int reg)
s = fpu_dtof(fp, s, space[1]);
break;
+ default:
panic("fpu_explode");
panic("fpu_explode: invalid type %d", type);
}
diff --git a/sys/powerpc/include/counter.h b/sys/powerpc/include/counter.h
index e876f62..4a9d647 100644
--- a/sys/powerpc/include/counter.h
+++ b/sys/powerpc/include/counter.h
@@ -34,7 +34,7 @@
#include <sys/proc.h>
#endif
-#if defined(AIM) && defined(__powerpc64__)
+#ifdef __powerpc64__
#define counter_enter() do {} while (0)
#define counter_exit() do {} while (0)
@@ -98,7 +98,7 @@ counter_u64_add(counter_u64_t c, int64_t inc)
: "cc", "memory");
}
-#else /* !AIM || !64bit */
+#else /* !64bit */
#define counter_enter() critical_enter()
#define counter_exit() critical_exit()
@@ -157,6 +157,6 @@ counter_u64_add(counter_u64_t c, int64_t inc)
counter_exit();
}
-#endif /* AIM 64bit */
+#endif /* 64bit */
#endif /* ! __MACHINE_COUNTER_H__ */
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 2076f42..a1a8132 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -47,8 +47,9 @@ struct pcb {
faultbuf *pcb_onfault; /* For use during
copyin/copyout */
int pcb_flags;
-#define PCB_FPU 1 /* Process had FPU initialized */
-#define PCB_VEC 2 /* Process had Altivec initialized */
+#define PCB_FPU 1 /* Process uses FPU */
+#define PCB_FPREGS 2 /* Process had FPU registers initialized */
+#define PCB_VEC 4 /* Process had Altivec initialized */
struct fpu {
double fpr[32];
double fpscr; /* FPSCR stored as double for easier access */
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index 038be9b..4b4be6c 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -381,19 +381,20 @@ grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
mcp->mc_gpr[4] = 0;
}
-#ifdef AIM
/*
* This assumes that floating-point context is *not* lazy,
* so if the thread has used FP there would have been a
* FP-unavailable exception that would have set things up
* correctly.
*/
- if (pcb->pcb_flags & PCB_FPU) {
- KASSERT(td == curthread,
- ("get_mcontext: fp save not curthread"));
- critical_enter();
- save_fpu(td);
- critical_exit();
+ if (pcb->pcb_flags & PCB_FPREGS) {
+ if (pcb->pcb_flags & PCB_FPU) {
+ KASSERT(td == curthread,
+ ("get_mcontext: fp save not curthread"));
+ critical_enter();
+ save_fpu(td);
+ critical_exit();
+ }
mcp->mc_flags |= _MC_FP_VALID;
memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double));
@@ -414,7 +415,6 @@ grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
mcp->mc_vrsave = pcb->pcb_vec.vrsave;
memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec));
}
-#endif
mcp->mc_len = sizeof(*mcp);
@@ -467,13 +467,9 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
else
tf->fixreg[2] = tls;
-#ifdef AIM
if (mcp->mc_flags & _MC_FP_VALID) {
- if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) {
- critical_enter();
- enable_fpu(td);
- critical_exit();
- }
+ /* enable_fpu() will happen lazily on a fault */
+ pcb->pcb_flags |= PCB_FPREGS;
memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double));
}
@@ -488,7 +484,6 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
pcb->pcb_vec.vrsave = mcp->mc_vrsave;
memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec));
}
-#endif
return (0);
}
@@ -625,7 +620,7 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs)
pcb = td->td_pcb;
- if ((pcb->pcb_flags & PCB_FPU) == 0)
+ if ((pcb->pcb_flags & PCB_FPREGS) == 0)
memset(fpregs, 0, sizeof(struct fpreg));
else
memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
@@ -654,14 +649,11 @@ set_dbregs(struct thread *td, struct dbreg *dbregs)
int
set_fpregs(struct thread *td, struct fpreg *fpregs)
{
-#ifdef AIM
struct pcb *pcb;
pcb = td->td_pcb;
- if ((pcb->pcb_flags & PCB_FPU) == 0)
- enable_fpu(td);
+ pcb->pcb_flags |= PCB_FPREGS;
memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
-#endif
return (0);
}
@@ -1021,14 +1013,10 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
tf->fixreg[3] = (register_t)arg;
if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
tf->srr0 = (register_t)entry;
- #ifdef AIM
tf->srr1 = PSL_USERSET | PSL_FE_DFLT;
#ifdef __powerpc64__
tf->srr1 &= ~PSL_SF;
#endif
- #else
- tf->srr1 = PSL_USERSET;
- #endif
} else {
#ifdef __powerpc64__
register_t entry_desc[3];
diff --git a/sys/powerpc/powerpc/fpu.c b/sys/powerpc/powerpc/fpu.c
index c4cc326..b719218 100644
--- a/sys/powerpc/powerpc/fpu.c
+++ b/sys/powerpc/powerpc/fpu.c
@@ -66,10 +66,11 @@ enable_fpu(struct thread *td)
* initialise the FPU registers and FPSCR to 0, and set the flag
* to indicate that the FPU is in use.
*/
+ pcb->pcb_flags |= PCB_FPU;
tf->srr1 |= PSL_FP;
- if (!(pcb->pcb_flags & PCB_FPU)) {
+ if (!(pcb->pcb_flags & PCB_FPREGS)) {
memset(&pcb->pcb_fpu, 0, sizeof pcb->pcb_fpu);
- pcb->pcb_flags |= PCB_FPU;
+ pcb->pcb_flags |= PCB_FPREGS;
}
/*
diff --git a/sys/powerpc/powerpc/swtch32.S b/sys/powerpc/powerpc/swtch32.S
index 5d88c2f..84f9ead 100644
--- a/sys/powerpc/powerpc/swtch32.S
+++ b/sys/powerpc/powerpc/swtch32.S
@@ -100,7 +100,6 @@ ENTRY(cpu_switch)
mr %r16,%r5 /* and the new lock */
mr %r17,%r6 /* and the PCB */
-#ifdef AIM
lwz %r7,PCB_FLAGS(%r17)
/* Save FPU context if needed */
andi. %r7, %r7, PCB_FPU
@@ -116,7 +115,6 @@ ENTRY(cpu_switch)
bl save_vec
.L2:
-#endif
mr %r3,%r14 /* restore old thread ptr */
bl pmap_deactivate /* Deactivate the current pmap */
@@ -143,7 +141,6 @@ blocked_loop:
mr %r3,%r2 /* Get new thread ptr */
bl pmap_activate /* Activate the new address space */
-#ifdef AIM
lwz %r6, PCB_FLAGS(%r17)
/* Restore FPU context if needed */
andi. %r6, %r6, PCB_FPU
@@ -160,7 +157,6 @@ blocked_loop:
bl enable_vec
.L4:
-#endif
/* thread to restore is in r3 */
mr %r3,%r17 /* Recover PCB ptr */
lmw %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs */
OpenPOWER on IntegriCloud