fpu.h revision 230426
182867Sdfr/*- 2139790Simp * Copyright (c) 1990 The Regents of the University of California. 3139790Simp * All rights reserved. 482867Sdfr * 582867Sdfr * This code is derived from software contributed to Berkeley by 682867Sdfr * William Jolitz. 782867Sdfr * 882867Sdfr * Redistribution and use in source and binary forms, with or without 982867Sdfr * modification, are permitted provided that the following conditions 1082867Sdfr * are met: 1182867Sdfr * 1. Redistributions of source code must retain the above copyright 1282867Sdfr * notice, this list of conditions and the following disclaimer. 1382867Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1482867Sdfr * notice, this list of conditions and the following disclaimer in the 1582867Sdfr * documentation and/or other materials provided with the distribution. 1682867Sdfr * 4. Neither the name of the University nor the names of its contributors 1782867Sdfr * may be used to endorse or promote products derived from this software 1882867Sdfr * without specific prior written permission. 1982867Sdfr * 2082867Sdfr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2182867Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2282867Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2382867Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2482867Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2582867Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2682867Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2782867Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2882867Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2982867Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3082867Sdfr * SUCH DAMAGE. 3182867Sdfr * 3282867Sdfr * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 3382867Sdfr * $FreeBSD: head/sys/amd64/include/fpu.h 230426 2012-01-21 17:45:27Z kib $ 3482867Sdfr */ 3582867Sdfr 3682867Sdfr/* 3782867Sdfr * Floating Point Data Structures and Constants 3882867Sdfr * W. Jolitz 1/90 3982867Sdfr */ 4082867Sdfr 4182867Sdfr#ifndef _MACHINE_FPU_H_ 4282867Sdfr#define _MACHINE_FPU_H_ 4382867Sdfr 4482867Sdfr/* Contents of each x87 floating point accumulator */ 4582867Sdfrstruct fpacc87 { 4682867Sdfr uint8_t fp_bytes[10]; 4782867Sdfr}; 4882867Sdfr 4982867Sdfr/* Contents of each SSE extended accumulator */ 5082867Sdfrstruct xmmacc { 5182867Sdfr uint8_t xmm_bytes[16]; 5282867Sdfr}; 5382867Sdfr 5482867Sdfr/* Contents of the upper 16 bytes of each AVX extended accumulator */ 5582867Sdfrstruct ymmacc { 5682867Sdfr uint8_t ymm_bytes[16]; 5782867Sdfr}; 5882867Sdfr 5982867Sdfrstruct envxmm { 6082867Sdfr uint16_t en_cw; /* control word (16bits) */ 6182867Sdfr uint16_t en_sw; /* status word (16bits) */ 6282867Sdfr uint8_t en_tw; /* tag word (8bits) */ 6382867Sdfr uint8_t en_zero; 6482867Sdfr uint16_t en_opcode; /* opcode last executed (11 bits ) */ 6582867Sdfr uint64_t en_rip; /* floating point instruction pointer */ 6682867Sdfr uint64_t en_rdp; /* floating operand pointer */ 6782867Sdfr uint32_t en_mxcsr; /* SSE sontorol/status register */ 6882867Sdfr uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 6982867Sdfr}; 7082867Sdfr 7182867Sdfrstruct savefpu { 7282867Sdfr struct envxmm sv_env; 7382867Sdfr struct { 7482867Sdfr struct fpacc87 fp_acc; 7582867Sdfr uint8_t fp_pad[6]; /* padding */ 7682867Sdfr } sv_fp[8]; 7782867Sdfr struct xmmacc sv_xmm[16]; 7882867Sdfr uint8_t sv_pad[96]; 7982867Sdfr} __aligned(16); 8082867Sdfr 8182867Sdfrstruct xstate_hdr { 8282867Sdfr uint64_t xstate_bv; 8382867Sdfr uint8_t xstate_rsrv0[16]; 8482867Sdfr uint8_t xstate_rsrv[40]; 8582867Sdfr}; 8682867Sdfr 8782867Sdfrstruct savefpu_xstate { 8882867Sdfr struct xstate_hdr sx_hd; 8982867Sdfr struct ymmacc sx_ymm[16]; 9082867Sdfr}; 9182867Sdfr 9282867Sdfrstruct savefpu_ymm { 9382867Sdfr struct envxmm sv_env; 9482867Sdfr struct { 9582867Sdfr struct fpacc87 fp_acc; 9682867Sdfr int8_t fp_pad[6]; /* padding */ 9782867Sdfr } sv_fp[8]; 9882867Sdfr struct xmmacc sv_xmm[16]; 9982867Sdfr uint8_t sv_pad[96]; 10082867Sdfr struct savefpu_xstate sv_xstate; 10182867Sdfr} __aligned(64); 10282867Sdfr 10382867Sdfr#ifdef _KERNEL 10482867Sdfr 10582867Sdfrstruct fpu_kern_ctx; 10682867Sdfr 10782867Sdfr#define PCB_USER_FPU(pcb) (((pcb)->pcb_flags & PCB_KERNFPU) == 0) 10882867Sdfr 10982867Sdfr#define XSAVE_AREA_ALIGN 64 11082867Sdfr 11182867Sdfr#endif 11282867Sdfr 11382867Sdfr/* 11482867Sdfr * The hardware default control word for i387's and later coprocessors is 11582867Sdfr * 0x37F, giving: 11682867Sdfr * 11782867Sdfr * round to nearest 11882867Sdfr * 64-bit precision 11982867Sdfr * all exceptions masked. 12082867Sdfr * 12182867Sdfr * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc 12282867Sdfr * because of the difference between memory and fpu register stack arguments. 12382867Sdfr * If its using an intermediate fpu register, it has 80/64 bits to work 12482867Sdfr * with. If it uses memory, it has 64/53 bits to work with. However, 12582867Sdfr * gcc is aware of this and goes to a fair bit of trouble to make the 12682867Sdfr * best use of it. 12782867Sdfr * 12882867Sdfr * This is mostly academic for AMD64, because the ABI prefers the use 12982867Sdfr * SSE2 based math. For FreeBSD/amd64, we go with the default settings. 13082867Sdfr */ 13182867Sdfr#define __INITIAL_FPUCW__ 0x037F 13282867Sdfr#define __INITIAL_FPUCW_I386__ 0x127F 13382867Sdfr#define __INITIAL_MXCSR__ 0x1F80 13482867Sdfr#define __INITIAL_MXCSR_MASK__ 0xFFBF 13582867Sdfr 13682867Sdfr#ifdef _KERNEL 13782867Sdfrvoid fpudna(void); 13882867Sdfrvoid fpudrop(void); 13982867Sdfrvoid fpuexit(struct thread *td); 14082867Sdfrint fpuformat(void); 14182867Sdfrint fpugetregs(struct thread *td); 14282867Sdfrvoid fpuinit(void); 14382867Sdfrvoid fpusave(void *addr); 14482867Sdfrint fpusetregs(struct thread *td, struct savefpu *addr, 14582867Sdfr char *xfpustate, size_t xfpustate_size); 14682867Sdfrint fpusetxstate(struct thread *td, char *xfpustate, 14782867Sdfr size_t xfpustate_size); 14882867Sdfrint fputrap(void); 14982867Sdfrvoid fpuuserinited(struct thread *td); 15082867Sdfrstruct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int flags); 15182867Sdfrvoid fpu_kern_free_ctx(struct fpu_kern_ctx *ctx); 15282867Sdfrint fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, 15382867Sdfr u_int flags); 15482867Sdfrint fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx); 15582867Sdfrint fpu_kern_thread(u_int flags); 15682867Sdfrint is_fpu_kern_thread(u_int flags); 15782867Sdfr 15882867Sdfr/* 15982867Sdfr * Flags for fpu_kern_alloc_ctx(), fpu_kern_enter() and fpu_kern_thread(). 16082867Sdfr */ 16182867Sdfr#define FPU_KERN_NORMAL 0x0000 16282867Sdfr#define FPU_KERN_NOWAIT 0x0001 16382867Sdfr 16482867Sdfr#endif 16582867Sdfr 16682867Sdfr#endif /* !_MACHINE_FPU_H_ */ 16782867Sdfr