mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
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
This commit is contained in:
parent
d713568142
commit
93312a9143
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=295132
|
@ -183,7 +183,7 @@ fpu_dumpfpn(struct fpn *fp)
|
|||
* (Typically: zero, SIGFPE, SIGILL, SIGSEGV)
|
||||
*/
|
||||
int
|
||||
fpu_emulate(struct trapframe *frame, struct fpreg *fpf)
|
||||
fpu_emulate(struct trapframe *frame, struct fpu *fpf)
|
||||
{
|
||||
static union instr insn;
|
||||
static struct fpemu fe;
|
||||
|
|
|
@ -138,7 +138,7 @@ struct fpn {
|
|||
* Emulator state.
|
||||
*/
|
||||
struct fpemu {
|
||||
struct fpreg *fe_fpstate; /* registers, etc */
|
||||
struct fpu *fe_fpstate; /* registers, etc */
|
||||
int fe_fpscr; /* fpscr copy (modified during op) */
|
||||
int fe_cx; /* keep track of exceptions */
|
||||
struct fpn fe_f1; /* operand 1 */
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
*/
|
||||
|
||||
struct proc;
|
||||
struct fpreg;
|
||||
struct fpu;
|
||||
struct trapframe;
|
||||
union instr;
|
||||
struct fpemu;
|
||||
struct fpn;
|
||||
|
||||
/* fpu.c */
|
||||
int fpu_emulate(struct trapframe *, struct fpreg *);
|
||||
int fpu_emulate(struct trapframe *, struct fpu *);
|
||||
int fpu_execute(struct trapframe *, struct fpemu *, union instr *);
|
||||
|
||||
/* fpu_explode.c */
|
||||
|
|
|
@ -18,12 +18,8 @@ struct reg {
|
|||
register_t pc;
|
||||
};
|
||||
|
||||
/* Must match pcb.pcb_fpu */
|
||||
struct fpreg {
|
||||
union {
|
||||
double fpr;
|
||||
uint64_t vsr[2];
|
||||
} fpreg[32];
|
||||
double fpreg[32];
|
||||
double fpscr;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue