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