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