xref: /onnv-gate/usr/src/uts/intel/ia32/ml/float.s (revision 6648:aa953da6b224)
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