14Srgrimes/*- 24Srgrimes * Copyright (c) 1990 The Regents of the University of California. 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * William Jolitz. 74Srgrimes * 84Srgrimes * Redistribution and use in source and binary forms, with or without 94Srgrimes * modification, are permitted provided that the following conditions 104Srgrimes * are met: 114Srgrimes * 1. Redistributions of source code must retain the above copyright 124Srgrimes * notice, this list of conditions and the following disclaimer. 134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer in the 154Srgrimes * documentation and/or other materials provided with the distribution. 164Srgrimes * 4. Neither the name of the University nor the names of its contributors 174Srgrimes * may be used to endorse or promote products derived from this software 184Srgrimes * without specific prior written permission. 194Srgrimes * 204Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 214Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 244Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304Srgrimes * SUCH DAMAGE. 314Srgrimes * 32621Srgrimes * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 3350477Speter * $FreeBSD$ 344Srgrimes */ 354Srgrimes 364Srgrimes/* 37122292Speter * Floating Point Data Structures and Constants 384Srgrimes * W. Jolitz 1/90 394Srgrimes */ 404Srgrimes 41122292Speter#ifndef _MACHINE_FPU_H_ 42122292Speter#define _MACHINE_FPU_H_ 434Srgrimes 44114349Speter/* Contents of each x87 floating point accumulator */ 4583047Sobrienstruct fpacc87 { 46230503Skib uint8_t fp_bytes[10]; 474Srgrimes}; 484Srgrimes 49114349Speter/* Contents of each SSE extended accumulator */ 50114349Speterstruct xmmacc { 51230503Skib uint8_t xmm_bytes[16]; 524Srgrimes}; 534Srgrimes 54230503Skib/* Contents of the upper 16 bytes of each AVX extended accumulator */ 55230503Skibstruct ymmacc { 56230503Skib uint8_t ymm_bytes[16]; 57230503Skib}; 58230503Skib 5979609Speterstruct envxmm { 60230503Skib uint16_t en_cw; /* control word (16bits) */ 61230503Skib uint16_t en_sw; /* status word (16bits) */ 62230503Skib uint8_t en_tw; /* tag word (8bits) */ 63230503Skib uint8_t en_zero; 64230503Skib uint16_t en_opcode; /* opcode last executed (11 bits ) */ 65230503Skib uint64_t en_rip; /* floating point instruction pointer */ 66230503Skib uint64_t en_rdp; /* floating operand pointer */ 67230503Skib uint32_t en_mxcsr; /* SSE sontorol/status register */ 68230503Skib uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 6979609Speter}; 7079609Speter 71114349Speterstruct savefpu { 7279609Speter struct envxmm sv_env; 7379609Speter struct { 7479609Speter struct fpacc87 fp_acc; 75230503Skib uint8_t fp_pad[6]; /* padding */ 7679609Speter } sv_fp[8]; 77114349Speter struct xmmacc sv_xmm[16]; 78230503Skib uint8_t sv_pad[96]; 79103834Speter} __aligned(16); 8079609Speter 81230504Skibstruct xstate_hdr { 82230504Skib uint64_t xstate_bv; 83230504Skib uint8_t xstate_rsrv0[16]; 84230504Skib uint8_t xstate_rsrv[40]; 85230504Skib}; 86230504Skib 87230504Skibstruct savefpu_xstate { 88230504Skib struct xstate_hdr sx_hd; 89230504Skib struct ymmacc sx_ymm[16]; 90230504Skib}; 91230504Skib 92230504Skibstruct savefpu_ymm { 93230504Skib struct envxmm sv_env; 94230504Skib struct { 95230504Skib struct fpacc87 fp_acc; 96230504Skib int8_t fp_pad[6]; /* padding */ 97230504Skib } sv_fp[8]; 98230504Skib struct xmmacc sv_xmm[16]; 99230504Skib uint8_t sv_pad[96]; 100230504Skib struct savefpu_xstate sv_xstate; 101230504Skib} __aligned(64); 102230504Skib 103208833Skib#ifdef _KERNEL 104208833Skib 105231979Skibstruct fpu_kern_ctx; 106231979Skib 107208833Skib#define PCB_USER_FPU(pcb) (((pcb)->pcb_flags & PCB_KERNFPU) == 0) 108231979Skib 109231979Skib#define XSAVE_AREA_ALIGN 64 110231979Skib 111208833Skib#endif 112208833Skib 1134Srgrimes/* 11457890Scracauer * The hardware default control word for i387's and later coprocessors is 11557890Scracauer * 0x37F, giving: 1164Srgrimes * 1174Srgrimes * round to nearest 1184Srgrimes * 64-bit precision 1194Srgrimes * all exceptions masked. 1204Srgrimes * 121117865Speter * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc 122117865Speter * because of the difference between memory and fpu register stack arguments. 123117865Speter * If its using an intermediate fpu register, it has 80/64 bits to work 124117865Speter * with. If it uses memory, it has 64/53 bits to work with. However, 125117865Speter * gcc is aware of this and goes to a fair bit of trouble to make the 126117865Speter * best use of it. 1274Srgrimes * 128117865Speter * This is mostly academic for AMD64, because the ABI prefers the use 129117865Speter * SSE2 based math. For FreeBSD/amd64, we go with the default settings. 1304Srgrimes */ 131122292Speter#define __INITIAL_FPUCW__ 0x037F 132187867Sjhb#define __INITIAL_FPUCW_I386__ 0x127F 133114859Speter#define __INITIAL_MXCSR__ 0x1F80 134114859Speter#define __INITIAL_MXCSR_MASK__ 0xFFBF 1354Srgrimes 13655205Speter#ifdef _KERNEL 137189412Sjhbvoid fpudna(void); 138122292Spetervoid fpudrop(void); 139122292Spetervoid fpuexit(struct thread *td); 140122292Speterint fpuformat(void); 141215865Skibint fpugetregs(struct thread *td); 142122295Spetervoid fpuinit(void); 143245046Sgrehanvoid fpurestore(void *addr); 144231979Skibvoid fpusave(void *addr); 145231979Skibint fpusetregs(struct thread *td, struct savefpu *addr, 146231979Skib char *xfpustate, size_t xfpustate_size); 147231979Skibint fpusetxstate(struct thread *td, char *xfpustate, 148231979Skib size_t xfpustate_size); 149262981Sjkimvoid fpususpend(void *addr); 150239944Skibint fputrap_sse(void); 151239944Skibint fputrap_x87(void); 152215865Skibvoid fpuuserinited(struct thread *td); 153231979Skibstruct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int flags); 154231979Skibvoid fpu_kern_free_ctx(struct fpu_kern_ctx *ctx); 155208833Skibint fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, 156208833Skib u_int flags); 157208833Skibint fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx); 158208833Skibint fpu_kern_thread(u_int flags); 159208833Skibint is_fpu_kern_thread(u_int flags); 160208833Skib 161245046Sgrehanstruct savefpu *fpu_save_area_alloc(void); 162245046Sgrehanvoid fpu_save_area_free(struct savefpu *fsa); 163245046Sgrehanvoid fpu_save_area_reset(struct savefpu *fsa); 164245046Sgrehan 165208833Skib/* 166231979Skib * Flags for fpu_kern_alloc_ctx(), fpu_kern_enter() and fpu_kern_thread(). 167208833Skib */ 168208833Skib#define FPU_KERN_NORMAL 0x0000 169231979Skib#define FPU_KERN_NOWAIT 0x0001 170208833Skib 1714175Sbde#endif 1724175Sbde 173122292Speter#endif /* !_MACHINE_FPU_H_ */ 174