Tue Feb 18 18:39:11 2014 UTC ()
It seems that firefox includes machine/fpu.h on amd64.
Add the file back so that the firwfox source doesn't have to depend
on the version of netbsd it is being compiled for.
(The i386 version doesn't play the same games in its SIGFPE handler.)


(dsl)
diff -r0 -r1.14 src/sys/arch/amd64/include/fpu.h
diff -r1.7 -r1.8 src/sys/arch/x86/include/cpu_extended_state.h

File Added: src/sys/arch/amd64/include/fpu.h
#ifndef _AMD64_FPU_H_
#define _AMD64_FPU_H_

/*
 * This file is only present for backwards compatibility with
 * a few user programs, particularly firefox.
 */

#ifndef _KERNEL
#define fxsave64 fxsave
#include <x86/cpu_extended_state.h>
#endif

#endif

cvs diff -r1.7 -r1.8 src/sys/arch/x86/include/cpu_extended_state.h (switch to unified diff)

--- src/sys/arch/x86/include/cpu_extended_state.h 2014/02/15 10:11:15 1.7
+++ src/sys/arch/x86/include/cpu_extended_state.h 2014/02/18 18:39:10 1.8
@@ -1,251 +1,246 @@ @@ -1,251 +1,246 @@
1/* $NetBSD: cpu_extended_state.h,v 1.7 2014/02/15 10:11:15 dsl Exp $ */ 1/* $NetBSD: cpu_extended_state.h,v 1.8 2014/02/18 18:39:10 dsl Exp $ */
2 2
3#ifndef _X86_CPU_EXTENDED_STATE_H_ 3#ifndef _X86_CPU_EXTENDED_STATE_H_
4#define _X86_CPU_EXTENDED_STATE_H_ 4#define _X86_CPU_EXTENDED_STATE_H_
5 5
6/* 6/*
7 * This file contains definitions of structures that match the memory 7 * This file contains definitions of structures that match the memory
8 * layouts used x86 processors to save floating point registers and other 8 * layouts used x86 processors to save floating point registers and other
9 * extended cpu state. 9 * extended cpu state.
10 * This includes registers (etc) used by SSE/SSE2/SSE3/SSSE3/SSE4 and 10 * This includes registers (etc) used by SSE/SSE2/SSE3/SSSE3/SSE4 and
11 * the later AVX instructions. 11 * the later AVX instructions.
12 * The definitions are such that any future 'extended state' should 12 * The definitions are such that any future 'extended state' should
13 * be handled (provided the kernel doesn't need to know the actual contents. 13 * be handled (provided the kernel doesn't need to know the actual contents.
14 * 14 *
15 * The actual structures the cpu accesses must be aligned to 16 for 15 * The actual structures the cpu accesses must be aligned to 16 for
16 * FXSAVE and 64 for XSAVE. The types aren't aligned because copies 16 * FXSAVE and 64 for XSAVE. The types aren't aligned because copies
17 * do not need extra alignment. 17 * do not need extra alignment.
18 * 18 *
19 * The slightly different layout saved by the i387 fsave in also defined. 19 * The slightly different layout saved by the i387 fsave in also defined.
20 * This is only normally written by pre Pentium II type cpus that don't  20 * This is only normally written by pre Pentium II type cpus that don't
21 * support the fxsave instruction.  21 * support the fxsave instruction.
22 * 22 *
23 * Associated save instructions: 23 * Associated save instructions:
24 * FNSAVE: Saves x87 state in 108 bytes (original i387 layout). 24 * FNSAVE: Saves x87 state in 108 bytes (original i387 layout).
25 * Then reinitialies the fpu. 25 * Then reinitialies the fpu.
26 * FSAVE: Encodes to FWAIT followed by FNSAVE. 26 * FSAVE: Encodes to FWAIT followed by FNSAVE.
27 * FXSAVE: Saves the x87 state and XMM (aka SSE) registers to the 27 * FXSAVE: Saves the x87 state and XMM (aka SSE) registers to the
28 * first 448 (max) bytes of a 512 byte area. 28 * first 448 (max) bytes of a 512 byte area.
29 * This layout does not match that written by FNSAVE. 29 * This layout does not match that written by FNSAVE.
30 * XSAVE: Uses the same layout for the x87 and XMM registers, 30 * XSAVE: Uses the same layout for the x87 and XMM registers,
31 * followed by a 64byte header and separate save areas 31 * followed by a 64byte header and separate save areas
32 * for additional extended cpu state. 32 * for additional extended cpu state.
33 * The x87 state is always saved, the others conditionally. 33 * The x87 state is always saved, the others conditionally.
34 * XSAVEOPT: As XSAVE but (IIRC) only writes the registers blocks 34 * XSAVEOPT: As XSAVE but (IIRC) only writes the registers blocks
35 * that have been modified. 35 * that have been modified.
36 */ 36 */
37 37
38#ifdef __lint__ 38#ifdef __lint__
39/* Lint has different packing rules and doesn't understand __aligned() */ 39/* Lint has different packing rules and doesn't understand __aligned() */
40#define __CTASSERT_NOLINT(x) __CTASSERT(1) 40#define __CTASSERT_NOLINT(x) __CTASSERT(1)
41#else 41#else
42#define __CTASSERT_NOLINT(x) __CTASSERT(x) 42#define __CTASSERT_NOLINT(x) __CTASSERT(x)
43#endif 43#endif
44 44
45/* 45/*
46 * Layout for code/data pointers relating to FP exceptions. 46 * Layout for code/data pointers relating to FP exceptions.
47 * Marked 'packed' because they aren't always 64bit aligned. 47 * Marked 'packed' because they aren't always 64bit aligned.
48 * Since the x86 cpu supports misaligned accesses it isn't 48 * Since the x86 cpu supports misaligned accesses it isn't
49 * worth avoiding the 'packed' attribute. 49 * worth avoiding the 'packed' attribute.
50 */ 50 */
51union fp_addr { 51union fp_addr {
52 uint64_t fa_64; /* Linear address for 64bit systems */ 52 uint64_t fa_64; /* Linear address for 64bit systems */
53 struct { 53 struct {
54 uint32_t fa_off; /* linear address for 32 bit */ 54 uint32_t fa_off; /* linear address for 32 bit */
55 uint16_t fa_seg; /* code/data (etc) segment */ 55 uint16_t fa_seg; /* code/data (etc) segment */
56 uint16_t fa_opcode; /* last opcode (sometimes) */ 56 uint16_t fa_opcode; /* last opcode (sometimes) */
57 } fa_32; 57 } fa_32;
58} __packed __aligned(4); 58} __packed __aligned(4);
59 59
60/* The x87 registers are 80 bits */ 60/* The x87 registers are 80 bits */
61struct fpacc87 { 61struct fpacc87 {
62 uint64_t f87_mantissa; /* mantissa */ 62 uint64_t f87_mantissa; /* mantissa */
63 uint16_t f87_exp_sign; /* exponent and sign */ 63 uint16_t f87_exp_sign; /* exponent and sign */
64} __packed __aligned(2); 64} __packed __aligned(2);
65 65
66/* The x87 registers padded out to 16 bytes for fxsave */ 66/* The x87 registers padded out to 16 bytes for fxsave */
67struct fpaccfx { 67struct fpaccfx {
68 struct fpacc87 r __aligned(16); 68 struct fpacc87 r __aligned(16);
69}; 69};
70 70
71/* The SSE/SSE2 registers are 128 bits */ 71/* The SSE/SSE2 registers are 128 bits */
72struct xmmreg { 72struct xmmreg {
73 uint8_t xmm_bytes[16]; 73 uint8_t xmm_bytes[16];
74}; 74};
75 75
76/* The AVX registers are 256 bits, but the low bits are the xmmregs */ 76/* The AVX registers are 256 bits, but the low bits are the xmmregs */
77struct ymmreg { 77struct ymmreg {
78 uint8_t ymm_bytes[16]; 78 uint8_t ymm_bytes[16];
79}; 79};
80 80
81/* 81/*
82 * Floating point unit registers (fsave instruction). 82 * Floating point unit registers (fsave instruction).
83 * The s87_ac[] and fx_87_ac[] are relative to the stack top. 83 * The s87_ac[] and fx_87_ac[] are relative to the stack top.
84 * The 'tag word' contains 2 bits per register and refers to 84 * The 'tag word' contains 2 bits per register and refers to
85 * absolute register numbers. 85 * absolute register numbers.
86 * The cpu sets the tag values 0b01 (zero) and 0b10 (special) when a value 86 * The cpu sets the tag values 0b01 (zero) and 0b10 (special) when a value
87 * is loaded. The software need only set 0b00 (used) and 0xb11 (unused). 87 * is loaded. The software need only set 0b00 (used) and 0xb11 (unused).
88 * The fxsave 'Abridged tag word' in inverted. 88 * The fxsave 'Abridged tag word' in inverted.
89 */ 89 */
90struct save87 { 90struct save87 {
91 uint16_t s87_cw __aligned(4); /* control word (16bits) */ 91 uint16_t s87_cw __aligned(4); /* control word (16bits) */
92 uint16_t s87_sw __aligned(4); /* status word (16bits) */ 92 uint16_t s87_sw __aligned(4); /* status word (16bits) */
93 uint16_t s87_tw __aligned(4); /* tag word (16bits) */ 93 uint16_t s87_tw __aligned(4); /* tag word (16bits) */
94 union fp_addr s87_ip; /* floating point instruction pointer */ 94 union fp_addr s87_ip; /* floating point instruction pointer */
95#define s87_opcode s87_ip.fa_32.fa_opcode /* opcode last executed (11bits) */ 95#define s87_opcode s87_ip.fa_32.fa_opcode /* opcode last executed (11bits) */
96 union fp_addr s87_dp; /* floating operand offset */ 96 union fp_addr s87_dp; /* floating operand offset */
97 struct fpacc87 s87_ac[8]; /* accumulator contents, 0-7 */ 97 struct fpacc87 s87_ac[8]; /* accumulator contents, 0-7 */
98}; 98};
99__CTASSERT_NOLINT(sizeof (struct save87) == 108); 99__CTASSERT_NOLINT(sizeof (struct save87) == 108);
100 100
101/* FPU/MMX/SSE/SSE2 context */ 101/* FPU/MMX/SSE/SSE2 context */
102struct fxsave { 102struct fxsave {
103/*0*/ uint16_t fx_cw; /* FPU Control Word */ 103/*0*/ uint16_t fx_cw; /* FPU Control Word */
104 uint16_t fx_sw; /* FPU Status Word */ 104 uint16_t fx_sw; /* FPU Status Word */
105 uint8_t fx_tw; /* FPU Tag Word (abridged) */ 105 uint8_t fx_tw; /* FPU Tag Word (abridged) */
106 uint16_t fx_opcode; /* FPU Opcode */ 106 uint16_t fx_opcode; /* FPU Opcode */
107 union fp_addr fx_ip; /* FPU Instruction Pointer */ 107 union fp_addr fx_ip; /* FPU Instruction Pointer */
108/*16*/ union fp_addr fx_dp; /* FPU Data pointer */ 108/*16*/ union fp_addr fx_dp; /* FPU Data pointer */
109 uint32_t fx_mxcsr; /* MXCSR Register State */ 109 uint32_t fx_mxcsr; /* MXCSR Register State */
110 uint32_t fx_mxcsr_mask; 110 uint32_t fx_mxcsr_mask;
111 struct fpaccfx fx_87_ac[8]; /* 8 x87 registers */ 111 struct fpaccfx fx_87_ac[8]; /* 8 x87 registers */
112 struct xmmreg fx_xmm[16]; /* XMM regs (8 in 32bit modes) */ 112 struct xmmreg fx_xmm[16]; /* XMM regs (8 in 32bit modes) */
113 uint8_t fx_rsvd[48]; 113 uint8_t fx_rsvd[48];
114 uint8_t fx_kernel[48]; /* Not written by the hardware */ 114 uint8_t fx_kernel[48]; /* Not written by the hardware */
115} __aligned(16); 115} __aligned(16);
116__CTASSERT_NOLINT(sizeof (struct fxsave) == 512); 116__CTASSERT_NOLINT(sizeof (struct fxsave) == 512);
117 117
118#ifndef _KERNEL 
119/* Backwards compatibility for firefox (looks at fx_xmm) */ 
120#define fxsave64 fxsave 
121#endif 
122 
123/* The end of the fsave buffer can be used by the operating system */ 118/* The end of the fsave buffer can be used by the operating system */
124struct fxsave_os { 119struct fxsave_os {
125 uint8_t fxo_fxsave[512 - 48]; 120 uint8_t fxo_fxsave[512 - 48];
126 /* 48 bytes available, NB copied to/from userspace */ 121 /* 48 bytes available, NB copied to/from userspace */
127 uint16_t fxo_dflt_cw; /* Control word for signal handlers */ 122 uint16_t fxo_dflt_cw; /* Control word for signal handlers */
128}; 123};
129 124
130union savefpu { 125union savefpu {
131 struct save87 sv_87; 126 struct save87 sv_87;
132 struct fxsave sv_xmm; 127 struct fxsave sv_xmm;
133 struct fxsave_os sv_os; 128 struct fxsave_os sv_os;
134}; 129};
135 130
136/* 131/*
137 * For XSAVE a 64byte header follows the above. 132 * For XSAVE a 64byte header follows the above.
138 * Currently it only contains one field of which only 3 bits are defined. 133 * Currently it only contains one field of which only 3 bits are defined.
139 * Some other parts must be zero - zero it all. 134 * Some other parts must be zero - zero it all.
140 * 135 *
141 * The xsh_xstate_bv bits match those of XCR0: 136 * The xsh_xstate_bv bits match those of XCR0:
142 * XCR0_X87 0x00000001 x87 FPU/MMX state (always set) 137 * XCR0_X87 0x00000001 x87 FPU/MMX state (always set)
143 * XCR0_SSE 0x00000002 SSE state 138 * XCR0_SSE 0x00000002 SSE state
144 * XCR0_AVX 0x00000004 AVX state (ymmn registers) 139 * XCR0_AVX 0x00000004 AVX state (ymmn registers)
145 * 140 *
146 * The offsets and sizes of any save areas can be found by reading 141 * The offsets and sizes of any save areas can be found by reading
147 * the correct control registers. 142 * the correct control registers.
148 */ 143 */
149 144
150struct xsave_header { 145struct xsave_header {
151 uint64_t xsh_xstate_bv; /* bitmap of saved sub structures */ 146 uint64_t xsh_xstate_bv; /* bitmap of saved sub structures */
152 uint64_t xsh_rsrvd[2]; /* must be zero */ 147 uint64_t xsh_rsrvd[2]; /* must be zero */
153 uint64_t xsh_reserved[5];/* best if zero */ 148 uint64_t xsh_reserved[5];/* best if zero */
154}; 149};
155__CTASSERT(sizeof (struct xsave_header) == 64); 150__CTASSERT(sizeof (struct xsave_header) == 64);
156 151
157/* 152/*
158 * The ymm save area actually follows the xsave_header. 153 * The ymm save area actually follows the xsave_header.
159 */ 154 */
160struct xsave_ymm { 155struct xsave_ymm {
161 struct ymmreg xs_ymm[16]; /* High bits of YMM registers */ 156 struct ymmreg xs_ymm[16]; /* High bits of YMM registers */
162}; 157};
163__CTASSERT(sizeof (struct xsave_ymm) == 256); 158__CTASSERT(sizeof (struct xsave_ymm) == 256);
164 159
165 160
166/* 161/*
167 * 80387 control and status word bits 162 * 80387 control and status word bits
168 * 163 *
169 * The only reference I can find to bits 0x40 and 0x80 in the control word 164 * The only reference I can find to bits 0x40 and 0x80 in the control word
170 * is for the Weitek 1167/3167. 165 * is for the Weitek 1167/3167.
171 * I (dsl) can't find why the default word has 0x40 set. 166 * I (dsl) can't find why the default word has 0x40 set.
172 * 167 *
173 * A stack error is signalled as an INVOP that also sets STACK_FAULT 168 * A stack error is signalled as an INVOP that also sets STACK_FAULT
174 * (other INVOP do not clear STACK_FAULT). 169 * (other INVOP do not clear STACK_FAULT).
175 */ 170 */
176/* Interrupt masks (set masks interrupt) and status bits */ 171/* Interrupt masks (set masks interrupt) and status bits */
177#define EN_SW_INVOP 0x0001 /* Invalid operation */ 172#define EN_SW_INVOP 0x0001 /* Invalid operation */
178#define EN_SW_DENORM 0x0002 /* Denormalized operand */ 173#define EN_SW_DENORM 0x0002 /* Denormalized operand */
179#define EN_SW_ZERODIV 0x0004 /* Divide by zero */ 174#define EN_SW_ZERODIV 0x0004 /* Divide by zero */
180#define EN_SW_OVERFLOW 0x0008 /* Overflow */ 175#define EN_SW_OVERFLOW 0x0008 /* Overflow */
181#define EN_SW_UNDERFLOW 0x0010 /* Underflow */ 176#define EN_SW_UNDERFLOW 0x0010 /* Underflow */
182#define EN_SW_PRECLOSS 0x0020 /* Loss of precision */ 177#define EN_SW_PRECLOSS 0x0020 /* Loss of precision */
183/* Status word bits (reserved in control word) */ 178/* Status word bits (reserved in control word) */
184#define EN_SW_STACK_FAULT 0x0040 /* Stack under/overflow */ 179#define EN_SW_STACK_FAULT 0x0040 /* Stack under/overflow */
185#define EN_SW_ERROR_SUMMARY 0x0080 /* Unmasked error has ocurred */ 180#define EN_SW_ERROR_SUMMARY 0x0080 /* Unmasked error has ocurred */
186/* Control bits (badly named) */ 181/* Control bits (badly named) */
187#define EN_SW_CTL_PREC 0x0300 /* Precision control */ 182#define EN_SW_CTL_PREC 0x0300 /* Precision control */
188#define EN_SW_PREC_24 0x0000 /* Single precision */ 183#define EN_SW_PREC_24 0x0000 /* Single precision */
189#define EN_SW_PREC_53 0x0200 /* Double precision */ 184#define EN_SW_PREC_53 0x0200 /* Double precision */
190#define EN_SW_PREC_64 0x0300 /* Extended precision */ 185#define EN_SW_PREC_64 0x0300 /* Extended precision */
191#define EN_SW_CTL_ROUND 0x0c00 /* Rounding control */ 186#define EN_SW_CTL_ROUND 0x0c00 /* Rounding control */
192#define EN_SW_ROUND_EVEN 0x0000 /* Round to nearest even */ 187#define EN_SW_ROUND_EVEN 0x0000 /* Round to nearest even */
193#define EN_SW_ROUND_DOWN 0x0400 /* Round towards minus infinity */ 188#define EN_SW_ROUND_DOWN 0x0400 /* Round towards minus infinity */
194#define EN_SW_ROUND_UP 0x0800 /* Round towards plus infinity */ 189#define EN_SW_ROUND_UP 0x0800 /* Round towards plus infinity */
195#define EN_SW_ROUND_ZERO 0x0c00 /* Round towards zero (truncates) */ 190#define EN_SW_ROUND_ZERO 0x0c00 /* Round towards zero (truncates) */
196#define EN_SW_CTL_INF 0x1000 /* Infinity control, not used */ 191#define EN_SW_CTL_INF 0x1000 /* Infinity control, not used */
197 192
198/* 193/*
199 * The standard 0x87 control word from finit is 0x37F, giving: 194 * The standard 0x87 control word from finit is 0x37F, giving:
200 * round to nearest 195 * round to nearest
201 * 64-bit precision 196 * 64-bit precision
202 * all exceptions masked. 197 * all exceptions masked.
203 * 198 *
204 * NetBSD used to select: 199 * NetBSD used to select:
205 * round to nearest 200 * round to nearest
206 * 53-bit precision 201 * 53-bit precision
207 * all exceptions masked. 202 * all exceptions masked.
208 * Stating: 64-bit precision often gives bad results with high level 203 * Stating: 64-bit precision often gives bad results with high level
209 * languages because it makes the results of calculations depend on whether 204 * languages because it makes the results of calculations depend on whether
210 * intermediate values are stored in memory or in FPU registers. 205 * intermediate values are stored in memory or in FPU registers.
211 * Also some 'pathological divisions' give an error in the LSB because 206 * Also some 'pathological divisions' give an error in the LSB because
212 * the value is first rounded up when the 64bit mantissa is generated, 207 * the value is first rounded up when the 64bit mantissa is generated,
213 * and then again when it is truncated to 53 bits. 208 * and then again when it is truncated to 53 bits.
214 * 209 *
215 * However the C language explicitly allows the extra precision. 210 * However the C language explicitly allows the extra precision.
216 * 211 *
217 * The iBCS control word has underflow, overflow, zero divide, and invalid 212 * The iBCS control word has underflow, overflow, zero divide, and invalid
218 * operation exceptions unmasked. But that causes an unexpected exception 213 * operation exceptions unmasked. But that causes an unexpected exception
219 * in the test program 'paranoia' and makes denormals useless (DBL_MIN / 2 214 * in the test program 'paranoia' and makes denormals useless (DBL_MIN / 2
220 * underflows). It doesn't make a lot of sense to trap underflow without 215 * underflows). It doesn't make a lot of sense to trap underflow without
221 * trapping denormals. 216 * trapping denormals.
222 */ 217 */
223#define __INITIAL_NPXCW__ 0x037f 218#define __INITIAL_NPXCW__ 0x037f
224/* Modern NetBSD uses the default control word.. */ 219/* Modern NetBSD uses the default control word.. */
225#define __NetBSD_NPXCW__ __INITIAL_NPXCW__ 220#define __NetBSD_NPXCW__ __INITIAL_NPXCW__
226/* NetBSD before 6.99.26 forced IEEE double precision. */ 221/* NetBSD before 6.99.26 forced IEEE double precision. */
227#define __NetBSD_COMPAT_NPXCW__ 0x127f 222#define __NetBSD_COMPAT_NPXCW__ 0x127f
228/* FreeBSD leaves some exceptions unmasked as well. */ 223/* FreeBSD leaves some exceptions unmasked as well. */
229#define __FreeBSD_NPXCW__ 0x1272 224#define __FreeBSD_NPXCW__ 0x1272
230/* iBCS2 goes a bit further and leaves the underflow exception unmasked. */ 225/* iBCS2 goes a bit further and leaves the underflow exception unmasked. */
231#define __iBCS2_NPXCW__ 0x0262 226#define __iBCS2_NPXCW__ 0x0262
232/* Linux just uses the default control word. */ 227/* Linux just uses the default control word. */
233#define __Linux_NPXCW__ __INITIAL_NPXCW__ 228#define __Linux_NPXCW__ __INITIAL_NPXCW__
234/* SVR4 uses the same control word as iBCS2. */ 229/* SVR4 uses the same control word as iBCS2. */
235#define __SVR4_NPXCW__ 0x0262 230#define __SVR4_NPXCW__ 0x0262
236 231
237/* 232/*
238 * The default MXCSR value at reset is 0x1f80, IA-32 Instruction 233 * The default MXCSR value at reset is 0x1f80, IA-32 Instruction
239 * Set Reference, pg. 3-369. 234 * Set Reference, pg. 3-369.
240 * 235 *
241 * The low 6 bits of the mxcsr are the fp status bits (same order as x87). 236 * The low 6 bits of the mxcsr are the fp status bits (same order as x87).
242 * Bit 6 is 'denormals are zero' (speeds up calculations). 237 * Bit 6 is 'denormals are zero' (speeds up calculations).
243 * Bits 7-16 are the interrupt mask bits (same order, 1 to mask). 238 * Bits 7-16 are the interrupt mask bits (same order, 1 to mask).
244 * Bits 13 and 14 are rounding control. 239 * Bits 13 and 14 are rounding control.
245 * Bit 15 is 'flush to zero' - affects underflow. 240 * Bit 15 is 'flush to zero' - affects underflow.
246 * Bits 16-31 must be zero. 241 * Bits 16-31 must be zero.
247 */ 242 */
248#define __INITIAL_MXCSR__ 0x1f80 243#define __INITIAL_MXCSR__ 0x1f80
249#define __INITIAL_MXCSR_MASK__ 0xffbf 244#define __INITIAL_MXCSR_MASK__ 0xffbf
250 245
251#endif /* _X86_CPU_EXTENDED_STATE_H_ */ 246#endif /* _X86_CPU_EXTENDED_STATE_H_ */