1b2b3ffcdSSimon Schubert /*- 2b2b3ffcdSSimon Schubert * Copyright (c) 1990 The Regents of the University of California. 3b2b3ffcdSSimon Schubert * Copyright (c) 2008 The DragonFly Project. 4b2b3ffcdSSimon Schubert * All rights reserved. 5b2b3ffcdSSimon Schubert * 6b2b3ffcdSSimon Schubert * This code is derived from software contributed to Berkeley by 7b2b3ffcdSSimon Schubert * William Jolitz. 8b2b3ffcdSSimon Schubert * 9b2b3ffcdSSimon Schubert * Redistribution and use in source and binary forms, with or without 10b2b3ffcdSSimon Schubert * modification, are permitted provided that the following conditions 11b2b3ffcdSSimon Schubert * are met: 12b2b3ffcdSSimon Schubert * 1. Redistributions of source code must retain the above copyright 13b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer. 14b2b3ffcdSSimon Schubert * 2. Redistributions in binary form must reproduce the above copyright 15b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer in the 16b2b3ffcdSSimon Schubert * documentation and/or other materials provided with the distribution. 172c64e990Szrj * 3. Neither the name of the University nor the names of its contributors 18b2b3ffcdSSimon Schubert * may be used to endorse or promote products derived from this software 19b2b3ffcdSSimon Schubert * without specific prior written permission. 20b2b3ffcdSSimon Schubert * 21b2b3ffcdSSimon Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22b2b3ffcdSSimon Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b2b3ffcdSSimon Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b2b3ffcdSSimon Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25b2b3ffcdSSimon Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b2b3ffcdSSimon Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b2b3ffcdSSimon Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b2b3ffcdSSimon Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b2b3ffcdSSimon Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b2b3ffcdSSimon Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b2b3ffcdSSimon Schubert * SUCH DAMAGE. 32b2b3ffcdSSimon Schubert * 33b2b3ffcdSSimon Schubert * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 34b2b3ffcdSSimon Schubert * $FreeBSD: src/sys/i386/include/npx.h,v 1.18.2.1 2001/08/15 01:23:52 peter Exp $ 35b2b3ffcdSSimon Schubert */ 36b2b3ffcdSSimon Schubert 37b2b3ffcdSSimon Schubert /* 38b2b3ffcdSSimon Schubert * 287/387 NPX Coprocessor Data Structures and Constants 39b2b3ffcdSSimon Schubert * W. Jolitz 1/90 40b2b3ffcdSSimon Schubert */ 41b2b3ffcdSSimon Schubert 42b2b3ffcdSSimon Schubert #ifndef _CPU_NPX_H_ 43b2b3ffcdSSimon Schubert #define _CPU_NPX_H_ 44b2b3ffcdSSimon Schubert 45eaf07fa9Szrj #ifndef _SYS_STDINT_H_ 46eaf07fa9Szrj #include <sys/stdint.h> 47eaf07fa9Szrj #endif 48b2b3ffcdSSimon Schubert 49b2b3ffcdSSimon Schubert /* Environment information of floating point unit */ 50b2b3ffcdSSimon Schubert struct env87 { 519e6e869eSMatthew Dillon int32_t en_cw; /* control word (16bits) */ 529e6e869eSMatthew Dillon int32_t en_sw; /* status word (16bits) */ 539e6e869eSMatthew Dillon int32_t en_tw; /* tag word (16bits) */ 549e6e869eSMatthew Dillon int32_t en_fip; /* floating point instruction pointer */ 5570ca95baSJohn Marino uint16_t en_fcs; /* floating code segment selector */ 5670ca95baSJohn Marino uint16_t en_opcode; /* opcode last executed (11 bits ) */ 579e6e869eSMatthew Dillon int32_t en_foo; /* floating operand offset */ 589e6e869eSMatthew Dillon int32_t en_fos; /* floating operand segment selector */ 59b2b3ffcdSSimon Schubert }; 60b2b3ffcdSSimon Schubert 6170ca95baSJohn Marino /* Contents of each x87 floating point accumulator */ 62b2b3ffcdSSimon Schubert struct fpacc87 { 6370ca95baSJohn Marino uint8_t fp_bytes[10]; 64b2b3ffcdSSimon Schubert }; 65b2b3ffcdSSimon Schubert 6670ca95baSJohn Marino /* Floating point context (i386 fnsave/frstor) */ 67b2b3ffcdSSimon Schubert struct save87 { 68b2b3ffcdSSimon Schubert struct env87 sv_env; /* floating point control/status */ 69b2b3ffcdSSimon Schubert struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ 7070ca95baSJohn Marino uint8_t sv_pad0[4]; /* saved status word (now unused) */ 71b2b3ffcdSSimon Schubert /* 72b2b3ffcdSSimon Schubert * Bogus padding for emulators. Emulators should use their own 73b2b3ffcdSSimon Schubert * struct and arrange to store into this struct (ending here) 74b2b3ffcdSSimon Schubert * before it is inspected for ptracing or for core dumps. Some 75b2b3ffcdSSimon Schubert * emulators overwrite the whole struct. We have no good way of 76b2b3ffcdSSimon Schubert * knowing how much padding to leave. Leave just enough for the 77b2b3ffcdSSimon Schubert * GPL emulator's i387_union (176 bytes total). 78b2b3ffcdSSimon Schubert */ 7970ca95baSJohn Marino uint8_t sv_pad[64]; 80b2b3ffcdSSimon Schubert }; 81b2b3ffcdSSimon Schubert 82b2b3ffcdSSimon Schubert struct envxmm { 8370ca95baSJohn Marino uint16_t en_cw; /* control word (16bits) */ 8470ca95baSJohn Marino uint16_t en_sw; /* status word (16bits) */ 8570ca95baSJohn Marino uint16_t en_tw; /* tag word (16bits) */ 8670ca95baSJohn Marino uint16_t en_opcode; /* opcode last executed (11 bits) */ 8770ca95baSJohn Marino uint32_t en_fip; /* fp instruction pointer */ 8870ca95baSJohn Marino uint16_t en_fcs; /* fp code segment selector */ 8970ca95baSJohn Marino uint16_t en_pad0; /* padding */ 9070ca95baSJohn Marino uint32_t en_foo; /* fp operand offset */ 9170ca95baSJohn Marino uint16_t en_fos; /* fp operand segment selector */ 9270ca95baSJohn Marino uint16_t en_pad1; /* padding */ 9370ca95baSJohn Marino uint32_t en_mxcsr; /* SSE control/status register */ 9470ca95baSJohn Marino uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 9570ca95baSJohn Marino }; 9670ca95baSJohn Marino 97357acec7SAaron LI /* Layout for code/data pointers relating to FP exceptions. */ 98357acec7SAaron LI union fp_addr { 99357acec7SAaron LI uint64_t fa_64; /* linear address for 64-bit system */ 100357acec7SAaron LI struct { 101357acec7SAaron LI uint32_t fa_off; /* linear address for 32-bit system */ 102357acec7SAaron LI uint16_t fa_seg; /* code/data (etc) segment */ 103357acec7SAaron LI uint16_t fa_opcode; /* last opcode (sometimes) */ 104357acec7SAaron LI } fa_32; 105357acec7SAaron LI }; 106357acec7SAaron LI 10770ca95baSJohn Marino struct envxmm64 { 10870ca95baSJohn Marino uint16_t en_cw; /* control word (16bits) */ 10970ca95baSJohn Marino uint16_t en_sw; /* status word (16bits) */ 11070ca95baSJohn Marino uint8_t en_tw; /* tag word (8bits) */ 11170ca95baSJohn Marino uint8_t en_zero; 11270ca95baSJohn Marino uint16_t en_opcode; /* opcode last executed (11 bits ) */ 113357acec7SAaron LI union { /* fp instruction pointer */ 114357acec7SAaron LI uint64_t en_rip; 115357acec7SAaron LI union fp_addr en_ip64; 116357acec7SAaron LI }; 117357acec7SAaron LI union { /* fp operand pointer */ 118357acec7SAaron LI uint64_t en_rdp; 119357acec7SAaron LI union fp_addr en_dp64; 120357acec7SAaron LI }; 12170ca95baSJohn Marino uint32_t en_mxcsr; /* SSE control/status register */ 12270ca95baSJohn Marino uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 123b2b3ffcdSSimon Schubert }; 124b2b3ffcdSSimon Schubert 125b2b3ffcdSSimon Schubert /* Contents of each SSE extended accumulator */ 126b2b3ffcdSSimon Schubert struct xmmacc { 12770ca95baSJohn Marino uint8_t xmm_bytes[16]; 12870ca95baSJohn Marino }; 12970ca95baSJohn Marino 13070ca95baSJohn Marino /* Contents of the upper 16 bytes of each AVX extended accumulator */ 13170ca95baSJohn Marino struct ymmacc { 13270ca95baSJohn Marino uint8_t ymm_bytes[16]; 133b2b3ffcdSSimon Schubert }; 134b2b3ffcdSSimon Schubert 135b2b3ffcdSSimon Schubert /* 13670ca95baSJohn Marino * Floating point context. (i386 fxsave/fxrstor) 137b2b3ffcdSSimon Schubert * savexmm is a 512-byte structure 138b2b3ffcdSSimon Schubert */ 139b2b3ffcdSSimon Schubert struct savexmm { 140b2b3ffcdSSimon Schubert struct envxmm sv_env; /* 32 */ 141b2b3ffcdSSimon Schubert struct { 1422ad04be3SAaron LI struct fpacc87 fp_acc; 1432ad04be3SAaron LI uint8_t fp_pad[6]; 14470ca95baSJohn Marino } sv_fp[8]; /* 128 */ 145b2b3ffcdSSimon Schubert struct xmmacc sv_xmm[8]; /* 128 */ 1462ad04be3SAaron LI uint8_t sv_pad[224]; /* 224 */ 1471530d07cSSascha Wildner } __aligned(16); 148b2b3ffcdSSimon Schubert 14970ca95baSJohn Marino /* 15070ca95baSJohn Marino * Floating point context. (amd64 fxsave/fxrstor) 15170ca95baSJohn Marino * savexmm64 is a 512-byte structure 15270ca95baSJohn Marino */ 15370ca95baSJohn Marino struct savexmm64 { 15470ca95baSJohn Marino struct envxmm64 sv_env; /* 32 */ 15570ca95baSJohn Marino struct { 15670ca95baSJohn Marino struct fpacc87 fp_acc; 15770ca95baSJohn Marino uint8_t fp_pad[6]; 15870ca95baSJohn Marino } sv_fp[8]; /* 128 */ 1592ad04be3SAaron LI struct xmmacc sv_xmm[16]; /* 256 */ 1602ad04be3SAaron LI uint8_t sv_pad[96]; /* 96 */ 1611530d07cSSascha Wildner } __aligned(16); 16270ca95baSJohn Marino 16370ca95baSJohn Marino /* xstate_hdr is a 64-byte structure */ 16470ca95baSJohn Marino struct xstate_hdr { 16570ca95baSJohn Marino uint64_t xstate_bv; 16670ca95baSJohn Marino uint64_t xstate_xcomp_bv; 16770ca95baSJohn Marino uint8_t xstate_rsrv0[8]; 16870ca95baSJohn Marino uint8_t xstate_rsrv[40]; 16970ca95baSJohn Marino }; 17070ca95baSJohn Marino #define XSTATE_XCOMP_BV_COMPACT (1ULL << 63) 17170ca95baSJohn Marino 17270ca95baSJohn Marino /* savexmm_xstate is a 320-byte structure (64 + 256) */ 17370ca95baSJohn Marino struct savexmm_xstate { 17470ca95baSJohn Marino struct xstate_hdr sx_hd; 17570ca95baSJohn Marino struct ymmacc sx_ymm[16]; 17670ca95baSJohn Marino }; 17770ca95baSJohn Marino 17870ca95baSJohn Marino /* saveymm is a 832-byte structure (i386) */ 1795cf56a8dSAlex Hornung struct saveymm { 18070ca95baSJohn Marino struct envxmm sv_env; /* 32 */ 18170ca95baSJohn Marino struct { 18270ca95baSJohn Marino struct fpacc87 fp_acc; 18370ca95baSJohn Marino uint8_t fp_pad[6]; 18470ca95baSJohn Marino } sv_fp[8]; /* 128 */ 18570ca95baSJohn Marino struct xmmacc sv_xmm[16]; /* 256 */ 18670ca95baSJohn Marino uint8_t sv_pad[96]; /* 96 */ 18770ca95baSJohn Marino struct savexmm_xstate sv_xstate; /* 320 */ 1881530d07cSSascha Wildner } __aligned(64); 18970ca95baSJohn Marino 19070ca95baSJohn Marino /* saveymm64 is a 832-byte structure (amd64) */ 19170ca95baSJohn Marino struct saveymm64 { 19270ca95baSJohn Marino struct envxmm64 sv_env; /* 32 */ 19370ca95baSJohn Marino struct { 19470ca95baSJohn Marino struct fpacc87 fp_acc; 19570ca95baSJohn Marino int8_t fp_pad[6]; 19670ca95baSJohn Marino } sv_fp[8]; /* 128 */ 19770ca95baSJohn Marino struct xmmacc sv_xmm[16]; /* 256 */ 19870ca95baSJohn Marino uint8_t sv_pad[96]; /* 96 */ 19970ca95baSJohn Marino struct savexmm_xstate sv_xstate; /* 320 */ 2001530d07cSSascha Wildner } __aligned(64); 2015cf56a8dSAlex Hornung 202b2b3ffcdSSimon Schubert union savefpu { 203b2b3ffcdSSimon Schubert struct save87 sv_87; 204b2b3ffcdSSimon Schubert struct savexmm sv_xmm; 2055cf56a8dSAlex Hornung struct saveymm sv_ymm; 20670ca95baSJohn Marino struct savexmm64 sv_xmm64; 20770ca95baSJohn Marino struct saveymm64 sv_ymm64; 208c7e46c4aSMatthew Dillon char sv_savearea[1024]; /* see mcontext_t */ 209b2b3ffcdSSimon Schubert }; 210b2b3ffcdSSimon Schubert 211b2b3ffcdSSimon Schubert /* 212b2b3ffcdSSimon Schubert * The hardware default control word for i387's and later coprocessors is 213b2b3ffcdSSimon Schubert * 0x37F, giving: 214b2b3ffcdSSimon Schubert * 215b2b3ffcdSSimon Schubert * round to nearest 216b2b3ffcdSSimon Schubert * 64-bit precision 217b2b3ffcdSSimon Schubert * all exceptions masked. 218b2b3ffcdSSimon Schubert * 219b2b3ffcdSSimon Schubert * We modify the affine mode bit and precision bits in this to give: 220b2b3ffcdSSimon Schubert * 221b2b3ffcdSSimon Schubert * affine mode for 287's (if they work at all) (1 in bitfield 1<<12) 222b2b3ffcdSSimon Schubert * 53-bit precision (2 in bitfield 3<<8) 223b2b3ffcdSSimon Schubert * 224b2b3ffcdSSimon Schubert * 64-bit precision often gives bad results with high level languages 225b2b3ffcdSSimon Schubert * because it makes the results of calculations depend on whether 226b2b3ffcdSSimon Schubert * intermediate values are stored in memory or in FPU registers. 227b2b3ffcdSSimon Schubert */ 228b2b3ffcdSSimon Schubert #define __INITIAL_NPXCW__ 0x127F 229b2b3ffcdSSimon Schubert 230b2b3ffcdSSimon Schubert #define __INITIAL_FPUCW__ 0x037F /* used by libm/arch/x86_64/fenv.c */ 231b2b3ffcdSSimon Schubert #define __INITIAL_FPUCW_I386__ 0x127F 232b2b3ffcdSSimon Schubert #define __INITIAL_MXCSR__ 0x1F80 /* used by libm/arch/x86_64/fenv.c */ 233b2b3ffcdSSimon Schubert #define __INITIAL_MXCSR_MASK__ 0xFFBF 234b2b3ffcdSSimon Schubert 235b2b3ffcdSSimon Schubert #ifdef _KERNEL 236b2b3ffcdSSimon Schubert 237b2b3ffcdSSimon Schubert struct proc; 238b2b3ffcdSSimon Schubert struct trapframe; 239b2b3ffcdSSimon Schubert 240186c803fSMarkus Pfeiffer extern uint32_t npx_mxcsr_mask; 2417c656f7bSMatthew Dillon extern uint64_t npx_xcr0_mask; 242186c803fSMarkus Pfeiffer 243186c803fSMarkus Pfeiffer void npxprobemask (void); 244b2b3ffcdSSimon Schubert void npxexit (void); 245186c803fSMarkus Pfeiffer void npxinit (void); 246b2b3ffcdSSimon Schubert void npxsave (union savefpu *addr); 247*3fe3fa25SAaron LI void fpusave (union savefpu *addr, uint64_t mask); 248*3fe3fa25SAaron LI void fpurstor (union savefpu *addr, uint64_t mask); 249b2b3ffcdSSimon Schubert #endif 250b2b3ffcdSSimon Schubert 251b2b3ffcdSSimon Schubert #endif /* !_CPU_NPX_H_ */ 252