From 9e608d32e9e85246decd868f326efde66108c7f3 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 28 Nov 2009 17:09:38 +0100 Subject: Add XMM FPU registers save/restore support. * i386/include/mach/i386/fp_reg.h (struct i386_fp_regs): Invert array indices. (struct i386_xfp_save): New structure. (FP_387X): New macro. * i386/i386/thread.h (struct i386_fpsave_state): Add xfp_save_state member, keep existing fp_save_state and fp_regs members in an unnamed union member. Move fp_valid member to the end of the structure. * i386/i386/fpu.h (fxsave, fxrstor): New macros. (fpu_save_context): Use fxsave() when FPU is FXSR-capable. * i386/i386/fpu.c: Include (mxcsr_feature_mask): New variable. (fp_save, fp_load): Add declaration. (init_fpu): Add FXSR-capable FPU detection. (fpu_module_init): Request 16-byte alignment to zinit() for i386_fpsave_state structures. (twd_i387_to_fxsr, twd_fxsr_to_i387): New functions. (fpu_set_state): Convert FPU state when FPU is FXSR-capable. (fpu_get_state): Convert FPU state when FPU is FXSR-capable. (fpexterrflt): Pass to i386_exception either xfp_save_state or fp_save_state according to FPU type. (fpastintr): Likewise. (fp_load): Likewise. Use fxrstor() when FPU is FXSR-capable. (fp_save): Use fxsave() when FPU is FXSR-capable. (fp_state_alloc): Add FXSR-aware initialization. --- i386/include/mach/i386/fp_reg.h | 23 ++++++++++++++++++++++- i386/include/mach/i386/thread_status.h | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'i386/include') diff --git a/i386/include/mach/i386/fp_reg.h b/i386/include/mach/i386/fp_reg.h index 6fe7af5..5673055 100644 --- a/i386/include/mach/i386/fp_reg.h +++ b/i386/include/mach/i386/fp_reg.h @@ -46,10 +46,30 @@ struct i386_fp_save { }; struct i386_fp_regs { - unsigned short fp_reg_word[5][8]; + unsigned short fp_reg_word[8][5]; /* space for 8 80-bit FP registers */ }; +struct i386_xfp_save { + unsigned short fp_control; /* control */ + unsigned short fp_status; /* status */ + unsigned short fp_tag; /* register tags */ + unsigned short fp_opcode; /* opcode of failed instruction */ + unsigned int fp_eip; /* eip at failed instruction */ + unsigned short fp_cs; /* cs at failed instruction */ + unsigned short fp_unused_1; + unsigned int fp_dp; /* data address */ + unsigned short fp_ds; /* data segment */ + unsigned short fp_unused_2; + unsigned int fp_mxcsr; /* MXCSR */ + unsigned int fp_mxcsr_mask; /* MXCSR_MASK */ + unsigned char fp_reg_word[8][16]; + /* space for 8 128-bit FP registers */ + unsigned char fp_xreg_word[8][16]; + /* space for 8 128-bit XMM registers */ + unsigned int padding[56]; +} __attribute__((aligned(16))); + /* * Control register */ @@ -104,5 +124,6 @@ struct i386_fp_regs { #define FP_SOFT 1 /* software FP emulator */ #define FP_287 2 /* 80287 */ #define FP_387 3 /* 80387 or 80486 */ +#define FP_387X 4 /* FXSAVE/RSTOR-capable */ #endif /* _MACH_I386_FP_REG_H_ */ diff --git a/i386/include/mach/i386/thread_status.h b/i386/include/mach/i386/thread_status.h index cc3dc66..5f20355 100644 --- a/i386/include/mach/i386/thread_status.h +++ b/i386/include/mach/i386/thread_status.h @@ -111,7 +111,7 @@ struct i386_thread_state { (sizeof (struct i386_fp_save) + sizeof (struct i386_fp_regs)) struct i386_float_state { - int fpkind; /* FP_NO..FP_387 (readonly) */ + int fpkind; /* FP_NO..FP_387X (readonly) */ int initialized; unsigned char hw_state[FP_STATE_BYTES]; /* actual "hardware" state */ int exc_status; /* exception status (readonly) */ -- cgit v1.2.3