summaryrefslogtreecommitdiffstats
path: root/sys/x86/include/fpu.h
blob: 0430108ec08e68b3ce9ae9c26117b2cbb4557557 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * William Jolitz.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)npx.h	5.3 (Berkeley) 1/18/91
 * $FreeBSD$
 */

/*
 * Floating Point Data Structures and Constants
 * W. Jolitz 1/90
 */

#ifndef _X86_FPU_H_
#define	_X86_FPU_H_

/* Environment information of floating point unit. */
struct env87 {
	int32_t		en_cw;		/* control word (16bits) */
	int32_t		en_sw;		/* status word (16bits) */
	int32_t		en_tw;		/* tag word (16bits) */
	int32_t		en_fip;		/* fp instruction pointer */
	uint16_t	en_fcs;		/* fp code segment selector */
	uint16_t	en_opcode;	/* opcode last executed (11 bits) */
	int32_t		en_foo;		/* fp operand offset */
	int32_t		en_fos;		/* fp operand segment selector */
};

/* Contents of each x87 floating point accumulator. */
struct fpacc87 {
	uint8_t		fp_bytes[10];
};

/* Floating point context. (i386 fnsave/frstor) */
struct save87 {
	struct env87	sv_env;		/* floating point control/status */
	struct fpacc87	sv_ac[8];	/* accumulator contents, 0-7 */
	uint8_t		sv_pad0[4];	/* saved status word (now unused) */
	uint8_t		sv_pad[64];
};

/* Contents of each SSE extended accumulator. */
struct xmmacc {
	uint8_t		xmm_bytes[16];
};

/* Contents of the upper 16 bytes of each AVX extended accumulator. */
struct ymmacc {
	uint8_t		ymm_bytes[16];
};

/* Rename structs below depending on machine architecture. */
#ifdef __i386__
#define	__envxmm32	envxmm
#else
#define	__envxmm32	envxmm32
#define	__envxmm64	envxmm
#endif

struct __envxmm32 {
	uint16_t	en_cw;		/* control word (16bits) */
	uint16_t	en_sw;		/* status word (16bits) */
	uint16_t	en_tw;		/* tag word (16bits) */
	uint16_t	en_opcode;	/* opcode last executed (11 bits) */
	uint32_t	en_fip;		/* fp instruction pointer */
	uint16_t	en_fcs;		/* fp code segment selector */
	uint16_t	en_pad0;	/* padding */
	uint32_t	en_foo;		/* fp operand offset */
	uint16_t	en_fos;		/* fp operand segment selector */
	uint16_t	en_pad1;	/* padding */
	uint32_t	en_mxcsr;	/* SSE control/status register */
	uint32_t	en_mxcsr_mask;	/* valid bits in mxcsr */
};

struct __envxmm64 {
	uint16_t	en_cw;		/* control word (16bits) */
	uint16_t	en_sw;		/* status word (16bits) */
	uint8_t		en_tw;		/* tag word (8bits) */
	uint8_t		en_zero;
	uint16_t	en_opcode;	/* opcode last executed (11 bits ) */
	uint64_t	en_rip;		/* fp instruction pointer */
	uint64_t	en_rdp;		/* fp operand pointer */
	uint32_t	en_mxcsr;	/* SSE control/status register */
	uint32_t	en_mxcsr_mask;	/* valid bits in mxcsr */
};

/* Floating point context. (i386 fxsave/fxrstor) */
struct savexmm {
	struct __envxmm32	sv_env;
	struct {
		struct fpacc87	fp_acc;
		uint8_t		fp_pad[6];      /* padding */
	} sv_fp[8];
	struct xmmacc		sv_xmm[8];
	uint8_t			sv_pad[224];
} __aligned(16);

#ifdef __i386__
union savefpu {
	struct save87	sv_87;
	struct savexmm	sv_xmm;
};
#else
/* Floating point context. (amd64 fxsave/fxrstor) */
struct savefpu {
	struct __envxmm64	sv_env;
	struct {
		struct fpacc87	fp_acc;
		uint8_t		fp_pad[6];	/* padding */
	} sv_fp[8];
	struct xmmacc		sv_xmm[16];
	uint8_t			sv_pad[96];
} __aligned(16);
#endif

struct xstate_hdr {
	uint64_t	xstate_bv;
	uint64_t	xstate_xcomp_bv;
	uint8_t		xstate_rsrv0[8];
	uint8_t		xstate_rsrv[40];
};
#define	XSTATE_XCOMP_BV_COMPACT	(1ULL << 63)

struct savexmm_xstate {
	struct xstate_hdr	sx_hd;
	struct ymmacc		sx_ymm[16];
};

struct savexmm_ymm {
	struct __envxmm32	sv_env;
	struct {
		struct fpacc87	fp_acc;
		int8_t		fp_pad[6];	/* padding */
	} sv_fp[8];
	struct xmmacc		sv_xmm[16];
	uint8_t			sv_pad[96];
	struct savexmm_xstate	sv_xstate;
} __aligned(64);

struct savefpu_xstate {
	struct xstate_hdr	sx_hd;
	struct ymmacc		sx_ymm[16];
};

struct savefpu_ymm {
	struct __envxmm64	sv_env;
	struct {
		struct fpacc87	fp_acc;
		int8_t		fp_pad[6];	/* padding */
	} sv_fp[8];
	struct xmmacc		sv_xmm[16];
	uint8_t			sv_pad[96];
	struct savefpu_xstate	sv_xstate;
} __aligned(64);

#undef __envxmm32
#undef __envxmm64

/*
 * The hardware default control word for i387's and later coprocessors is
 * 0x37F, giving:
 *
 *	round to nearest
 *	64-bit precision
 *	all exceptions masked.
 *
 * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc
 * because of the difference between memory and fpu register stack arguments.
 * If its using an intermediate fpu register, it has 80/64 bits to work
 * with.  If it uses memory, it has 64/53 bits to work with.  However,
 * gcc is aware of this and goes to a fair bit of trouble to make the
 * best use of it.
 *
 * This is mostly academic for AMD64, because the ABI prefers the use
 * SSE2 based math.  For FreeBSD/amd64, we go with the default settings.
 */
#define	__INITIAL_FPUCW__	0x037F
#define	__INITIAL_FPUCW_I386__	0x127F
#define	__INITIAL_NPXCW__	__INITIAL_FPUCW_I386__
#define	__INITIAL_MXCSR__	0x1F80
#define	__INITIAL_MXCSR_MASK__	0xFFBF

/*
 * The current value of %xcr0 is saved in the sv_pad[] field of the FPU
 * state in the NT_X86_XSTATE note in core dumps.  This offset is chosen
 * to match the offset used by NT_X86_XSTATE in other systems.
 */
#define	X86_XSTATE_XCR0_OFFSET	464

#endif /* !_X86_FPU_H_ */
OpenPOWER on IntegriCloud