- Rename pcb_fpstate to pcb_ufp (user floating point), and change it to

a simple array of 64 ints.
- Use a critical section when saving floating point state in cpu_fork
  instead of sched_lock.
This commit is contained in:
Jake Burkholder 2003-04-01 04:02:45 +00:00
parent 70d5093a8b
commit f217a77ce4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112920
7 changed files with 39 additions and 70 deletions

View File

@ -27,26 +27,13 @@
#ifndef _MACHINE_FP_H_
#define _MACHINE_FP_H_
/* A block of 8 double-precision (16 single-precision) FP registers. */
struct fpblock {
u_int fpb_i[16];
};
struct fpstate {
struct fpblock fp_fb[4];
};
#ifdef _KERNEL
struct pcb;
struct thread;
/*
* Note: The pointers passed to the next two functions must be aligned on
* 64 byte boundaries.
* Note: The pointer passed to savefpctx must be aligned on a 64 byte
* boundary.
*/
void savefpctx(struct fpstate *);
void restorefpctx(struct fpstate *);
void savefpctx(uint32_t *fp);
#endif /* _KERNEL */
#endif /* !_MACHINE_FP_H_ */

View File

@ -29,14 +29,13 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
#include <machine/fp.h>
#include <machine/frame.h>
#define MAXWIN 8
/* NOTE: pcb_fpstate must be aligned on a 64 byte boundary. */
/* NOTE: pcb_ufp must be aligned on a 64 byte boundary. */
struct pcb {
struct fpstate pcb_fpstate;
uint32_t pcb_ufp[64];
u_long pcb_sp;
u_long pcb_pc;
u_long pcb_nsaved;

View File

@ -482,18 +482,6 @@ END(rsf_fatal)
.endr
.endm
.macro tl0_fp_restore
wr %g0, FPRS_FEF, %fprs
wr %g0, ASI_BLK_S, %asi
ldda [PCB_REG + PCB_FPSTATE + FP_FB0] %asi, %f0
ldda [PCB_REG + PCB_FPSTATE + FP_FB1] %asi, %f16
ldda [PCB_REG + PCB_FPSTATE + FP_FB2] %asi, %f32
ldda [PCB_REG + PCB_FPSTATE + FP_FB3] %asi, %f48
membar #Sync
done
.align 32
.endm
.macro tl0_insn_excptn
wrpr %g0, PSTATE_ALT, %pstate
wr %g0, ASI_IMMU, %asi
@ -1188,6 +1176,23 @@ END(tl0_sftrap)
.align 32
.endm
.macro tl0_fp_restore
ba,a %xcc, tl0_fp_restore
nop
.align 32
.endm
ENTRY(tl0_fp_restore)
wr %g0, FPRS_FEF, %fprs
wr %g0, ASI_BLK_S, %asi
ldda [PCB_REG + PCB_UFP + (0 * 64)] %asi, %f0
ldda [PCB_REG + PCB_UFP + (1 * 64)] %asi, %f16
ldda [PCB_REG + PCB_UFP + (2 * 64)] %asi, %f32
ldda [PCB_REG + PCB_UFP + (3 * 64)] %asi, %f48
membar #Sync
done
END(tl0_fp_restore)
.macro tl1_insn_excptn
wrpr %g0, PSTATE_ALT, %pstate
wr %g0, ASI_IMMU, %asi

View File

@ -243,7 +243,7 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(PCB_SIZEOF, sizeof(struct pcb));
ASSYM(PCB_FPSTATE, offsetof(struct pcb, pcb_fpstate));
ASSYM(PCB_UFP, offsetof(struct pcb, pcb_ufp));
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
ASSYM(PCB_PC, offsetof(struct pcb, pcb_pc));
ASSYM(PCB_NSAVED, offsetof(struct pcb, pcb_nsaved));
@ -255,11 +255,6 @@ ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active));
ASSYM(PM_CONTEXT, offsetof(struct pmap, pm_context));
ASSYM(PM_TSB, offsetof(struct pmap, pm_tsb));
ASSYM(FP_FB0, offsetof(struct fpstate, fp_fb[0]));
ASSYM(FP_FB1, offsetof(struct fpstate, fp_fb[1]));
ASSYM(FP_FB2, offsetof(struct fpstate, fp_fb[2]));
ASSYM(FP_FB3, offsetof(struct fpstate, fp_fb[3]));
ASSYM(CCFSZ, sizeof(struct frame));
ASSYM(SPOFF, SPOFF);

