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