fpu.h revision 233044
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: head/sys/x86/include/fpu.h 233044 2012-03-16 20:24:30Z tijl $ 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) */ 66233044Stijl /* 67233044Stijl * Bogus padding for emulators. Emulators should use their own 68233044Stijl * struct and arrange to store into this struct (ending here) 69233044Stijl * before it is inspected for ptracing or for core dumps. Some 70233044Stijl * emulators overwrite the whole struct. We have no good way of 71233044Stijl * knowing how much padding to leave. Leave just enough for the 72233044Stijl * GPL emulator's i387_union (176 bytes total). 73233044Stijl */ 74233044Stijl uint8_t sv_pad[64]; /* padding; used by emulators */ 75233044Stijl}; 76233044Stijl 77233044Stijl/* Contents of each SSE extended accumulator. */ 78233044Stijlstruct xmmacc { 79233044Stijl uint8_t xmm_bytes[16]; 80233044Stijl}; 81233044Stijl 82233044Stijl/* Contents of the upper 16 bytes of each AVX extended accumulator. */ 83233044Stijlstruct ymmacc { 84233044Stijl uint8_t ymm_bytes[16]; 85233044Stijl}; 86233044Stijl 87233044Stijl/* Rename structs below depending on machine architecture. */ 88233044Stijl#ifdef __i386__ 89233044Stijl#define __envxmm32 envxmm 90233044Stijl#else 91233044Stijl#define __envxmm32 envxmm32 92233044Stijl#define __envxmm64 envxmm 93233044Stijl#endif 94233044Stijl 95233044Stijlstruct __envxmm32 { 96233044Stijl uint16_t en_cw; /* control word (16bits) */ 97233044Stijl uint16_t en_sw; /* status word (16bits) */ 98233044Stijl uint16_t en_tw; /* tag word (16bits) */ 99233044Stijl uint16_t en_opcode; /* opcode last executed (11 bits) */ 100233044Stijl uint32_t en_fip; /* fp instruction pointer */ 101233044Stijl uint16_t en_fcs; /* fp code segment selector */ 102233044Stijl uint16_t en_pad0; /* padding */ 103233044Stijl uint32_t en_foo; /* fp operand offset */ 104233044Stijl uint16_t en_fos; /* fp operand segment selector */ 105233044Stijl uint16_t en_pad1; /* padding */ 106233044Stijl uint32_t en_mxcsr; /* SSE control/status register */ 107233044Stijl uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 108233044Stijl}; 109233044Stijl 110233044Stijlstruct __envxmm64 { 111233044Stijl uint16_t en_cw; /* control word (16bits) */ 112233044Stijl uint16_t en_sw; /* status word (16bits) */ 113233044Stijl uint8_t en_tw; /* tag word (8bits) */ 114233044Stijl uint8_t en_zero; 115233044Stijl uint16_t en_opcode; /* opcode last executed (11 bits ) */ 116233044Stijl uint64_t en_rip; /* fp instruction pointer */ 117233044Stijl uint64_t en_rdp; /* fp operand pointer */ 118233044Stijl uint32_t en_mxcsr; /* SSE control/status register */ 119233044Stijl uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 120233044Stijl}; 121233044Stijl 122233044Stijl/* Floating point context. (i386 fxsave/fxrstor) */ 123233044Stijlstruct savexmm { 124233044Stijl struct __envxmm32 sv_env; 125233044Stijl struct { 126233044Stijl struct fpacc87 fp_acc; 127233044Stijl uint8_t fp_pad[6]; /* padding */ 128233044Stijl } sv_fp[8]; 129233044Stijl struct xmmacc sv_xmm[8]; 130233044Stijl uint8_t sv_pad[224]; 131233044Stijl} __aligned(16); 132233044Stijl 133233044Stijl#ifdef __i386__ 134233044Stijlunion savefpu { 135233044Stijl struct save87 sv_87; 136233044Stijl struct savexmm sv_xmm; 137233044Stijl}; 138233044Stijl#else 139233044Stijl/* Floating point context. (amd64 fxsave/fxrstor) */ 140233044Stijlstruct savefpu { 141233044Stijl struct __envxmm64 sv_env; 142233044Stijl struct { 143233044Stijl struct fpacc87 fp_acc; 144233044Stijl uint8_t fp_pad[6]; /* padding */ 145233044Stijl } sv_fp[8]; 146233044Stijl struct xmmacc sv_xmm[16]; 147233044Stijl uint8_t sv_pad[96]; 148233044Stijl} __aligned(16); 149233044Stijl#endif 150233044Stijl 151233044Stijlstruct xstate_hdr { 152233044Stijl uint64_t xstate_bv; 153233044Stijl uint8_t xstate_rsrv0[16]; 154233044Stijl uint8_t xstate_rsrv[40]; 155233044Stijl}; 156233044Stijl 157233044Stijlstruct savexmm_xstate { 158233044Stijl struct xstate_hdr sx_hd; 159233044Stijl struct ymmacc sx_ymm[16]; 160233044Stijl}; 161233044Stijl 162233044Stijlstruct savexmm_ymm { 163233044Stijl struct __envxmm32 sv_env; 164233044Stijl struct { 165233044Stijl struct fpacc87 fp_acc; 166233044Stijl int8_t fp_pad[6]; /* padding */ 167233044Stijl } sv_fp[8]; 168233044Stijl struct xmmacc sv_xmm[16]; 169233044Stijl uint8_t sv_pad[96]; 170233044Stijl struct savexmm_xstate sv_xstate; 171233044Stijl} __aligned(64); 172233044Stijl 173233044Stijlstruct savefpu_xstate { 174233044Stijl struct xstate_hdr sx_hd; 175233044Stijl struct ymmacc sx_ymm[16]; 176233044Stijl}; 177233044Stijl 178233044Stijlstruct savefpu_ymm { 179233044Stijl struct __envxmm64 sv_env; 180233044Stijl struct { 181233044Stijl struct fpacc87 fp_acc; 182233044Stijl int8_t fp_pad[6]; /* padding */ 183233044Stijl } sv_fp[8]; 184233044Stijl struct xmmacc sv_xmm[16]; 185233044Stijl uint8_t sv_pad[96]; 186233044Stijl struct savefpu_xstate sv_xstate; 187233044Stijl} __aligned(64); 188233044Stijl 189233044Stijl#undef __envxmm32 190233044Stijl#undef __envxmm64 191233044Stijl 192233044Stijl/* 193233044Stijl * The hardware default control word for i387's and later coprocessors is 194233044Stijl * 0x37F, giving: 195233044Stijl * 196233044Stijl * round to nearest 197233044Stijl * 64-bit precision 198233044Stijl * all exceptions masked. 199233044Stijl * 200233044Stijl * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc 201233044Stijl * because of the difference between memory and fpu register stack arguments. 202233044Stijl * If its using an intermediate fpu register, it has 80/64 bits to work 203233044Stijl * with. If it uses memory, it has 64/53 bits to work with. However, 204233044Stijl * gcc is aware of this and goes to a fair bit of trouble to make the 205233044Stijl * best use of it. 206233044Stijl * 207233044Stijl * This is mostly academic for AMD64, because the ABI prefers the use 208233044Stijl * SSE2 based math. For FreeBSD/amd64, we go with the default settings. 209233044Stijl */ 210233044Stijl#define __INITIAL_FPUCW__ 0x037F 211233044Stijl#define __INITIAL_FPUCW_I386__ 0x127F 212233044Stijl#define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__ 213233044Stijl#define __INITIAL_MXCSR__ 0x1F80 214233044Stijl#define __INITIAL_MXCSR_MASK__ 0xFFBF 215233044Stijl 216233044Stijl#endif /* !_X86_FPU_H_ */ 217