fpu.h revision 230426
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: head/sys/amd64/include/fpu.h 230426 2012-01-21 17:45:27Z kib $ 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 { 46230269Skib uint8_t fp_bytes[10]; 474Srgrimes}; 484Srgrimes 49114349Speter/* Contents of each SSE extended accumulator */ 50114349Speterstruct xmmacc { 51230269Skib uint8_t xmm_bytes[16]; 524Srgrimes}; 534Srgrimes 54230269Skib/* Contents of the upper 16 bytes of each AVX extended accumulator */ 55230269Skibstruct ymmacc { 56230269Skib uint8_t ymm_bytes[16]; 57230269Skib}; 58230269Skib 5979609Speterstruct envxmm { 60230269Skib uint16_t en_cw; /* control word (16bits) */ 61230269Skib uint16_t en_sw; /* status word (16bits) */ 62230269Skib uint8_t en_tw; /* tag word (8bits) */ 63230269Skib uint8_t en_zero; 64230269Skib uint16_t en_opcode; /* opcode last executed (11 bits ) */ 65230269Skib uint64_t en_rip; /* floating point instruction pointer */ 66230269Skib uint64_t en_rdp; /* floating operand pointer */ 67230269Skib uint32_t en_mxcsr; /* SSE sontorol/status register */ 68230269Skib 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; 75230269Skib uint8_t fp_pad[6]; /* padding */ 7679609Speter } sv_fp[8]; 77114349Speter struct xmmacc sv_xmm[16]; 78230269Skib uint8_t sv_pad[96]; 79103834Speter} __aligned(16); 8079609Speter 81230270Skibstruct xstate_hdr { 82230270Skib uint64_t xstate_bv; 83230270Skib uint8_t xstate_rsrv0[16]; 84230270Skib uint8_t xstate_rsrv[40]; 85230270Skib}; 86230270Skib 87230270Skibstruct savefpu_xstate { 88230270Skib struct xstate_hdr sx_hd; 89230270Skib struct ymmacc sx_ymm[16]; 90230270Skib}; 91230270Skib 92230270Skibstruct savefpu_ymm { 93230270Skib struct envxmm sv_env; 94230270Skib struct { 95230270Skib struct fpacc87 fp_acc; 96230270Skib int8_t fp_pad[6]; /* padding */ 97230270Skib } sv_fp[8]; 98230270Skib struct xmmacc sv_xmm[16]; 99230270Skib uint8_t sv_pad[96]; 100230270Skib struct savefpu_xstate sv_xstate; 101230270Skib} __aligned(64); 102230270Skib 103208833Skib#ifdef _KERNEL 104208833Skib 105230426Skibstruct fpu_kern_ctx; 106230426Skib 107208833Skib#define PCB_USER_FPU(pcb) (((pcb)->pcb_flags & PCB_KERNFPU) == 0) 108230426Skib 109230426Skib#define XSAVE_AREA_ALIGN 64 110230426Skib 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); 143230426Skibvoid fpusave(void *addr); 144230426Skibint fpusetregs(struct thread *td, struct savefpu *addr, 145230426Skib char *xfpustate, size_t xfpustate_size); 146230426Skibint fpusetxstate(struct thread *td, char *xfpustate, 147230426Skib size_t xfpustate_size); 148122292Speterint fputrap(void); 149215865Skibvoid fpuuserinited(struct thread *td); 150230426Skibstruct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int flags); 151230426Skibvoid fpu_kern_free_ctx(struct fpu_kern_ctx *ctx); 152208833Skibint fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, 153208833Skib u_int flags); 154208833Skibint fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx); 155208833Skibint fpu_kern_thread(u_int flags); 156208833Skibint is_fpu_kern_thread(u_int flags); 157208833Skib 158208833Skib/* 159230426Skib * Flags for fpu_kern_alloc_ctx(), fpu_kern_enter() and fpu_kern_thread(). 160208833Skib */ 161208833Skib#define FPU_KERN_NORMAL 0x0000 162230426Skib#define FPU_KERN_NOWAIT 0x0001 163208833Skib 1644175Sbde#endif 1654175Sbde 166122292Speter#endif /* !_MACHINE_FPU_H_ */ 167