10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 53446Smrj * Common Development and Distribution License (the "License"). 63446Smrj * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 213446Smrj 220Sstevel@tonic-gate/* 23*6648Ska153516 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 280Sstevel@tonic-gate/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ 290Sstevel@tonic-gate/* All Rights Reserved */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate/* Copyright (c) 1987, 1988 Microsoft Corporation */ 320Sstevel@tonic-gate/* All Rights Reserved */ 330Sstevel@tonic-gate 340Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 350Sstevel@tonic-gate 360Sstevel@tonic-gate#include <sys/asm_linkage.h> 373446Smrj#include <sys/asm_misc.h> 380Sstevel@tonic-gate#include <sys/regset.h> 390Sstevel@tonic-gate#include <sys/privregs.h> 400Sstevel@tonic-gate#include <sys/x86_archext.h> 410Sstevel@tonic-gate 420Sstevel@tonic-gate#if defined(__lint) 430Sstevel@tonic-gate#include <sys/types.h> 440Sstevel@tonic-gate#include <sys/fp.h> 450Sstevel@tonic-gate#else 460Sstevel@tonic-gate#include "assym.h" 470Sstevel@tonic-gate#endif 480Sstevel@tonic-gate 490Sstevel@tonic-gate#if defined(__lint) 503446Smrj 513446Smrjuint_t 523446Smrjfpu_initial_probe(void) 533446Smrj{ return (0); } 540Sstevel@tonic-gate 550Sstevel@tonic-gate#else /* __lint */ 560Sstevel@tonic-gate 570Sstevel@tonic-gate /* 583446Smrj * Returns zero if x87 "chip" is present(!) 590Sstevel@tonic-gate */ 603446Smrj ENTRY_NP(fpu_initial_probe) 613446Smrj CLTS 623446Smrj fninit 633446Smrj fnstsw %ax 643446Smrj movzbl %al, %eax 653446Smrj ret 663446Smrj SET_SIZE(fpu_initial_probe) 670Sstevel@tonic-gate 680Sstevel@tonic-gate#endif /* __lint */ 690Sstevel@tonic-gate 703446Smrj#if defined(__lint) 710Sstevel@tonic-gate 720Sstevel@tonic-gate/*ARGSUSED*/ 730Sstevel@tonic-gatevoid 743446Smrjfxsave_insn(struct fxsave_state *fx) 750Sstevel@tonic-gate{} 760Sstevel@tonic-gate 770Sstevel@tonic-gate#else /* __lint */ 780Sstevel@tonic-gate 790Sstevel@tonic-gate#if defined(__amd64) 800Sstevel@tonic-gate 813446Smrj ENTRY_NP(fxsave_insn) 82*6648Ska153516 FXSAVEQ ((%rdi)) 830Sstevel@tonic-gate ret 843446Smrj SET_SIZE(fxsave_insn) 850Sstevel@tonic-gate 860Sstevel@tonic-gate#elif defined(__i386) 870Sstevel@tonic-gate 883446Smrj ENTRY_NP(fxsave_insn) 893446Smrj movl 4(%esp), %eax 903446Smrj fxsave (%eax) 913446Smrj ret 923446Smrj SET_SIZE(fxsave_insn) 933446Smrj 943446Smrj#endif 953446Smrj 963446Smrj#endif /* __lint */ 973446Smrj 983446Smrj#if defined(__i386) 993446Smrj 1003446Smrj/* 1013446Smrj * If (num1/num2 > num1/num3) the FPU has the FDIV bug. 1023446Smrj */ 1033446Smrj 1043446Smrj#if defined(__lint) 1053446Smrj 1063446Smrjint 1073446Smrjfpu_probe_pentium_fdivbug(void) 1083446Smrj{ return (0); } 1093446Smrj 1103446Smrj#else /* __lint */ 1113446Smrj 1123446Smrj ENTRY_NP(fpu_probe_pentium_fdivbug) 1133446Smrj fldl .num1 1143446Smrj fldl .num2 1150Sstevel@tonic-gate fdivr %st(1), %st 1160Sstevel@tonic-gate fxch %st(1) 1173446Smrj fdivl .num3 1180Sstevel@tonic-gate fcompp 1190Sstevel@tonic-gate fstsw %ax 1200Sstevel@tonic-gate sahf 1213446Smrj jae 0f 1223446Smrj movl $1, %eax 1233446Smrj ret 1243446Smrj 1253446Smrj0: xorl %eax, %eax 1263446Smrj ret 1273446Smrj 1283446Smrj .align 4 1293446Smrj.num1: .4byte 0xbce4217d /* 4.999999 */ 1303446Smrj .4byte 0x4013ffff 1313446Smrj.num2: .4byte 0x0 /* 15.0 */ 1323446Smrj .4byte 0x402e0000 1333446Smrj.num3: .4byte 0xde7210bf /* 14.999999 */ 1343446Smrj .4byte 0x402dffff 1353446Smrj SET_SIZE(fpu_probe_pentium_fdivbug) 1363446Smrj 1373446Smrj#endif /* __lint */ 1380Sstevel@tonic-gate 1393446Smrj/* 1403446Smrj * To cope with processors that do not implement fxsave/fxrstor 1413446Smrj * instructions, patch hot paths in the kernel to use them only 1423446Smrj * when that feature has been detected. 1433446Smrj */ 1443446Smrj 1453446Smrj#if defined(__lint) 1463446Smrj 1473446Smrjvoid 1483446Smrjpatch_sse(void) 1493446Smrj{} 1500Sstevel@tonic-gate 1513446Smrjvoid 1523446Smrjpatch_sse2(void) 1533446Smrj{} 1543446Smrj 1553446Smrj#else /* __lint */ 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate ENTRY_NP(patch_sse) 1583446Smrj _HOT_PATCH_PROLOG 1590Sstevel@tonic-gate / 1603446Smrj / frstor (%ebx); nop -> fxrstor (%ebx) 1610Sstevel@tonic-gate / 1623446Smrj _HOT_PATCH(_fxrstor_ebx_insn, _patch_fxrstor_ebx, 3) 1630Sstevel@tonic-gate / 1640Sstevel@tonic-gate / lock; xorl $0, (%esp) -> sfence; ret 1650Sstevel@tonic-gate / 1663446Smrj _HOT_PATCH(_sfence_ret_insn, _patch_sfence_ret, 4) 1673446Smrj _HOT_PATCH_EPILOG 1680Sstevel@tonic-gate ret 1693446Smrj_fxrstor_ebx_insn: / see ndptrap_frstor() 1703446Smrj fxrstor (%ebx) 1710Sstevel@tonic-gate_ldmxcsr_ebx_insn: / see resume_from_zombie() 1720Sstevel@tonic-gate ldmxcsr (%ebx) 1730Sstevel@tonic-gate_sfence_ret_insn: / see membar_producer() 1740Sstevel@tonic-gate .byte 0xf, 0xae, 0xf8 / [sfence instruction] 1750Sstevel@tonic-gate ret 1760Sstevel@tonic-gate SET_SIZE(patch_sse) 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate ENTRY_NP(patch_sse2) 1793446Smrj _HOT_PATCH_PROLOG 1800Sstevel@tonic-gate / 1810Sstevel@tonic-gate / lock; xorl $0, (%esp) -> lfence; ret 1820Sstevel@tonic-gate / 1833446Smrj _HOT_PATCH(_lfence_ret_insn, _patch_lfence_ret, 4) 1843446Smrj _HOT_PATCH_EPILOG 1850Sstevel@tonic-gate ret 1860Sstevel@tonic-gate_lfence_ret_insn: / see membar_consumer() 1870Sstevel@tonic-gate .byte 0xf, 0xae, 0xe8 / [lfence instruction] 1880Sstevel@tonic-gate ret 1890Sstevel@tonic-gate SET_SIZE(patch_sse2) 1900Sstevel@tonic-gate 1913446Smrj#endif /* __lint */ 1920Sstevel@tonic-gate#endif /* __i386 */ 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate/* 1960Sstevel@tonic-gate * One of these routines is called from any lwp with floating 1973446Smrj * point context as part of the prolog of a context switch. 1980Sstevel@tonic-gate */ 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate#if defined(__lint) 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate/*ARGSUSED*/ 2030Sstevel@tonic-gatevoid 2043446Smrjfpxsave_ctxt(void *arg) 2050Sstevel@tonic-gate{} 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate/*ARGSUSED*/ 2080Sstevel@tonic-gatevoid 2093446Smrjfpnsave_ctxt(void *arg) 2100Sstevel@tonic-gate{} 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate#else /* __lint */ 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate#if defined(__amd64) 2150Sstevel@tonic-gate 2163446Smrj ENTRY_NP(fpxsave_ctxt) 2173446Smrj cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%rdi) 2180Sstevel@tonic-gate jne 1f 2193446Smrj 2203446Smrj movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%rdi) 221*6648Ska153516 FXSAVEQ (FPU_CTX_FPU_REGS(%rdi)) 222*6648Ska153516 2233446Smrj /* 2243446Smrj * On certain AMD processors, the "exception pointers" i.e. the last 2253446Smrj * instruction pointer, last data pointer, and last opcode 2263446Smrj * are saved by the fxsave instruction ONLY if the exception summary 2273446Smrj * bit is set. 2283446Smrj * 2293446Smrj * To ensure that we don't leak these values into the next context 2303446Smrj * on the cpu, we could just issue an fninit here, but that's 2313446Smrj * rather slow and so we issue an instruction sequence that 2323446Smrj * clears them more quickly, if a little obscurely. 2333446Smrj */ 2343446Smrj btw $7, FXSAVE_STATE_FSW(%rdi) /* Test saved ES bit */ 2353446Smrj jnc 0f /* jump if ES = 0 */ 2363446Smrj fnclex /* clear pending x87 exceptions */ 2373446Smrj0: ffree %st(7) /* clear tag bit to remove possible stack overflow */ 2383446Smrj fildl .fpzero_const(%rip) 2393446Smrj /* dummy load changes all exception pointers */ 2403446Smrj STTS(%rsi) /* trap on next fpu touch */ 241545Skalai1: rep; ret /* use 2 byte return instruction when branch target */ 242545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 2433446Smrj SET_SIZE(fpxsave_ctxt) 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate#elif defined(__i386) 2460Sstevel@tonic-gate 2473446Smrj ENTRY_NP(fpnsave_ctxt) 2483446Smrj movl 4(%esp), %eax /* a struct fpu_ctx */ 2493446Smrj cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%eax) 2500Sstevel@tonic-gate jne 1f 2513446Smrj 2523446Smrj movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax) 2533446Smrj fnsave FPU_CTX_FPU_REGS(%eax) 2543446Smrj /* (fnsave also reinitializes x87 state) */ 2553446Smrj STTS(%edx) /* trap on next fpu touch */ 256545Skalai1: rep; ret /* use 2 byte return instruction when branch target */ 257545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 2583446Smrj SET_SIZE(fpnsave_ctxt) 2593446Smrj 2603446Smrj ENTRY_NP(fpxsave_ctxt) 2613446Smrj movl 4(%esp), %eax /* a struct fpu_ctx */ 2623446Smrj cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%eax) 2633446Smrj jne 1f 2640Sstevel@tonic-gate 2653446Smrj movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax) 2663446Smrj fxsave FPU_CTX_FPU_REGS(%eax) 2673446Smrj /* (see notes above about "exception pointers") */ 2683446Smrj btw $7, FXSAVE_STATE_FSW(%eax) /* Test saved ES bit */ 2693446Smrj jnc 0f /* jump if ES = 0 */ 2703446Smrj fnclex /* clear pending x87 exceptions */ 2713446Smrj0: ffree %st(7) /* clear tag bit to remove possible stack overflow */ 2723446Smrj fildl .fpzero_const 2733446Smrj /* dummy load changes all exception pointers */ 2743446Smrj STTS(%edx) /* trap on next fpu touch */ 275545Skalai1: rep; ret /* use 2 byte return instruction when branch target */ 276545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 2773446Smrj SET_SIZE(fpxsave_ctxt) 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate#endif /* __i386 */ 2803446Smrj 2813446Smrj .align 8 2823446Smrj.fpzero_const: 2833446Smrj .4byte 0x0 2843446Smrj .4byte 0x0 2853446Smrj 2860Sstevel@tonic-gate#endif /* __lint */ 2870Sstevel@tonic-gate 2883446Smrj 2890Sstevel@tonic-gate#if defined(__lint) 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate/*ARGSUSED*/ 2920Sstevel@tonic-gatevoid 2930Sstevel@tonic-gatefpsave(struct fnsave_state *f) 2940Sstevel@tonic-gate{} 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate/*ARGSUSED*/ 2970Sstevel@tonic-gatevoid 2980Sstevel@tonic-gatefpxsave(struct fxsave_state *f) 2990Sstevel@tonic-gate{} 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate#else /* __lint */ 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate#if defined(__amd64) 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate ENTRY_NP(fpxsave) 3063446Smrj CLTS 307*6648Ska153516 FXSAVEQ ((%rdi)) 3083446Smrj fninit /* clear exceptions, init x87 tags */ 3093446Smrj STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */ 3100Sstevel@tonic-gate ret 3110Sstevel@tonic-gate SET_SIZE(fpxsave) 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate#elif defined(__i386) 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate ENTRY_NP(fpsave) 3163446Smrj CLTS 3173446Smrj movl 4(%esp), %eax 3180Sstevel@tonic-gate fnsave (%eax) 3193446Smrj STTS(%eax) /* set TS bit in %cr0 (disable FPU) */ 3200Sstevel@tonic-gate ret 3210Sstevel@tonic-gate SET_SIZE(fpsave) 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate ENTRY_NP(fpxsave) 3243446Smrj CLTS 3253446Smrj movl 4(%esp), %eax 3260Sstevel@tonic-gate fxsave (%eax) 3273446Smrj fninit /* clear exceptions, init x87 tags */ 3283446Smrj STTS(%eax) /* set TS bit in %cr0 (disable FPU) */ 3290Sstevel@tonic-gate ret 3300Sstevel@tonic-gate SET_SIZE(fpxsave) 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate#endif /* __i386 */ 3330Sstevel@tonic-gate#endif /* __lint */ 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate#if defined(__lint) 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate/*ARGSUSED*/ 3380Sstevel@tonic-gatevoid 3390Sstevel@tonic-gatefprestore(struct fnsave_state *f) 3400Sstevel@tonic-gate{} 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate/*ARGSUSED*/ 3430Sstevel@tonic-gatevoid 3440Sstevel@tonic-gatefpxrestore(struct fxsave_state *f) 3450Sstevel@tonic-gate{} 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate#else /* __lint */ 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate#if defined(__amd64) 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate ENTRY_NP(fpxrestore) 3523446Smrj CLTS 353*6648Ska153516 FXRSTORQ ((%rdi)) 3540Sstevel@tonic-gate ret 3550Sstevel@tonic-gate SET_SIZE(fpxrestore) 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate#elif defined(__i386) 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate ENTRY_NP(fprestore) 3603446Smrj CLTS 3613446Smrj movl 4(%esp), %eax 3620Sstevel@tonic-gate frstor (%eax) 3630Sstevel@tonic-gate ret 3640Sstevel@tonic-gate SET_SIZE(fprestore) 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate ENTRY_NP(fpxrestore) 3673446Smrj CLTS 3683446Smrj movl 4(%esp), %eax 3690Sstevel@tonic-gate fxrstor (%eax) 3700Sstevel@tonic-gate ret 3710Sstevel@tonic-gate SET_SIZE(fpxrestore) 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate#endif /* __i386 */ 3740Sstevel@tonic-gate#endif /* __lint */ 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate/* 3770Sstevel@tonic-gate * Disable the floating point unit. 3780Sstevel@tonic-gate */ 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate#if defined(__lint) 3810Sstevel@tonic-gate 3820Sstevel@tonic-gatevoid 3830Sstevel@tonic-gatefpdisable(void) 3840Sstevel@tonic-gate{} 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate#else /* __lint */ 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate#if defined(__amd64) 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate ENTRY_NP(fpdisable) 3913446Smrj STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */ 3920Sstevel@tonic-gate ret 3930Sstevel@tonic-gate SET_SIZE(fpdisable) 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate#elif defined(__i386) 3960Sstevel@tonic-gate 3970Sstevel@tonic-gate ENTRY_NP(fpdisable) 3983446Smrj STTS(%eax) 3990Sstevel@tonic-gate ret 4000Sstevel@tonic-gate SET_SIZE(fpdisable) 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate#endif /* __i386 */ 4030Sstevel@tonic-gate#endif /* __lint */ 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate/* 4060Sstevel@tonic-gate * Initialize the fpu hardware. 4070Sstevel@tonic-gate */ 4080Sstevel@tonic-gate 4090Sstevel@tonic-gate#if defined(__lint) 4100Sstevel@tonic-gate 4110Sstevel@tonic-gatevoid 4120Sstevel@tonic-gatefpinit(void) 4130Sstevel@tonic-gate{} 4140Sstevel@tonic-gate 4150Sstevel@tonic-gate#else /* __lint */ 4160Sstevel@tonic-gate 4170Sstevel@tonic-gate#if defined(__amd64) 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate ENTRY_NP(fpinit) 4203446Smrj CLTS 4210Sstevel@tonic-gate leaq sse_initial(%rip), %rax 422*6648Ska153516 FXRSTORQ ((%rax)) /* load clean initial state */ 4230Sstevel@tonic-gate ret 4240Sstevel@tonic-gate SET_SIZE(fpinit) 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate#elif defined(__i386) 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate ENTRY_NP(fpinit) 4293446Smrj CLTS 4300Sstevel@tonic-gate cmpl $__FP_SSE, fp_kind 4310Sstevel@tonic-gate je 1f 4320Sstevel@tonic-gate 4333446Smrj fninit 4340Sstevel@tonic-gate movl $x87_initial, %eax 4353446Smrj frstor (%eax) /* load clean initial state */ 4360Sstevel@tonic-gate ret 4370Sstevel@tonic-gate1: 4380Sstevel@tonic-gate movl $sse_initial, %eax 4393446Smrj fxrstor (%eax) /* load clean initial state */ 4400Sstevel@tonic-gate ret 4410Sstevel@tonic-gate SET_SIZE(fpinit) 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate#endif /* __i386 */ 4440Sstevel@tonic-gate#endif /* __lint */ 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate/* 4470Sstevel@tonic-gate * Clears FPU exception state. 4480Sstevel@tonic-gate * Returns the FP status word. 4490Sstevel@tonic-gate */ 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate#if defined(__lint) 4520Sstevel@tonic-gate 4530Sstevel@tonic-gateuint32_t 4540Sstevel@tonic-gatefperr_reset(void) 4553446Smrj{ return (0); } 4560Sstevel@tonic-gate 4570Sstevel@tonic-gateuint32_t 4580Sstevel@tonic-gatefpxerr_reset(void) 4593446Smrj{ return (0); } 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate#else /* __lint */ 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate#if defined(__amd64) 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate ENTRY_NP(fperr_reset) 4663446Smrj CLTS 4670Sstevel@tonic-gate xorl %eax, %eax 4683446Smrj fnstsw %ax 4693446Smrj fnclex 4700Sstevel@tonic-gate ret 4710Sstevel@tonic-gate SET_SIZE(fperr_reset) 4720Sstevel@tonic-gate 4730Sstevel@tonic-gate ENTRY_NP(fpxerr_reset) 4740Sstevel@tonic-gate pushq %rbp 4750Sstevel@tonic-gate movq %rsp, %rbp 4760Sstevel@tonic-gate subq $0x10, %rsp /* make some temporary space */ 4773446Smrj CLTS 4783446Smrj stmxcsr (%rsp) 4790Sstevel@tonic-gate movl (%rsp), %eax 4800Sstevel@tonic-gate andl $_BITNOT(SSE_MXCSR_EFLAGS), (%rsp) 4810Sstevel@tonic-gate ldmxcsr (%rsp) /* clear processor exceptions */ 4820Sstevel@tonic-gate leave 4830Sstevel@tonic-gate ret 4840Sstevel@tonic-gate SET_SIZE(fpxerr_reset) 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate#elif defined(__i386) 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate ENTRY_NP(fperr_reset) 4893446Smrj CLTS 4900Sstevel@tonic-gate xorl %eax, %eax 4913446Smrj fnstsw %ax 4923446Smrj fnclex 4930Sstevel@tonic-gate ret 4940Sstevel@tonic-gate SET_SIZE(fperr_reset) 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate ENTRY_NP(fpxerr_reset) 4973446Smrj CLTS 4983446Smrj subl $4, %esp /* make some temporary space */ 4993446Smrj stmxcsr (%esp) 5000Sstevel@tonic-gate movl (%esp), %eax 5010Sstevel@tonic-gate andl $_BITNOT(SSE_MXCSR_EFLAGS), (%esp) 5023446Smrj ldmxcsr (%esp) /* clear processor exceptions */ 5030Sstevel@tonic-gate addl $4, %esp 5040Sstevel@tonic-gate ret 5050Sstevel@tonic-gate SET_SIZE(fpxerr_reset) 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate#endif /* __i386 */ 5080Sstevel@tonic-gate#endif /* __lint */ 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate#if defined(__lint) 5110Sstevel@tonic-gate 5120Sstevel@tonic-gateuint32_t 5130Sstevel@tonic-gatefpgetcwsw(void) 5140Sstevel@tonic-gate{ 5150Sstevel@tonic-gate return (0); 5160Sstevel@tonic-gate} 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate#else /* __lint */ 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate#if defined(__amd64) 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate ENTRY_NP(fpgetcwsw) 5230Sstevel@tonic-gate pushq %rbp 5240Sstevel@tonic-gate movq %rsp, %rbp 5250Sstevel@tonic-gate subq $0x10, %rsp /* make some temporary space */ 5263446Smrj CLTS 5270Sstevel@tonic-gate fnstsw (%rsp) /* store the status word */ 5280Sstevel@tonic-gate fnstcw 2(%rsp) /* store the control word */ 5290Sstevel@tonic-gate movl (%rsp), %eax /* put both in %eax */ 5300Sstevel@tonic-gate leave 5310Sstevel@tonic-gate ret 5320Sstevel@tonic-gate SET_SIZE(fpgetcwsw) 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate#elif defined(__i386) 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate ENTRY_NP(fpgetcwsw) 5373446Smrj CLTS 5380Sstevel@tonic-gate subl $4, %esp /* make some temporary space */ 5390Sstevel@tonic-gate fnstsw (%esp) /* store the status word */ 5400Sstevel@tonic-gate fnstcw 2(%esp) /* store the control word */ 5410Sstevel@tonic-gate movl (%esp), %eax /* put both in %eax */ 5420Sstevel@tonic-gate addl $4, %esp 5430Sstevel@tonic-gate ret 5440Sstevel@tonic-gate SET_SIZE(fpgetcwsw) 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate#endif /* __i386 */ 5470Sstevel@tonic-gate#endif /* __lint */ 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate/* 5500Sstevel@tonic-gate * Returns the MXCSR register. 5510Sstevel@tonic-gate */ 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate#if defined(__lint) 5540Sstevel@tonic-gate 5550Sstevel@tonic-gateuint32_t 5560Sstevel@tonic-gatefpgetmxcsr(void) 5570Sstevel@tonic-gate{ 5580Sstevel@tonic-gate return (0); 5590Sstevel@tonic-gate} 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate#else /* __lint */ 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate#if defined(__amd64) 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate ENTRY_NP(fpgetmxcsr) 5660Sstevel@tonic-gate pushq %rbp 5670Sstevel@tonic-gate movq %rsp, %rbp 5683446Smrj subq $0x10, %rsp /* make some temporary space */ 5693446Smrj CLTS 5703446Smrj stmxcsr (%rsp) 5710Sstevel@tonic-gate movl (%rsp), %eax 5720Sstevel@tonic-gate leave 5730Sstevel@tonic-gate ret 5740Sstevel@tonic-gate SET_SIZE(fpgetmxcsr) 5750Sstevel@tonic-gate 5760Sstevel@tonic-gate#elif defined(__i386) 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate ENTRY_NP(fpgetmxcsr) 5793446Smrj CLTS 5803446Smrj subl $4, %esp /* make some temporary space */ 5813446Smrj stmxcsr (%esp) 5820Sstevel@tonic-gate movl (%esp), %eax 5830Sstevel@tonic-gate addl $4, %esp 5840Sstevel@tonic-gate ret 5850Sstevel@tonic-gate SET_SIZE(fpgetmxcsr) 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate#endif /* __i386 */ 5880Sstevel@tonic-gate#endif /* __lint */ 589