fpu.h revision 279211
1233044Stijl/*- 2233044Stijl * Copyright (c) 1990 The Regents of the University of California. 3233044Stijl * All rights reserved. 4233044Stijl * 5233044Stijl * This code is derived from software contributed to Berkeley by 6233044Stijl * William Jolitz. 7233044Stijl * 8233044Stijl * Redistribution and use in source and binary forms, with or without 9233044Stijl * modification, are permitted provided that the following conditions 10233044Stijl * are met: 11233044Stijl * 1. Redistributions of source code must retain the above copyright 12233044Stijl * notice, this list of conditions and the following disclaimer. 13233044Stijl * 2. Redistributions in binary form must reproduce the above copyright 14233044Stijl * notice, this list of conditions and the following disclaimer in the 15233044Stijl * documentation and/or other materials provided with the distribution. 16233044Stijl * 4. Neither the name of the University nor the names of its contributors 17233044Stijl * may be used to endorse or promote products derived from this software 18233044Stijl * without specific prior written permission. 19233044Stijl * 20233044Stijl * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21233044Stijl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22233044Stijl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23233044Stijl * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24233044Stijl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25233044Stijl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26233044Stijl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27233044Stijl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28233044Stijl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29233044Stijl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30233044Stijl * SUCH DAMAGE. 31233044Stijl * 32233044Stijl * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 33233044Stijl * $FreeBSD: stable/10/sys/x86/include/fpu.h 279211 2015-02-23 18:38:41Z jhb $ 34233044Stijl */ 35233044Stijl 36233044Stijl/* 37233044Stijl * Floating Point Data Structures and Constants 38233044Stijl * W. Jolitz 1/90 39233044Stijl */ 40233044Stijl 41233044Stijl#ifndef _X86_FPU_H_ 42233044Stijl#define _X86_FPU_H_ 43233044Stijl 44233044Stijl/* Environment information of floating point unit. */ 45233044Stijlstruct env87 { 46233044Stijl int32_t en_cw; /* control word (16bits) */ 47233044Stijl int32_t en_sw; /* status word (16bits) */ 48233044Stijl int32_t en_tw; /* tag word (16bits) */ 49233044Stijl int32_t en_fip; /* fp instruction pointer */ 50233044Stijl uint16_t en_fcs; /* fp code segment selector */ 51233044Stijl uint16_t en_opcode; /* opcode last executed (11 bits) */ 52233044Stijl int32_t en_foo; /* fp operand offset */ 53233044Stijl int32_t en_fos; /* fp operand segment selector */ 54233044Stijl}; 55233044Stijl 56233044Stijl/* Contents of each x87 floating point accumulator. */ 57233044Stijlstruct fpacc87 { 58233044Stijl uint8_t fp_bytes[10]; 59233044Stijl}; 60233044Stijl 61233044Stijl/* Floating point context. (i386 fnsave/frstor) */ 62233044Stijlstruct save87 { 63233044Stijl struct env87 sv_env; /* floating point control/status */ 64233044Stijl struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ 65233044Stijl uint8_t sv_pad0[4]; /* saved status word (now unused) */ 66279211Sjhb uint8_t sv_pad[64]; 67233044Stijl}; 68233044Stijl 69233044Stijl/* Contents of each SSE extended accumulator. */ 70233044Stijlstruct xmmacc { 71233044Stijl uint8_t xmm_bytes[16]; 72233044Stijl}; 73233044Stijl 74233044Stijl/* Contents of the upper 16 bytes of each AVX extended accumulator. */ 75233044Stijlstruct ymmacc { 76233044Stijl uint8_t ymm_bytes[16]; 77233044Stijl}; 78233044Stijl 79233044Stijl/* Rename structs below depending on machine architecture. */ 80233044Stijl#ifdef __i386__ 81233044Stijl#define __envxmm32 envxmm 82233044Stijl#else 83233044Stijl#define __envxmm32 envxmm32 84233044Stijl#define __envxmm64 envxmm 85233044Stijl#endif 86233044Stijl 87233044Stijlstruct __envxmm32 { 88233044Stijl uint16_t en_cw; /* control word (16bits) */ 89233044Stijl uint16_t en_sw; /* status word (16bits) */ 90233044Stijl uint16_t en_tw; /* tag word (16bits) */ 91233044Stijl uint16_t en_opcode; /* opcode last executed (11 bits) */ 92233044Stijl uint32_t en_fip; /* fp instruction pointer */ 93233044Stijl uint16_t en_fcs; /* fp code segment selector */ 94233044Stijl uint16_t en_pad0; /* padding */ 95233044Stijl uint32_t en_foo; /* fp operand offset */ 96233044Stijl uint16_t en_fos; /* fp operand segment selector */ 97233044Stijl uint16_t en_pad1; /* padding */ 98233044Stijl uint32_t en_mxcsr; /* SSE control/status register */ 99233044Stijl uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 100233044Stijl}; 101233044Stijl 102233044Stijlstruct __envxmm64 { 103233044Stijl uint16_t en_cw; /* control word (16bits) */ 104233044Stijl uint16_t en_sw; /* status word (16bits) */ 105233044Stijl uint8_t en_tw; /* tag word (8bits) */ 106233044Stijl uint8_t en_zero; 107233044Stijl uint16_t en_opcode; /* opcode last executed (11 bits ) */ 108233044Stijl uint64_t en_rip; /* fp instruction pointer */ 109233044Stijl uint64_t en_rdp; /* fp operand pointer */ 110233044Stijl uint32_t en_mxcsr; /* SSE control/status register */ 111233044Stijl uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 112233044Stijl}; 113233044Stijl 114233044Stijl/* Floating point context. (i386 fxsave/fxrstor) */ 115233044Stijlstruct savexmm { 116233044Stijl struct __envxmm32 sv_env; 117233044Stijl struct { 118233044Stijl struct fpacc87 fp_acc; 119233044Stijl uint8_t fp_pad[6]; /* padding */ 120233044Stijl } sv_fp[8]; 121233044Stijl struct xmmacc sv_xmm[8]; 122233044Stijl uint8_t sv_pad[224]; 123233044Stijl} __aligned(16); 124233044Stijl 125233044Stijl#ifdef __i386__ 126233044Stijlunion savefpu { 127233044Stijl struct save87 sv_87; 128233044Stijl struct savexmm sv_xmm; 129233044Stijl}; 130233044Stijl#else 131233044Stijl/* Floating point context. (amd64 fxsave/fxrstor) */ 132233044Stijlstruct savefpu { 133233044Stijl struct __envxmm64 sv_env; 134233044Stijl struct { 135233044Stijl struct fpacc87 fp_acc; 136233044Stijl uint8_t fp_pad[6]; /* padding */ 137233044Stijl } sv_fp[8]; 138233044Stijl struct xmmacc sv_xmm[16]; 139233044Stijl uint8_t sv_pad[96]; 140233044Stijl} __aligned(16); 141233044Stijl#endif 142233044Stijl 143233044Stijlstruct xstate_hdr { 144233044Stijl uint64_t xstate_bv; 145276133Skib uint64_t xstate_xcomp_bv; 146276133Skib uint8_t xstate_rsrv0[8]; 147233044Stijl uint8_t xstate_rsrv[40]; 148233044Stijl}; 149276133Skib#define XSTATE_XCOMP_BV_COMPACT (1ULL << 63) 150233044Stijl 151233044Stijlstruct savexmm_xstate { 152233044Stijl struct xstate_hdr sx_hd; 153233044Stijl struct ymmacc sx_ymm[16]; 154233044Stijl}; 155233044Stijl 156233044Stijlstruct savexmm_ymm { 157233044Stijl struct __envxmm32 sv_env; 158233044Stijl struct { 159233044Stijl struct fpacc87 fp_acc; 160233044Stijl int8_t fp_pad[6]; /* padding */ 161233044Stijl } sv_fp[8]; 162233044Stijl struct xmmacc sv_xmm[16]; 163233044Stijl uint8_t sv_pad[96]; 164233044Stijl struct savexmm_xstate sv_xstate; 165233044Stijl} __aligned(64); 166233044Stijl 167233044Stijlstruct savefpu_xstate { 168233044Stijl struct xstate_hdr sx_hd; 169233044Stijl struct ymmacc sx_ymm[16]; 170233044Stijl}; 171233044Stijl 172233044Stijlstruct savefpu_ymm { 173233044Stijl struct __envxmm64 sv_env; 174233044Stijl struct { 175233044Stijl struct fpacc87 fp_acc; 176233044Stijl int8_t fp_pad[6]; /* padding */ 177233044Stijl } sv_fp[8]; 178233044Stijl struct xmmacc sv_xmm[16]; 179233044Stijl uint8_t sv_pad[96]; 180233044Stijl struct savefpu_xstate sv_xstate; 181233044Stijl} __aligned(64); 182233044Stijl 183233044Stijl#undef __envxmm32 184233044Stijl#undef __envxmm64 185233044Stijl 186233044Stijl/* 187233044Stijl * The hardware default control word for i387's and later coprocessors is 188233044Stijl * 0x37F, giving: 189233044Stijl * 190233044Stijl * round to nearest 191233044Stijl * 64-bit precision 192233044Stijl * all exceptions masked. 193233044Stijl * 194233044Stijl * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc 195233044Stijl * because of the difference between memory and fpu register stack arguments. 196233044Stijl * If its using an intermediate fpu register, it has 80/64 bits to work 197233044Stijl * with. If it uses memory, it has 64/53 bits to work with. However, 198233044Stijl * gcc is aware of this and goes to a fair bit of trouble to make the 199233044Stijl * best use of it. 200233044Stijl * 201233044Stijl * This is mostly academic for AMD64, because the ABI prefers the use 202233044Stijl * SSE2 based math. For FreeBSD/amd64, we go with the default settings. 203233044Stijl */ 204233044Stijl#define __INITIAL_FPUCW__ 0x037F 205233044Stijl#define __INITIAL_FPUCW_I386__ 0x127F 206233044Stijl#define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__ 207233044Stijl#define __INITIAL_MXCSR__ 0x1F80 208233044Stijl#define __INITIAL_MXCSR_MASK__ 0xFFBF 209233044Stijl 210279211Sjhb/* 211279211Sjhb * The current value of %xcr0 is saved in the sv_pad[] field of the FPU 212279211Sjhb * state in the NT_X86_XSTATE note in core dumps. This offset is chosen 213279211Sjhb * to match the offset used by NT_X86_XSTATE in other systems. 214279211Sjhb */ 215279211Sjhb#define X86_XSTATE_XCR0_OFFSET 464 216279211Sjhb 217233044Stijl#endif /* !_X86_FPU_H_ */ 218