View File

@ -682,8 +682,7 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs)
pcb = td->td_pcb;
tf = td->td_frame;
bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs,
sizeof(pcb->pcb_fpstate.fp_fb));
bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs));
fpregs->fr_fsr = tf->tf_fsr;
fpregs->fr_gsr = tf->tf_gsr;
return (0);
@ -697,8 +696,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs)
pcb = td->td_pcb;
tf = td->td_frame;
bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb,
sizeof(fpregs->fr_regs));
bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp));
tf->tf_fsr = fpregs->fr_fsr;
tf->tf_gsr = fpregs->fr_gsr;
return (0);

View File

@ -68,10 +68,10 @@ ENTRY(cpu_switch)
nop
wr %g0, FPRS_FEF, %fprs
wr %g0, ASI_BLK_S, %asi
stda %f0, [%l1 + PCB_FPSTATE + FP_FB0] %asi
stda %f16, [%l1 + PCB_FPSTATE + FP_FB1] %asi
stda %f32, [%l1 + PCB_FPSTATE + FP_FB2] %asi
stda %f48, [%l1 + PCB_FPSTATE + FP_FB3] %asi
stda %f0, [%l1 + PCB_UFP + (0 * 64)] %asi
stda %f16, [%l1 + PCB_UFP + (1 * 64)] %asi
stda %f32, [%l1 + PCB_UFP + (2 * 64)] %asi
stda %f48, [%l1 + PCB_UFP + (3 * 64)] %asi
membar #Sync
wr %g0, 0, %fprs
andn %l3, FPRS_FEF, %l3
@ -278,31 +278,16 @@ ENTRY(savectx)
END(savectx)
/*
* void savefpctx(struct fpstate *);
* void savefpctx(uint32_t *);
*/
ENTRY(savefpctx)
wr %g0, FPRS_FEF, %fprs
wr %g0, ASI_BLK_S, %asi
stda %f0, [%o0 + PCB_FPSTATE + FP_FB0] %asi
stda %f16, [%o0 + PCB_FPSTATE + FP_FB1] %asi
stda %f32, [%o0 + PCB_FPSTATE + FP_FB2] %asi
stda %f48, [%o0 + PCB_FPSTATE + FP_FB3] %asi
stda %f0, [%o0 + (0 * 64)] %asi
stda %f16, [%o0 + (1 * 64)] %asi
stda %f32, [%o0 + (2 * 64)] %asi
stda %f48, [%o0 + (3 * 64)] %asi
membar #Sync
retl
wr %g0, 0, %fprs
END(savefpctx)
/*
* void restorefpctx(struct fpstate *);
*/
ENTRY(restorefpctx)
wr %g0, FPRS_FEF, %fprs
wr %g0, ASI_BLK_S, %asi
ldda [%o0 + PCB_FPSTATE + FP_FB0] %asi, %f0
ldda [%o0 + PCB_FPSTATE + FP_FB1] %asi, %f16
ldda [%o0 + PCB_FPSTATE + FP_FB2] %asi, %f32
ldda [%o0 + PCB_FPSTATE + FP_FB3] %asi, %f48
membar #Sync
retl
wr %g0, 0, %fprs
END(restorefpctx)

View File

@ -71,6 +71,7 @@
#include <machine/cache.h>
#include <machine/cpu.h>
#include <machine/fp.h>
#include <machine/fsr.h>
#include <machine/frame.h>
#include <machine/md_var.h>
@ -186,11 +187,10 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
/*
* Ensure that p1's pcb is up to date.
*/
if ((td1->td_frame->tf_fprs & FPRS_FEF) != 0) {
mtx_lock_spin(&sched_lock);
savefpctx(&pcb1->pcb_fpstate);
mtx_unlock_spin(&sched_lock);
}
critical_enter();
if ((td1->td_frame->tf_fprs & FPRS_FEF) != 0)
savefpctx(pcb1->pcb_ufp);
critical_exit();
/* Make sure the copied windows are spilled. */
flushw();
/* Copy the pcb (this will copy the windows saved in the pcb, too). */