X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/89b3af67bb32e691275bf6fa803d1834b2284115..21362eb3e66fd2c787aee132bce100a44d71a99c:/osfmk/i386/fpu.h diff --git a/osfmk/i386/fpu.h b/osfmk/i386/fpu.h index 7979b66fa..a053bd56c 100644 --- a/osfmk/i386/fpu.h +++ b/osfmk/i386/fpu.h @@ -64,36 +64,12 @@ * Macro definitions for routines to manipulate the * floating-point processor. */ -#include + +#include #include #include #include #include -#include - -extern int fp_kind; - -extern void init_fpu(void); -extern void fpu_module_init(void); -extern void fpu_free( - struct x86_fpsave_state * fps); -extern kern_return_t fpu_set_fxstate( - thread_t thr_act, - thread_state_t state); -extern kern_return_t fpu_get_fxstate( - thread_t thr_act, - thread_state_t state); -extern void fpu_dup_fxstate( - thread_t parent, - thread_t child); -extern void fpnoextflt(void); -extern void fpextovrflt(void); -extern void fpexterrflt(void); -extern void fpSSEexterrflt(void); -extern void fpflush(thread_t); -extern void fp_setvalid(boolean_t); -extern void fxsave64(struct x86_fx_save *); -extern void fxrstor64(struct x86_fx_save *); /* * FPU instructions. @@ -133,45 +109,58 @@ extern __inline__ unsigned short fnstsw(void) #define FXSAFE() (fp_kind == FP_FXSR) - -static inline void clear_fpu(void) -{ - set_ts(); -} +#define fpu_load_context(pcb) /* * Save thread`s FPU context. + * If only one CPU, we just set the task-switched bit, + * to keep the new thread from using the coprocessor. + * If multiple CPUs, we save the entire state. + * NOTE: in order to provide backwards compatible support in the kernel. When saving SSE2 state, we also save the + * FP state in it's old location. Otherwise fpu_get_state() and fpu_set_state() will stop working */ +#define fpu_save_context(thread) \ + { \ + register struct i386_fpsave_state *ifps; \ + ifps = (thread)->machine.pcb->ims.ifps; \ + if (ifps != 0 && !ifps->fp_valid) { \ + /* registers are in FPU - save to memory */ \ + ifps->fp_valid = TRUE; \ + ifps->fp_save_flavor = FP_387; \ + if (FXSAFE()) { \ + fxsave(&ifps->fx_save_state); \ + ifps->fp_save_flavor = FP_FXSR; \ + } \ + fnsave(&ifps->fp_save_state); \ + } \ + set_ts(); \ + } + + + +extern int fp_kind; -static inline void fpu_save_context(thread_t thread) -{ - struct x86_fpsave_state *ifps; - - assert(ml_get_interrupts_enabled() == FALSE); - ifps = (thread)->machine.pcb->ifps; - if (ifps != 0 && !ifps->fp_valid) { - /* Clear CR0.TS in preparation for the FP context save. In - * theory, this shouldn't be necessary since a live FPU should - * indicate that TS is clear. However, various routines - * (such as sendsig & sigreturn) manipulate TS directly. - */ - clear_ts(); - /* registers are in FPU - save to memory */ - ifps->fp_valid = TRUE; - if (!thread_is_64bit(thread) || is_saved_state32(thread->machine.pcb->iss)) { - /* save the compatibility/legacy mode XMM+x87 state */ - fxsave(&ifps->fx_save_state); - ifps->fp_save_layout = FXSAVE32; - } - else { - /* Execute a brief jump to 64-bit mode to save the 64 - * bit state - */ - fxsave64(&ifps->fx_save_state); - ifps->fp_save_layout = FXSAVE64; - } - } - set_ts(); -} +extern void init_fpu(void); +extern void fpu_module_init(void); +extern void fpu_free( + struct i386_fpsave_state * fps); +extern kern_return_t fpu_set_state( + thread_t thr_act, + struct i386_float_state * st); +extern kern_return_t fpu_get_state( + thread_t thr_act, + struct i386_float_state * st); +extern kern_return_t fpu_set_fxstate( + thread_t thr_act, + struct i386_float_state * st); +extern kern_return_t fpu_get_fxstate( + thread_t thr_act, + struct i386_float_state * st); +extern void fpnoextflt(void); +extern void fpextovrflt(void); +extern void fpexterrflt(void); +extern void fp_state_alloc(void); +extern void fpintr(void); +extern void fpflush(thread_t); #endif /* _I386_FPU_H_ */