Home | History | Annotate | Line # | Download | only in include
fpu.h revision 1.10
      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