15b81b6b3SRodney W. Grimes /*- 25b81b6b3SRodney W. Grimes * Copyright (c) 1990 The Regents of the University of California. 35b81b6b3SRodney W. Grimes * All rights reserved. 45b81b6b3SRodney W. Grimes * 55b81b6b3SRodney W. Grimes * This code is derived from software contributed to Berkeley by 65b81b6b3SRodney W. Grimes * William Jolitz. 75b81b6b3SRodney W. Grimes * 85b81b6b3SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 95b81b6b3SRodney W. Grimes * modification, are permitted provided that the following conditions 105b81b6b3SRodney W. Grimes * are met: 115b81b6b3SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 125b81b6b3SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 135b81b6b3SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 145b81b6b3SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 155b81b6b3SRodney W. Grimes * documentation and/or other materials provided with the distribution. 165b81b6b3SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 175b81b6b3SRodney W. Grimes * may be used to endorse or promote products derived from this software 185b81b6b3SRodney W. Grimes * without specific prior written permission. 195b81b6b3SRodney W. Grimes * 205b81b6b3SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 215b81b6b3SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 225b81b6b3SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 235b81b6b3SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 245b81b6b3SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 255b81b6b3SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 265b81b6b3SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 275b81b6b3SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 285b81b6b3SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 295b81b6b3SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 305b81b6b3SRodney W. Grimes * SUCH DAMAGE. 315b81b6b3SRodney W. Grimes * 3234a8ed1bSRodney W. Grimes * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 33c3aac50fSPeter Wemm * $FreeBSD$ 345b81b6b3SRodney W. Grimes */ 355b81b6b3SRodney W. Grimes 365b81b6b3SRodney W. Grimes /* 37bf2f09eeSPeter Wemm * Floating Point Data Structures and Constants 385b81b6b3SRodney W. Grimes * W. Jolitz 1/90 395b81b6b3SRodney W. Grimes */ 405b81b6b3SRodney W. Grimes 41bf2f09eeSPeter Wemm #ifndef _MACHINE_FPU_H_ 42bf2f09eeSPeter Wemm #define _MACHINE_FPU_H_ 435b81b6b3SRodney W. Grimes 44afa88623SPeter Wemm /* Contents of each x87 floating point accumulator */ 455b81b6b3SRodney W. Grimes struct fpacc87 { 46e568229fSKonstantin Belousov uint8_t fp_bytes[10]; 479d146ac5SPeter Wemm }; 489d146ac5SPeter Wemm 499d146ac5SPeter Wemm /* Contents of each SSE extended accumulator */ 509d146ac5SPeter Wemm struct xmmacc { 51e568229fSKonstantin Belousov uint8_t xmm_bytes[16]; 52e568229fSKonstantin Belousov }; 53e568229fSKonstantin Belousov 54e568229fSKonstantin Belousov /* Contents of the upper 16 bytes of each AVX extended accumulator */ 55e568229fSKonstantin Belousov struct ymmacc { 56e568229fSKonstantin Belousov uint8_t ymm_bytes[16]; 579d146ac5SPeter Wemm }; 589d146ac5SPeter Wemm 59afa88623SPeter Wemm struct envxmm { 60e568229fSKonstantin Belousov uint16_t en_cw; /* control word (16bits) */ 61e568229fSKonstantin Belousov uint16_t en_sw; /* status word (16bits) */ 62e568229fSKonstantin Belousov uint8_t en_tw; /* tag word (8bits) */ 63e568229fSKonstantin Belousov uint8_t en_zero; 64e568229fSKonstantin Belousov uint16_t en_opcode; /* opcode last executed (11 bits ) */ 65e568229fSKonstantin Belousov uint64_t en_rip; /* floating point instruction pointer */ 66e568229fSKonstantin Belousov uint64_t en_rdp; /* floating operand pointer */ 67e568229fSKonstantin Belousov uint32_t en_mxcsr; /* SSE sontorol/status register */ 68e568229fSKonstantin Belousov uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ 69afa88623SPeter Wemm }; 70afa88623SPeter Wemm 71afa88623SPeter Wemm struct savefpu { 729d146ac5SPeter Wemm struct envxmm sv_env; 739d146ac5SPeter Wemm struct { 749d146ac5SPeter Wemm struct fpacc87 fp_acc; 75e568229fSKonstantin Belousov uint8_t fp_pad[6]; /* padding */ 769d146ac5SPeter Wemm } sv_fp[8]; 77afa88623SPeter Wemm struct xmmacc sv_xmm[16]; 78e568229fSKonstantin Belousov uint8_t sv_pad[96]; 79c692fbe0SPeter Wemm } __aligned(16); 809d146ac5SPeter Wemm 81*6db9cf55SKonstantin Belousov struct xstate_hdr { 82*6db9cf55SKonstantin Belousov uint64_t xstate_bv; 83*6db9cf55SKonstantin Belousov uint8_t xstate_rsrv0[16]; 84*6db9cf55SKonstantin Belousov uint8_t xstate_rsrv[40]; 85*6db9cf55SKonstantin Belousov }; 86*6db9cf55SKonstantin Belousov 87*6db9cf55SKonstantin Belousov struct savefpu_xstate { 88*6db9cf55SKonstantin Belousov struct xstate_hdr sx_hd; 89*6db9cf55SKonstantin Belousov struct ymmacc sx_ymm[16]; 90*6db9cf55SKonstantin Belousov }; 91*6db9cf55SKonstantin Belousov 92*6db9cf55SKonstantin Belousov struct savefpu_ymm { 93*6db9cf55SKonstantin Belousov struct envxmm sv_env; 94*6db9cf55SKonstantin Belousov struct { 95*6db9cf55SKonstantin Belousov struct fpacc87 fp_acc; 96*6db9cf55SKonstantin Belousov int8_t fp_pad[6]; /* padding */ 97*6db9cf55SKonstantin Belousov } sv_fp[8]; 98*6db9cf55SKonstantin Belousov struct xmmacc sv_xmm[16]; 99*6db9cf55SKonstantin Belousov uint8_t sv_pad[96]; 100*6db9cf55SKonstantin Belousov struct savefpu_xstate sv_xstate; 101*6db9cf55SKonstantin Belousov } __aligned(64); 102*6db9cf55SKonstantin Belousov 1036cf9a08dSKonstantin Belousov #ifdef _KERNEL 1046cf9a08dSKonstantin Belousov struct fpu_kern_ctx { 1056cf9a08dSKonstantin Belousov struct savefpu hwstate; 1066cf9a08dSKonstantin Belousov struct savefpu *prev; 1076cf9a08dSKonstantin Belousov uint32_t flags; 1086cf9a08dSKonstantin Belousov }; 1096cf9a08dSKonstantin Belousov #define FPU_KERN_CTX_FPUINITDONE 0x01 1106cf9a08dSKonstantin Belousov 1116cf9a08dSKonstantin Belousov #define PCB_USER_FPU(pcb) (((pcb)->pcb_flags & PCB_KERNFPU) == 0) 1126cf9a08dSKonstantin Belousov #endif 1136cf9a08dSKonstantin Belousov 1145b81b6b3SRodney W. Grimes /* 1150c14a660SMartin Cracauer * The hardware default control word for i387's and later coprocessors is 1160c14a660SMartin Cracauer * 0x37F, giving: 1175b81b6b3SRodney W. Grimes * 1185b81b6b3SRodney W. Grimes * round to nearest 1195b81b6b3SRodney W. Grimes * 64-bit precision 1205b81b6b3SRodney W. Grimes * all exceptions masked. 1215b81b6b3SRodney W. Grimes * 1225b9f8ddbSPeter Wemm * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc 1235b9f8ddbSPeter Wemm * because of the difference between memory and fpu register stack arguments. 1245b9f8ddbSPeter Wemm * If its using an intermediate fpu register, it has 80/64 bits to work 1255b9f8ddbSPeter Wemm * with. If it uses memory, it has 64/53 bits to work with. However, 1265b9f8ddbSPeter Wemm * gcc is aware of this and goes to a fair bit of trouble to make the 1275b9f8ddbSPeter Wemm * best use of it. 1285b81b6b3SRodney W. Grimes * 1295b9f8ddbSPeter Wemm * This is mostly academic for AMD64, because the ABI prefers the use 1305b9f8ddbSPeter Wemm * SSE2 based math. For FreeBSD/amd64, we go with the default settings. 1315b81b6b3SRodney W. Grimes */ 132bf2f09eeSPeter Wemm #define __INITIAL_FPUCW__ 0x037F 133de43ac60SJohn Baldwin #define __INITIAL_FPUCW_I386__ 0x127F 134395e65aaSPeter Wemm #define __INITIAL_MXCSR__ 0x1F80 135395e65aaSPeter Wemm #define __INITIAL_MXCSR_MASK__ 0xFFBF 1365b81b6b3SRodney W. Grimes 137664a31e4SPeter Wemm #ifdef _KERNEL 138a8346a98SJohn Baldwin void fpudna(void); 139bf2f09eeSPeter Wemm void fpudrop(void); 140bf2f09eeSPeter Wemm void fpuexit(struct thread *td); 141bf2f09eeSPeter Wemm int fpuformat(void); 1425c6eb037SKonstantin Belousov int fpugetregs(struct thread *td); 143398dbb11SPeter Wemm void fpuinit(void); 144bf2f09eeSPeter Wemm void fpusetregs(struct thread *td, struct savefpu *addr); 145bf2f09eeSPeter Wemm int fputrap(void); 1465c6eb037SKonstantin Belousov void fpuuserinited(struct thread *td); 1476cf9a08dSKonstantin Belousov int fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, 1486cf9a08dSKonstantin Belousov u_int flags); 1496cf9a08dSKonstantin Belousov int fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx); 1506cf9a08dSKonstantin Belousov int fpu_kern_thread(u_int flags); 1516cf9a08dSKonstantin Belousov int is_fpu_kern_thread(u_int flags); 1526cf9a08dSKonstantin Belousov 1536cf9a08dSKonstantin Belousov /* 1546cf9a08dSKonstantin Belousov * Flags for fpu_kern_enter() and fpu_kern_thread(). 1556cf9a08dSKonstantin Belousov */ 1566cf9a08dSKonstantin Belousov #define FPU_KERN_NORMAL 0x0000 1576cf9a08dSKonstantin Belousov 158a1ca704eSBruce Evans #endif 159a1ca704eSBruce Evans 160bf2f09eeSPeter Wemm #endif /* !_MACHINE_FPU_H_ */ 161