* Set the state of the FPU. */
| 969 | * Set the state of the FPU. |
| 970 | */ |
| 971 | int |
| 972 | fpusetregs(struct thread *td, struct savefpu *addr, char *xfpustate, |
| 973 | size_t xfpustate_size) |
| 974 | { |
| 975 | struct pcb *pcb; |
| 976 | int error; |
| 977 | |
| 978 | addr->sv_env.en_mxcsr &= cpu_mxcsr_mask; |
| 979 | pcb = td->td_pcb; |
| 980 | error = 0; |
| 981 | critical_enter(); |
| 982 | if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { |
| 983 | error = fpusetxstate(td, xfpustate, xfpustate_size); |
| 984 | if (error == 0) { |
| 985 | bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); |
| 986 | fpurestore(get_pcb_user_save_td(td)); |
| 987 | set_pcb_flags(pcb, PCB_FPUINITDONE | |
| 988 | PCB_USERFPUINITDONE); |
| 989 | } |
| 990 | } else { |
| 991 | error = fpusetxstate(td, xfpustate, xfpustate_size); |
| 992 | if (error == 0) { |
| 993 | bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); |
| 994 | fpuuserinited(td); |
| 995 | } |
| 996 | } |
| 997 | critical_exit(); |
| 998 | return (error); |
| 999 | } |
| 1000 | |
| 1001 | /* |
| 1002 | * On AuthenticAMD processors, the fxrstor instruction does not restore |
no test coverage detected