summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powerpc
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-02-01 23:12:04 +0000
committerjhb <jhb@FreeBSD.org>2016-02-01 23:12:04 +0000
commit0e26efe2d7cf6ba3520c373445f73eca41063634 (patch)
treeb4cc30e17f8aa862ea6005df019e28fa263b8435 /sys/powerpc/powerpc
parent0924d1687c5bc1e7e372986f9ec31e50ccd21c7b (diff)
downloadFreeBSD-src-0e26efe2d7cf6ba3520c373445f73eca41063634.zip
FreeBSD-src-0e26efe2d7cf6ba3520c373445f73eca41063634.tar.gz
Restore the ABI of 'struct fpreg' on powerpc.
The PT_{GET,SET}FPREGS requests use 'struct fpreg' and the NT_FPREGSET core note stores a copy of 'struct fpreg'. As with x86 and the floating point state there compared to the extended state in XSAVE, struct fpreg on powerpc now only holds the 'base' FP state, and setting it via PT_SETFPREGS leaves the extended vector state in a thread unchanged. Reviewed by: jhibbits Differential Revision: https://reviews.freebsd.org/D5004
Diffstat (limited to 'sys/powerpc/powerpc')
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index d657244f..d8238a1 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -608,13 +608,18 @@ int
fill_fpregs(struct thread *td, struct fpreg *fpregs)
{
struct pcb *pcb;
+ int i;
pcb = td->td_pcb;
if ((pcb->pcb_flags & PCB_FPREGS) == 0)
memset(fpregs, 0, sizeof(struct fpreg));
- else
- memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
+ else {
+ memcpy(&fpregs->fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
+ for (i = 0; i < 32; i++)
+ memcpy(&fpregs->fpreg[i], &pcb->pcb_fpu.fpr[i].fpr,
+ sizeof(double));
+ }
return (0);
}
@@ -641,10 +646,15 @@ int
set_fpregs(struct thread *td, struct fpreg *fpregs)
{
struct pcb *pcb;
+ int i;
pcb = td->td_pcb;
pcb->pcb_flags |= PCB_FPREGS;
- memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
+ memcpy(&pcb->pcb_fpu.fpscr, &fpregs->fpscr, sizeof(double));
+ for (i = 0; i < 32; i++) {
+ memcpy(&pcb->pcb_fpu.fpr[i].fpr, &fpregs->fpreg[i],
+ sizeof(double));
+ }
return (0);
}
@@ -1060,7 +1070,7 @@ ppc_instr_emulate(struct trapframe *frame, struct pcb *pcb)
bzero(&pcb->pcb_fpu, sizeof(pcb->pcb_fpu));
pcb->pcb_flags |= PCB_FPREGS;
}
- sig = fpu_emulate(frame, (struct fpreg *)&pcb->pcb_fpu);
+ sig = fpu_emulate(frame, &pcb->pcb_fpu);
#endif
return (sig);
OpenPOWER on IntegriCloud