1 /* $NetBSD: fpu.h,v 1.10 2013/12/01 01:05:16 christos 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 struct savefpu_i387 { 38 uint16_t fp_ex_sw; /* saved status from last exception */ 39 uint16_t fp_ex_tw; /* saved tag from last exception */ 40 }; 41 42 /* 43 * The i387 defaults to Intel extended precision mode and round to nearest, 44 * with all exceptions masked. 45 */ 46 #define __INITIAL_NPXCW__ 0x037f 47 #define __INITIAL_MXCSR__ 0x1f80 48 #define __INITIAL_MXCSR_MASK__ 0xffbf 49 50 /* Modern NetBSD uses the default control word.. */ 51 #define __NetBSD_NPXCW__ 0x037f 52 /* NetBSD before 6.99.26 forced IEEE double precision. */ 53 #define __NetBSD_COMPAT_NPXCW__ 0x127f 54 /* Linux just uses the default control word. */ 55 #define __Linux_NPXCW__ 0x037f 56 57 /* 58 * The standard control word from finit is 0x37F, giving: 59 * round to nearest 60 * 64-bit precision 61 * all exceptions masked. 62 * 63 * Now we want: 64 * affine mode (if we decide to support 287's) 65 * round to nearest 66 * 53-bit precision 67 * all exceptions masked. 68 * 69 * 64-bit precision often gives bad results with high level languages 70 * because it makes the results of calculations depend on whether 71 * intermediate values are stored in memory or in FPU registers. 72 */ 73 74 #ifdef _KERNEL 75 /* 76 * XXX 77 */ 78 struct trapframe; 79 struct cpu_info; 80 81 void fpuinit(struct cpu_info *); 82 void fpudrop(void); 83 void fpusave(struct lwp *); 84 void fpudiscard(struct lwp *); 85 void fputrap(struct trapframe *); 86 void fpusave_lwp(struct lwp *, bool); 87 void fpusave_cpu(bool); 88 89 #endif 90 91 #endif /* _AMD64_FPU_H_ */ 92