1 /* $NetBSD: fpu.h,v 1.11 2013/12/11 22:06:51 dsl Exp $ */ 2 3 #ifndef _AMD64_FPU_H_ 4 #define _AMD64_FPU_H_ 5 6 /* 7 * NetBSD/amd64 only uses the extended save/restore format used 8 * by fxsave/fsrestore, to always deal with the SSE registers, 9 * which are part of the ABI to pass floating point values. 10 * 11 * The memory used for the 'fsave' instruction must be 16 byte aligned, 12 * but the definition here isn't aligned to avoid padding elsewhere. 13 */ 14 15 struct fxsave64 { 16 uint16_t fx_fcw; /* 0: FPU control word */ 17 uint16_t fx_fsw; /* 2: FPU status word */ 18 uint8_t fx_ftw; /* 4: Abridged FPU tag word */ 19 uint8_t fx_reserved1; /* 5: */ 20 uint16_t fx_fop; /* 6: Low 11 bits are FPU opcode */ 21 uint64_t fx_rip; /* 8: Address of faulting instruction */ 22 uint64_t fx_rdp; /* 16: Data address associated with fault */ 23 uint32_t fx_mxcsr; /* 24: SIMD control & status */ 24 uint32_t fx_mxcsr_mask; /* 28: */ 25 uint64_t fx_st[8][2]; /* 32: 8 normal FP regs (80 bit) */ 26 uint64_t fx_xmm[16][2]; /* 160: 16 SSE2 registers */ 27 uint8_t fx_reserved2[48]; /* 416: */ 28 uint8_t fx_available[48]; /* 464: could be used by kernel */ 29 }; 30 31 __CTASSERT(sizeof (struct fxsave64) == 512); 32 33 struct savefpu { 34 struct fxsave64 fp_fxsave; /* see above */ 35 }; 36 37 /* 38 * The i387 defaults to Intel extended precision mode and round to nearest, 39 * with all exceptions masked. 40 */ 41 #define __INITIAL_NPXCW__ 0x037f 42 #define __INITIAL_MXCSR__ 0x1f80 43 #define __INITIAL_MXCSR_MASK__ 0xffbf 44 45 /* Modern NetBSD uses the default control word.. */ 46 #define __NetBSD_NPXCW__ 0x037f 47 /* NetBSD before 6.99.26 forced IEEE double precision. */ 48 #define __NetBSD_COMPAT_NPXCW__ 0x127f 49 /* Linux just uses the default control word. */ 50 #define __Linux_NPXCW__ 0x037f 51 52 /* 53 * The standard control word from finit is 0x37F, giving: 54 * round to nearest 55 * 64-bit precision 56 * all exceptions masked. 57 * 58 * Now we want: 59 * affine mode (if we decide to support 287's) 60 * round to nearest 61 * 53-bit precision 62 * all exceptions masked. 63 * 64 * 64-bit precision often gives bad results with high level languages 65 * because it makes the results of calculations depend on whether 66 * intermediate values are stored in memory or in FPU registers. 67 */ 68 69 #ifdef _KERNEL 70 /* 71 * XXX 72 */ 73 struct trapframe; 74 struct cpu_info; 75 76 void fpuinit(struct cpu_info *); 77 void fpudrop(void); 78 void fpusave(struct lwp *); 79 void fpudiscard(struct lwp *); 80 void fputrap(struct trapframe *); 81 void fpusave_lwp(struct lwp *, bool); 82 void fpusave_cpu(bool); 83 84 #endif 85 86 #endif /* _AMD64_FPU_H_ */ 87