-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);
+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();
+}