Home | History | Annotate | Download | only in machine
      1 /*	$NetBSD: fpu.h,v 1.1 2003/04/26 18:39:40 fvdl 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  * Must be stored in memory on a 16-byte boundary.
     11  */
     12 
     13 struct fxsave64 {
     14 	u_int16_t  fx_fcw;
     15 	u_int16_t  fx_fsw;
     16 	u_int8_t   fx_ftw;
     17 	u_int8_t   fx_unused1;
     18 	u_int16_t  fx_fop;
     19 	u_int64_t  fx_rip;
     20 	u_int64_t  fx_rdp;
     21 	u_int32_t  fx_mxcsr;
     22 	u_int32_t  fx_mxcsr_mask;
     23 	u_int64_t  fx_st[8][2];   /* 8 normal FP regs */
     24 	u_int64_t  fx_xmm[16][2]; /* 16 SSE2 registers */
     25 	u_int8_t   fx_unused3[96];
     26 } __attribute__((packed));
     27 
     28 struct savefpu {
     29 	struct fxsave64 fp_fxsave;	/* see above */
     30 	u_int16_t fp_ex_sw;		/* saved status from last exception */
     31 	u_int16_t fp_ex_tw;		/* saved tag from last exception */
     32 };
     33 
     34 #ifdef _KERNEL
     35 
     36 /*
     37  * This one only used for backward compat coredumping.
     38  */
     39 struct oldfsave {
     40 	u_int16_t	fs_control;
     41 	u_int16_t	fs_unused0;
     42 	u_int16_t	fs_status;
     43 	u_int16_t	fs_unused1;
     44 	u_int16_t	fs_tag;
     45 	u_int16_t	fs_unused2;
     46 	u_int32_t	fs_ipoff;
     47 	u_int16_t	fs_ipsel;
     48 	u_int16_t	fs_op;
     49 	u_int32_t	fs_opoff;
     50 	u_int16_t	fs_opsel;
     51 } __attribute__ ((packed));
     52 
     53 #endif
     54 
     55 
     56 /*
     57  * The i387 defaults to Intel extended precision mode and round to nearest,
     58  * with all exceptions masked.
     59  */
     60 #define	__INITIAL_NPXCW__	0x037f
     61 #define __INITIAL_MXCSR__ 	0x1f80
     62 #define __INITIAL_MXCSR_MASK__	0xffbf
     63 
     64 /* NetBSD uses IEEE double precision. */
     65 #define	__NetBSD_NPXCW__	0x127f
     66 /* Linux just uses the default control word. */
     67 #define	__Linux_NPXCW__		0x037f
     68 
     69 /*
     70  * The standard control word from finit is 0x37F, giving:
     71  *	round to nearest
     72  *	64-bit precision
     73  *	all exceptions masked.
     74  *
     75  * Now we want:
     76  *	affine mode (if we decide to support 287's)
     77  *	round to nearest
     78  *	53-bit precision
     79  *	all exceptions masked.
     80  *
     81  * 64-bit precision often gives bad results with high level languages
     82  * because it makes the results of calculations depend on whether
     83  * intermediate values are stored in memory or in FPU registers.
     84  */
     85 
     86 #ifdef _KERNEL
     87 /*
     88  * XXX
     89  */
     90 struct trapframe;
     91 struct cpu_info;
     92 
     93 void fpuinit(struct cpu_info *);
     94 void fpudrop(void);
     95 void fpusave(struct lwp *);
     96 void fpudiscard(struct lwp *);
     97 void fputrap(struct trapframe *);
     98 void fpusave_lwp(struct lwp *, int);
     99 void fpusave_cpu(struct cpu_info *, int);
    100 
    101 #endif
    102 
    103 #endif /* _AMD64_FPU_H_ */
    104