xref: /onnv-gate/usr/src/uts/intel/ia32/ml/float.s (revision 13134:8315ff49e22e)
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*13134Skuriakose.kuruvilla@oracle.com * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate/*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
270Sstevel@tonic-gate/*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T   */
280Sstevel@tonic-gate/*        All Rights Reserved   */
290Sstevel@tonic-gate
300Sstevel@tonic-gate/*      Copyright (c) 1987, 1988 Microsoft Corporation  */
310Sstevel@tonic-gate/*        All Rights Reserved   */
320Sstevel@tonic-gate
33*13134Skuriakose.kuruvilla@oracle.com/*
34*13134Skuriakose.kuruvilla@oracle.com * Copyright (c) 2009, Intel Corporation.
35*13134Skuriakose.kuruvilla@oracle.com * All rights reserved.
36*13134Skuriakose.kuruvilla@oracle.com */
370Sstevel@tonic-gate
380Sstevel@tonic-gate#include <sys/asm_linkage.h>
393446Smrj#include <sys/asm_misc.h>
400Sstevel@tonic-gate#include <sys/regset.h>
410Sstevel@tonic-gate#include <sys/privregs.h>
420Sstevel@tonic-gate#include <sys/x86_archext.h>
430Sstevel@tonic-gate
440Sstevel@tonic-gate#if defined(__lint)
450Sstevel@tonic-gate#include <sys/types.h>
460Sstevel@tonic-gate#include <sys/fp.h>
470Sstevel@tonic-gate#else
480Sstevel@tonic-gate#include "assym.h"
490Sstevel@tonic-gate#endif
500Sstevel@tonic-gate
510Sstevel@tonic-gate#if defined(__lint)
523446Smrj
533446Smrjuint_t
543446Smrjfpu_initial_probe(void)
553446Smrj{ return (0); }
560Sstevel@tonic-gate
570Sstevel@tonic-gate#else	/* __lint */
580Sstevel@tonic-gate
590Sstevel@tonic-gate	/*
603446Smrj	 * Returns zero if x87 "chip" is present(!)
610Sstevel@tonic-gate	 */
623446Smrj	ENTRY_NP(fpu_initial_probe)
633446Smrj	CLTS
643446Smrj	fninit
653446Smrj	fnstsw	%ax
663446Smrj	movzbl	%al, %eax
673446Smrj	ret
683446Smrj	SET_SIZE(fpu_initial_probe)
690Sstevel@tonic-gate
700Sstevel@tonic-gate#endif	/* __lint */
710Sstevel@tonic-gate
723446Smrj#if defined(__lint)
730Sstevel@tonic-gate
740Sstevel@tonic-gate/*ARGSUSED*/
750Sstevel@tonic-gatevoid
763446Smrjfxsave_insn(struct fxsave_state *fx)
770Sstevel@tonic-gate{}
780Sstevel@tonic-gate
790Sstevel@tonic-gate#else	/* __lint */
800Sstevel@tonic-gate
810Sstevel@tonic-gate#if defined(__amd64)
820Sstevel@tonic-gate
833446Smrj	ENTRY_NP(fxsave_insn)
846648Ska153516	FXSAVEQ	((%rdi))
850Sstevel@tonic-gate	ret
863446Smrj	SET_SIZE(fxsave_insn)
870Sstevel@tonic-gate
880Sstevel@tonic-gate#elif defined(__i386)
890Sstevel@tonic-gate
903446Smrj	ENTRY_NP(fxsave_insn)
913446Smrj	movl	4(%esp), %eax
923446Smrj	fxsave	(%eax)
933446Smrj	ret
943446Smrj	SET_SIZE(fxsave_insn)
953446Smrj
963446Smrj#endif
973446Smrj
983446Smrj#endif	/* __lint */
993446Smrj
1003446Smrj#if defined(__i386)
1013446Smrj
1023446Smrj/*
1033446Smrj * If (num1/num2 > num1/num3) the FPU has the FDIV bug.
1043446Smrj */
1053446Smrj
1063446Smrj#if defined(__lint)
1073446Smrj
1083446Smrjint
1093446Smrjfpu_probe_pentium_fdivbug(void)
1103446Smrj{ return (0); }
1113446Smrj
1123446Smrj#else	/* __lint */
1133446Smrj
1143446Smrj	ENTRY_NP(fpu_probe_pentium_fdivbug)
1153446Smrj	fldl	.num1
1163446Smrj	fldl	.num2
1170Sstevel@tonic-gate	fdivr	%st(1), %st
1180Sstevel@tonic-gate	fxch	%st(1)
1193446Smrj	fdivl	.num3
1200Sstevel@tonic-gate	fcompp
1210Sstevel@tonic-gate	fstsw	%ax
1220Sstevel@tonic-gate	sahf
1233446Smrj	jae	0f
1243446Smrj	movl	$1, %eax
1253446Smrj	ret
1263446Smrj
1273446Smrj0:	xorl	%eax, %eax
1283446Smrj	ret
1293446Smrj
1303446Smrj	.align	4
1313446Smrj.num1:	.4byte	0xbce4217d	/* 4.999999 */
1323446Smrj	.4byte	0x4013ffff
1333446Smrj.num2:	.4byte	0x0		/* 15.0 */
1343446Smrj	.4byte	0x402e0000
1353446Smrj.num3:	.4byte	0xde7210bf	/* 14.999999 */
1363446Smrj	.4byte	0x402dffff
1373446Smrj	SET_SIZE(fpu_probe_pentium_fdivbug)
1383446Smrj
1393446Smrj#endif	/* __lint */
1400Sstevel@tonic-gate
1413446Smrj/*
1423446Smrj * To cope with processors that do not implement fxsave/fxrstor
1433446Smrj * instructions, patch hot paths in the kernel to use them only
1443446Smrj * when that feature has been detected.
1453446Smrj */
1463446Smrj
1473446Smrj#if defined(__lint)
1483446Smrj
1493446Smrjvoid
1503446Smrjpatch_sse(void)
1513446Smrj{}
1520Sstevel@tonic-gate
1533446Smrjvoid
1543446Smrjpatch_sse2(void)
1553446Smrj{}
1563446Smrj
157*13134Skuriakose.kuruvilla@oracle.comvoid
158*13134Skuriakose.kuruvilla@oracle.compatch_xsave(void)
159*13134Skuriakose.kuruvilla@oracle.com{}
160*13134Skuriakose.kuruvilla@oracle.com
1613446Smrj#else	/* __lint */
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate	ENTRY_NP(patch_sse)
1643446Smrj	_HOT_PATCH_PROLOG
1650Sstevel@tonic-gate	/
1663446Smrj	/	frstor (%ebx); nop	-> fxrstor (%ebx)
1670Sstevel@tonic-gate	/
1683446Smrj	_HOT_PATCH(_fxrstor_ebx_insn, _patch_fxrstor_ebx, 3)
1690Sstevel@tonic-gate	/
1700Sstevel@tonic-gate	/	lock; xorl $0, (%esp)	-> sfence; ret
1710Sstevel@tonic-gate	/
1723446Smrj	_HOT_PATCH(_sfence_ret_insn, _patch_sfence_ret, 4)
1733446Smrj	_HOT_PATCH_EPILOG
1740Sstevel@tonic-gate	ret
1753446Smrj_fxrstor_ebx_insn:			/ see ndptrap_frstor()
1763446Smrj	fxrstor	(%ebx)
1770Sstevel@tonic-gate_ldmxcsr_ebx_insn:			/ see resume_from_zombie()
1780Sstevel@tonic-gate	ldmxcsr	(%ebx)
1790Sstevel@tonic-gate_sfence_ret_insn:			/ see membar_producer()
1800Sstevel@tonic-gate	.byte	0xf, 0xae, 0xf8		/ [sfence instruction]
1810Sstevel@tonic-gate	ret
1820Sstevel@tonic-gate	SET_SIZE(patch_sse)
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate	ENTRY_NP(patch_sse2)
1853446Smrj	_HOT_PATCH_PROLOG
1860Sstevel@tonic-gate	/
1870Sstevel@tonic-gate	/	lock; xorl $0, (%esp)	-> lfence; ret
1880Sstevel@tonic-gate	/
1893446Smrj	_HOT_PATCH(_lfence_ret_insn, _patch_lfence_ret, 4)
1903446Smrj	_HOT_PATCH_EPILOG
1910Sstevel@tonic-gate	ret
1920Sstevel@tonic-gate_lfence_ret_insn:			/ see membar_consumer()
1930Sstevel@tonic-gate	.byte	0xf, 0xae, 0xe8		/ [lfence instruction]
1940Sstevel@tonic-gate	ret
1950Sstevel@tonic-gate	SET_SIZE(patch_sse2)
1960Sstevel@tonic-gate
197*13134Skuriakose.kuruvilla@oracle.com	/*
198*13134Skuriakose.kuruvilla@oracle.com	 * Patch lazy fp restore instructions in the trap handler
199*13134Skuriakose.kuruvilla@oracle.com	 * to use xrstor instead of frstor
200*13134Skuriakose.kuruvilla@oracle.com	 */
201*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(patch_xsave)
202*13134Skuriakose.kuruvilla@oracle.com	_HOT_PATCH_PROLOG
203*13134Skuriakose.kuruvilla@oracle.com	/
204*13134Skuriakose.kuruvilla@oracle.com	/	frstor (%ebx); nop	-> xrstor (%ebx)
205*13134Skuriakose.kuruvilla@oracle.com	/
206*13134Skuriakose.kuruvilla@oracle.com	_HOT_PATCH(_xrstor_ebx_insn, _patch_xrstor_ebx, 3)
207*13134Skuriakose.kuruvilla@oracle.com	_HOT_PATCH_EPILOG
208*13134Skuriakose.kuruvilla@oracle.com	ret
209*13134Skuriakose.kuruvilla@oracle.com_xrstor_ebx_insn:			/ see ndptrap_frstor()
210*13134Skuriakose.kuruvilla@oracle.com	#xrstor (%ebx)
211*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x2b
212*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(patch_xsave)
213*13134Skuriakose.kuruvilla@oracle.com
2143446Smrj#endif	/* __lint */
2150Sstevel@tonic-gate#endif	/* __i386 */
2160Sstevel@tonic-gate
217*13134Skuriakose.kuruvilla@oracle.com#if defined(__amd64)
218*13134Skuriakose.kuruvilla@oracle.com#if defined(__lint)
219*13134Skuriakose.kuruvilla@oracle.com
220*13134Skuriakose.kuruvilla@oracle.comvoid
221*13134Skuriakose.kuruvilla@oracle.compatch_xsave(void)
222*13134Skuriakose.kuruvilla@oracle.com{}
223*13134Skuriakose.kuruvilla@oracle.com
224*13134Skuriakose.kuruvilla@oracle.com#else	/* __lint */
225*13134Skuriakose.kuruvilla@oracle.com
226*13134Skuriakose.kuruvilla@oracle.com	/*
227*13134Skuriakose.kuruvilla@oracle.com	 * Patch lazy fp restore instructions in the trap handler
228*13134Skuriakose.kuruvilla@oracle.com	 * to use xrstor instead of fxrstorq
229*13134Skuriakose.kuruvilla@oracle.com	 */
230*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(patch_xsave)
231*13134Skuriakose.kuruvilla@oracle.com	pushq	%rbx
232*13134Skuriakose.kuruvilla@oracle.com	pushq	%rbp
233*13134Skuriakose.kuruvilla@oracle.com	pushq	%r15
234*13134Skuriakose.kuruvilla@oracle.com	/
235*13134Skuriakose.kuruvilla@oracle.com	/	FXRSTORQ (%rbx);	-> xrstor (%rbx)
236*13134Skuriakose.kuruvilla@oracle.com	/ hot_patch(_xrstor_rbx_insn, _patch_xrstorq_rbx, 4)
237*13134Skuriakose.kuruvilla@oracle.com	/
238*13134Skuriakose.kuruvilla@oracle.com	leaq	_patch_xrstorq_rbx(%rip), %rbx
239*13134Skuriakose.kuruvilla@oracle.com	leaq	_xrstor_rbx_insn(%rip), %rbp
240*13134Skuriakose.kuruvilla@oracle.com	movq	$4, %r15
241*13134Skuriakose.kuruvilla@oracle.com1:
242*13134Skuriakose.kuruvilla@oracle.com	movq	%rbx, %rdi			/* patch address */
243*13134Skuriakose.kuruvilla@oracle.com	movzbq	(%rbp), %rsi			/* instruction byte */
244*13134Skuriakose.kuruvilla@oracle.com	movq	$1, %rdx			/* count */
245*13134Skuriakose.kuruvilla@oracle.com	call	hot_patch_kernel_text
246*13134Skuriakose.kuruvilla@oracle.com	addq	$1, %rbx
247*13134Skuriakose.kuruvilla@oracle.com	addq	$1, %rbp
248*13134Skuriakose.kuruvilla@oracle.com	subq	$1, %r15
249*13134Skuriakose.kuruvilla@oracle.com	jnz	1b
2500Sstevel@tonic-gate
251*13134Skuriakose.kuruvilla@oracle.com	popq	%r15
252*13134Skuriakose.kuruvilla@oracle.com	popq	%rbp
253*13134Skuriakose.kuruvilla@oracle.com	popq	%rbx
254*13134Skuriakose.kuruvilla@oracle.com	ret
255*13134Skuriakose.kuruvilla@oracle.com
256*13134Skuriakose.kuruvilla@oracle.com_xrstor_rbx_insn:			/ see ndptrap_frstor()
257*13134Skuriakose.kuruvilla@oracle.com	#rex.W=1 (.byte 0x48)
258*13134Skuriakose.kuruvilla@oracle.com	#xrstor (%rbx)
259*13134Skuriakose.kuruvilla@oracle.com	.byte	0x48, 0x0f, 0xae, 0x2b
260*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(patch_xsave)
261*13134Skuriakose.kuruvilla@oracle.com
262*13134Skuriakose.kuruvilla@oracle.com#endif	/* __lint */
263*13134Skuriakose.kuruvilla@oracle.com#endif	/* __amd64 */
264*13134Skuriakose.kuruvilla@oracle.com
2650Sstevel@tonic-gate/*
2660Sstevel@tonic-gate * One of these routines is called from any lwp with floating
2673446Smrj * point context as part of the prolog of a context switch.
2680Sstevel@tonic-gate */
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate#if defined(__lint)
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate/*ARGSUSED*/
2730Sstevel@tonic-gatevoid
274*13134Skuriakose.kuruvilla@oracle.comxsave_ctxt(void *arg)
275*13134Skuriakose.kuruvilla@oracle.com{}
276*13134Skuriakose.kuruvilla@oracle.com
277*13134Skuriakose.kuruvilla@oracle.com/*ARGSUSED*/
278*13134Skuriakose.kuruvilla@oracle.comvoid
2793446Smrjfpxsave_ctxt(void *arg)
2800Sstevel@tonic-gate{}
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate/*ARGSUSED*/
2830Sstevel@tonic-gatevoid
2843446Smrjfpnsave_ctxt(void *arg)
2850Sstevel@tonic-gate{}
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate#else	/* __lint */
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate#if defined(__amd64)
2900Sstevel@tonic-gate
2913446Smrj	ENTRY_NP(fpxsave_ctxt)
2923446Smrj	cmpl	$FPU_EN, FPU_CTX_FPU_FLAGS(%rdi)
2930Sstevel@tonic-gate	jne	1f
2943446Smrj
2953446Smrj	movl	$_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%rdi)
2966648Ska153516	FXSAVEQ	(FPU_CTX_FPU_REGS(%rdi))
2976648Ska153516
2983446Smrj	/*
2993446Smrj	 * On certain AMD processors, the "exception pointers" i.e. the last
3003446Smrj	 * instruction pointer, last data pointer, and last opcode
3013446Smrj	 * are saved by the fxsave instruction ONLY if the exception summary
3023446Smrj	 * bit is set.
3033446Smrj	 *
3043446Smrj	 * To ensure that we don't leak these values into the next context
3053446Smrj	 * on the cpu, we could just issue an fninit here, but that's
3063446Smrj	 * rather slow and so we issue an instruction sequence that
3073446Smrj	 * clears them more quickly, if a little obscurely.
3083446Smrj	 */
3093446Smrj	btw	$7, FXSAVE_STATE_FSW(%rdi)	/* Test saved ES bit */
3103446Smrj	jnc	0f				/* jump if ES = 0 */
3113446Smrj	fnclex		/* clear pending x87 exceptions */
3123446Smrj0:	ffree	%st(7)	/* clear tag bit to remove possible stack overflow */
3133446Smrj	fildl	.fpzero_const(%rip)
3143446Smrj			/* dummy load changes all exception pointers */
3153446Smrj	STTS(%rsi)	/* trap on next fpu touch */
316545Skalai1:	rep;	ret	/* use 2 byte return instruction when branch target */
317545Skalai			/* AMD Software Optimization Guide - Section 6.2 */
3183446Smrj	SET_SIZE(fpxsave_ctxt)
3190Sstevel@tonic-gate
320*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xsave_ctxt)
321*13134Skuriakose.kuruvilla@oracle.com	cmpl	$FPU_EN, FPU_CTX_FPU_FLAGS(%rdi)
322*13134Skuriakose.kuruvilla@oracle.com	jne	1f
323*13134Skuriakose.kuruvilla@oracle.com	movl	$_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%rdi)
324*13134Skuriakose.kuruvilla@oracle.com	/*
325*13134Skuriakose.kuruvilla@oracle.com	 * Setup xsave flags in EDX:EAX
326*13134Skuriakose.kuruvilla@oracle.com	 */
327*13134Skuriakose.kuruvilla@oracle.com	movl	FPU_CTX_FPU_XSAVE_MASK(%rdi), %eax
328*13134Skuriakose.kuruvilla@oracle.com	movl	FPU_CTX_FPU_XSAVE_MASK+4(%rdi), %edx
329*13134Skuriakose.kuruvilla@oracle.com	leaq	FPU_CTX_FPU_REGS(%rdi), %rsi
330*13134Skuriakose.kuruvilla@oracle.com	#xsave	(%rsi)
331*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x26
332*13134Skuriakose.kuruvilla@oracle.com
333*13134Skuriakose.kuruvilla@oracle.com	/*
334*13134Skuriakose.kuruvilla@oracle.com	 * (see notes above about "exception pointers")
335*13134Skuriakose.kuruvilla@oracle.com	 * TODO: does it apply to any machine that uses xsave?
336*13134Skuriakose.kuruvilla@oracle.com	 */
337*13134Skuriakose.kuruvilla@oracle.com	btw	$7, FXSAVE_STATE_FSW(%rdi)	/* Test saved ES bit */
338*13134Skuriakose.kuruvilla@oracle.com	jnc	0f				/* jump if ES = 0 */
339*13134Skuriakose.kuruvilla@oracle.com	fnclex		/* clear pending x87 exceptions */
340*13134Skuriakose.kuruvilla@oracle.com0:	ffree	%st(7)	/* clear tag bit to remove possible stack overflow */
341*13134Skuriakose.kuruvilla@oracle.com	fildl	.fpzero_const(%rip)
342*13134Skuriakose.kuruvilla@oracle.com			/* dummy load changes all exception pointers */
343*13134Skuriakose.kuruvilla@oracle.com	STTS(%rsi)	/* trap on next fpu touch */
344*13134Skuriakose.kuruvilla@oracle.com1:	ret
345*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xsave_ctxt)
346*13134Skuriakose.kuruvilla@oracle.com
3470Sstevel@tonic-gate#elif defined(__i386)
3480Sstevel@tonic-gate
3493446Smrj	ENTRY_NP(fpnsave_ctxt)
3503446Smrj	movl	4(%esp), %eax		/* a struct fpu_ctx */
3513446Smrj	cmpl	$FPU_EN, FPU_CTX_FPU_FLAGS(%eax)
3520Sstevel@tonic-gate	jne	1f
3533446Smrj
3543446Smrj	movl	$_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
3553446Smrj	fnsave	FPU_CTX_FPU_REGS(%eax)
3563446Smrj			/* (fnsave also reinitializes x87 state) */
3573446Smrj	STTS(%edx)	/* trap on next fpu touch */
358545Skalai1:	rep;	ret	/* use 2 byte return instruction when branch target */
359545Skalai			/* AMD Software Optimization Guide - Section 6.2 */
3603446Smrj	SET_SIZE(fpnsave_ctxt)
3613446Smrj
3623446Smrj	ENTRY_NP(fpxsave_ctxt)
3633446Smrj	movl	4(%esp), %eax		/* a struct fpu_ctx */
3643446Smrj	cmpl	$FPU_EN, FPU_CTX_FPU_FLAGS(%eax)
3653446Smrj	jne	1f
3660Sstevel@tonic-gate
3673446Smrj	movl	$_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
3683446Smrj	fxsave	FPU_CTX_FPU_REGS(%eax)
3693446Smrj			/* (see notes above about "exception pointers") */
3703446Smrj	btw	$7, FXSAVE_STATE_FSW(%eax)	/* Test saved ES bit */
3713446Smrj	jnc	0f				/* jump if ES = 0 */
3723446Smrj	fnclex		/* clear pending x87 exceptions */
3733446Smrj0:	ffree	%st(7)	/* clear tag bit to remove possible stack overflow */
3743446Smrj	fildl	.fpzero_const
3753446Smrj			/* dummy load changes all exception pointers */
3763446Smrj	STTS(%edx)	/* trap on next fpu touch */
377545Skalai1:	rep;	ret	/* use 2 byte return instruction when branch target */
378545Skalai			/* AMD Software Optimization Guide - Section 6.2 */
3793446Smrj	SET_SIZE(fpxsave_ctxt)
3800Sstevel@tonic-gate
381*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xsave_ctxt)
382*13134Skuriakose.kuruvilla@oracle.com	movl	4(%esp), %ecx		/* a struct fpu_ctx */
383*13134Skuriakose.kuruvilla@oracle.com	cmpl	$FPU_EN, FPU_CTX_FPU_FLAGS(%ecx)
384*13134Skuriakose.kuruvilla@oracle.com	jne	1f
385*13134Skuriakose.kuruvilla@oracle.com
386*13134Skuriakose.kuruvilla@oracle.com	movl	$_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%ecx)
387*13134Skuriakose.kuruvilla@oracle.com	movl	FPU_CTX_FPU_XSAVE_MASK(%ecx), %eax
388*13134Skuriakose.kuruvilla@oracle.com	movl	FPU_CTX_FPU_XSAVE_MASK+4(%ecx), %edx
389*13134Skuriakose.kuruvilla@oracle.com	leal	FPU_CTX_FPU_REGS(%ecx), %ecx
390*13134Skuriakose.kuruvilla@oracle.com	#xsave	(%ecx)
391*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x21
392*13134Skuriakose.kuruvilla@oracle.com
393*13134Skuriakose.kuruvilla@oracle.com	/*
394*13134Skuriakose.kuruvilla@oracle.com	 * (see notes above about "exception pointers")
395*13134Skuriakose.kuruvilla@oracle.com	 * TODO: does it apply to any machine that uses xsave?
396*13134Skuriakose.kuruvilla@oracle.com	 */
397*13134Skuriakose.kuruvilla@oracle.com	btw	$7, FXSAVE_STATE_FSW(%ecx)	/* Test saved ES bit */
398*13134Skuriakose.kuruvilla@oracle.com	jnc	0f				/* jump if ES = 0 */
399*13134Skuriakose.kuruvilla@oracle.com	fnclex		/* clear pending x87 exceptions */
400*13134Skuriakose.kuruvilla@oracle.com0:	ffree	%st(7)	/* clear tag bit to remove possible stack overflow */
401*13134Skuriakose.kuruvilla@oracle.com	fildl	.fpzero_const
402*13134Skuriakose.kuruvilla@oracle.com			/* dummy load changes all exception pointers */
403*13134Skuriakose.kuruvilla@oracle.com	STTS(%edx)	/* trap on next fpu touch */
404*13134Skuriakose.kuruvilla@oracle.com1:	ret
405*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xsave_ctxt)
406*13134Skuriakose.kuruvilla@oracle.com
4070Sstevel@tonic-gate#endif	/* __i386 */
4083446Smrj
4093446Smrj	.align	8
4103446Smrj.fpzero_const:
4113446Smrj	.4byte	0x0
4123446Smrj	.4byte	0x0
4133446Smrj
4140Sstevel@tonic-gate#endif	/* __lint */
4150Sstevel@tonic-gate
4163446Smrj
4170Sstevel@tonic-gate#if defined(__lint)
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate/*ARGSUSED*/
4200Sstevel@tonic-gatevoid
4210Sstevel@tonic-gatefpsave(struct fnsave_state *f)
4220Sstevel@tonic-gate{}
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate/*ARGSUSED*/
4250Sstevel@tonic-gatevoid
4260Sstevel@tonic-gatefpxsave(struct fxsave_state *f)
4270Sstevel@tonic-gate{}
4280Sstevel@tonic-gate
429*13134Skuriakose.kuruvilla@oracle.com/*ARGSUSED*/
430*13134Skuriakose.kuruvilla@oracle.comvoid
431*13134Skuriakose.kuruvilla@oracle.comxsave(struct xsave_state *f, uint64_t m)
432*13134Skuriakose.kuruvilla@oracle.com{}
433*13134Skuriakose.kuruvilla@oracle.com
4340Sstevel@tonic-gate#else	/* __lint */
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate#if defined(__amd64)
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate	ENTRY_NP(fpxsave)
4393446Smrj	CLTS
4406648Ska153516	FXSAVEQ	((%rdi))
4413446Smrj	fninit				/* clear exceptions, init x87 tags */
4423446Smrj	STTS(%rdi)			/* set TS bit in %cr0 (disable FPU) */
4430Sstevel@tonic-gate	ret
4440Sstevel@tonic-gate	SET_SIZE(fpxsave)
4450Sstevel@tonic-gate
446*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xsave)
447*13134Skuriakose.kuruvilla@oracle.com	CLTS
448*13134Skuriakose.kuruvilla@oracle.com	movl	%esi, %eax		/* bv mask */
449*13134Skuriakose.kuruvilla@oracle.com	movq	%rsi, %rdx
450*13134Skuriakose.kuruvilla@oracle.com	shrq	$32, %rdx
451*13134Skuriakose.kuruvilla@oracle.com	#xsave	(%rdi)
452*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x27
453*13134Skuriakose.kuruvilla@oracle.com
454*13134Skuriakose.kuruvilla@oracle.com	fninit				/* clear exceptions, init x87 tags */
455*13134Skuriakose.kuruvilla@oracle.com	STTS(%rdi)			/* set TS bit in %cr0 (disable FPU) */
456*13134Skuriakose.kuruvilla@oracle.com	ret
457*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xsave)
458*13134Skuriakose.kuruvilla@oracle.com
4590Sstevel@tonic-gate#elif defined(__i386)
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate	ENTRY_NP(fpsave)
4623446Smrj	CLTS
4633446Smrj	movl	4(%esp), %eax
4640Sstevel@tonic-gate	fnsave	(%eax)
4653446Smrj	STTS(%eax)			/* set TS bit in %cr0 (disable FPU) */
4660Sstevel@tonic-gate	ret
4670Sstevel@tonic-gate	SET_SIZE(fpsave)
4680Sstevel@tonic-gate
4690Sstevel@tonic-gate	ENTRY_NP(fpxsave)
4703446Smrj	CLTS
4713446Smrj	movl	4(%esp), %eax
4720Sstevel@tonic-gate	fxsave	(%eax)
4733446Smrj	fninit				/* clear exceptions, init x87 tags */
4743446Smrj	STTS(%eax)			/* set TS bit in %cr0 (disable FPU) */
4750Sstevel@tonic-gate	ret
4760Sstevel@tonic-gate	SET_SIZE(fpxsave)
4770Sstevel@tonic-gate
478*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xsave)
479*13134Skuriakose.kuruvilla@oracle.com	CLTS
480*13134Skuriakose.kuruvilla@oracle.com	movl	4(%esp), %ecx
481*13134Skuriakose.kuruvilla@oracle.com	movl	8(%esp), %eax
482*13134Skuriakose.kuruvilla@oracle.com	movl	12(%esp), %edx
483*13134Skuriakose.kuruvilla@oracle.com	#xsave	(%ecx)
484*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x21
485*13134Skuriakose.kuruvilla@oracle.com
486*13134Skuriakose.kuruvilla@oracle.com	fninit				/* clear exceptions, init x87 tags */
487*13134Skuriakose.kuruvilla@oracle.com	STTS(%eax)			/* set TS bit in %cr0 (disable FPU) */
488*13134Skuriakose.kuruvilla@oracle.com	ret
489*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xsave)
490*13134Skuriakose.kuruvilla@oracle.com
4910Sstevel@tonic-gate#endif	/* __i386 */
4920Sstevel@tonic-gate#endif	/* __lint */
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate#if defined(__lint)
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate/*ARGSUSED*/
4970Sstevel@tonic-gatevoid
4980Sstevel@tonic-gatefprestore(struct fnsave_state *f)
4990Sstevel@tonic-gate{}
5000Sstevel@tonic-gate
5010Sstevel@tonic-gate/*ARGSUSED*/
5020Sstevel@tonic-gatevoid
5030Sstevel@tonic-gatefpxrestore(struct fxsave_state *f)
5040Sstevel@tonic-gate{}
5050Sstevel@tonic-gate
506*13134Skuriakose.kuruvilla@oracle.com/*ARGSUSED*/
507*13134Skuriakose.kuruvilla@oracle.comvoid
508*13134Skuriakose.kuruvilla@oracle.comxrestore(struct xsave_state *f, uint64_t m)
509*13134Skuriakose.kuruvilla@oracle.com{}
510*13134Skuriakose.kuruvilla@oracle.com
5110Sstevel@tonic-gate#else	/* __lint */
5120Sstevel@tonic-gate
5130Sstevel@tonic-gate#if defined(__amd64)
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate	ENTRY_NP(fpxrestore)
5163446Smrj	CLTS
5176648Ska153516	FXRSTORQ	((%rdi))
5180Sstevel@tonic-gate	ret
5190Sstevel@tonic-gate	SET_SIZE(fpxrestore)
5200Sstevel@tonic-gate
521*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xrestore)
522*13134Skuriakose.kuruvilla@oracle.com	CLTS
523*13134Skuriakose.kuruvilla@oracle.com	movl	%esi, %eax		/* bv mask */
524*13134Skuriakose.kuruvilla@oracle.com	movq	%rsi, %rdx
525*13134Skuriakose.kuruvilla@oracle.com	shrq	$32, %rdx
526*13134Skuriakose.kuruvilla@oracle.com	#xrstor	(%rdi)
527*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x2f
528*13134Skuriakose.kuruvilla@oracle.com	ret
529*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xrestore)
530*13134Skuriakose.kuruvilla@oracle.com
5310Sstevel@tonic-gate#elif defined(__i386)
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate	ENTRY_NP(fprestore)
5343446Smrj	CLTS
5353446Smrj	movl	4(%esp), %eax
5360Sstevel@tonic-gate	frstor	(%eax)
5370Sstevel@tonic-gate	ret
5380Sstevel@tonic-gate	SET_SIZE(fprestore)
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate	ENTRY_NP(fpxrestore)
5413446Smrj	CLTS
5423446Smrj	movl	4(%esp), %eax
5430Sstevel@tonic-gate	fxrstor	(%eax)
5440Sstevel@tonic-gate	ret
5450Sstevel@tonic-gate	SET_SIZE(fpxrestore)
5460Sstevel@tonic-gate
547*13134Skuriakose.kuruvilla@oracle.com	ENTRY_NP(xrestore)
548*13134Skuriakose.kuruvilla@oracle.com	CLTS
549*13134Skuriakose.kuruvilla@oracle.com	movl	4(%esp), %ecx
550*13134Skuriakose.kuruvilla@oracle.com	movl	8(%esp), %eax
551*13134Skuriakose.kuruvilla@oracle.com	movl	12(%esp), %edx
552*13134Skuriakose.kuruvilla@oracle.com	#xrstor	(%ecx)
553*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x29
554*13134Skuriakose.kuruvilla@oracle.com	ret
555*13134Skuriakose.kuruvilla@oracle.com	SET_SIZE(xrestore)
556*13134Skuriakose.kuruvilla@oracle.com
5570Sstevel@tonic-gate#endif	/* __i386 */
5580Sstevel@tonic-gate#endif	/* __lint */
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate/*
5610Sstevel@tonic-gate * Disable the floating point unit.
5620Sstevel@tonic-gate */
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate#if defined(__lint)
5650Sstevel@tonic-gate
5660Sstevel@tonic-gatevoid
5670Sstevel@tonic-gatefpdisable(void)
5680Sstevel@tonic-gate{}
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate#else	/* __lint */
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate#if defined(__amd64)
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate	ENTRY_NP(fpdisable)
5753446Smrj	STTS(%rdi)			/* set TS bit in %cr0 (disable FPU) */
5760Sstevel@tonic-gate	ret
5770Sstevel@tonic-gate	SET_SIZE(fpdisable)
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate#elif defined(__i386)
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate	ENTRY_NP(fpdisable)
5823446Smrj	STTS(%eax)
5830Sstevel@tonic-gate	ret
5840Sstevel@tonic-gate	SET_SIZE(fpdisable)
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate#endif	/* __i386 */
5870Sstevel@tonic-gate#endif	/* __lint */
5880Sstevel@tonic-gate
5890Sstevel@tonic-gate/*
5900Sstevel@tonic-gate * Initialize the fpu hardware.
5910Sstevel@tonic-gate */
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate#if defined(__lint)
5940Sstevel@tonic-gate
5950Sstevel@tonic-gatevoid
5960Sstevel@tonic-gatefpinit(void)
5970Sstevel@tonic-gate{}
5980Sstevel@tonic-gate
5990Sstevel@tonic-gate#else	/* __lint */
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate#if defined(__amd64)
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate	ENTRY_NP(fpinit)
6043446Smrj	CLTS
605*13134Skuriakose.kuruvilla@oracle.com	cmpl	$FP_XSAVE, fp_save_mech
606*13134Skuriakose.kuruvilla@oracle.com	je	1f
607*13134Skuriakose.kuruvilla@oracle.com
608*13134Skuriakose.kuruvilla@oracle.com	/* fxsave */
6090Sstevel@tonic-gate	leaq	sse_initial(%rip), %rax
6106648Ska153516	FXRSTORQ	((%rax))		/* load clean initial state */
6110Sstevel@tonic-gate	ret
612*13134Skuriakose.kuruvilla@oracle.com
613*13134Skuriakose.kuruvilla@oracle.com1:	/* xsave */
614*13134Skuriakose.kuruvilla@oracle.com	leaq	avx_initial(%rip), %rcx
615*13134Skuriakose.kuruvilla@oracle.com	xorl	%edx, %edx
616*13134Skuriakose.kuruvilla@oracle.com	movl	$XFEATURE_AVX, %eax
617*13134Skuriakose.kuruvilla@oracle.com	bt	$X86FSET_AVX, x86_featureset
618*13134Skuriakose.kuruvilla@oracle.com	cmovael	%edx, %eax
619*13134Skuriakose.kuruvilla@oracle.com	orl	$(XFEATURE_LEGACY_FP | XFEATURE_SSE), %eax
620*13134Skuriakose.kuruvilla@oracle.com	/* xrstor (%rcx) */
621*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x29		/* load clean initial state */
622*13134Skuriakose.kuruvilla@oracle.com	ret
6230Sstevel@tonic-gate	SET_SIZE(fpinit)
6240Sstevel@tonic-gate
6250Sstevel@tonic-gate#elif defined(__i386)
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate	ENTRY_NP(fpinit)
6283446Smrj	CLTS
629*13134Skuriakose.kuruvilla@oracle.com	cmpl	$FP_FXSAVE, fp_save_mech
6300Sstevel@tonic-gate	je	1f
631*13134Skuriakose.kuruvilla@oracle.com	cmpl	$FP_XSAVE, fp_save_mech
632*13134Skuriakose.kuruvilla@oracle.com	je	2f
6330Sstevel@tonic-gate
634*13134Skuriakose.kuruvilla@oracle.com	/* fnsave */
6353446Smrj	fninit
6360Sstevel@tonic-gate	movl	$x87_initial, %eax
6373446Smrj	frstor	(%eax)			/* load clean initial state */
6380Sstevel@tonic-gate	ret
639*13134Skuriakose.kuruvilla@oracle.com
640*13134Skuriakose.kuruvilla@oracle.com1:	/* fxsave */
6410Sstevel@tonic-gate	movl	$sse_initial, %eax
6423446Smrj	fxrstor	(%eax)			/* load clean initial state */
6430Sstevel@tonic-gate	ret
644*13134Skuriakose.kuruvilla@oracle.com
645*13134Skuriakose.kuruvilla@oracle.com2:	/* xsave */
646*13134Skuriakose.kuruvilla@oracle.com	movl	$avx_initial, %ecx
647*13134Skuriakose.kuruvilla@oracle.com	xorl	%edx, %edx
648*13134Skuriakose.kuruvilla@oracle.com	movl	$XFEATURE_AVX, %eax
649*13134Skuriakose.kuruvilla@oracle.com	bt	$X86FSET_AVX, x86_featureset
650*13134Skuriakose.kuruvilla@oracle.com	cmovael	%edx, %eax
651*13134Skuriakose.kuruvilla@oracle.com	orl	$(XFEATURE_LEGACY_FP | XFEATURE_SSE), %eax
652*13134Skuriakose.kuruvilla@oracle.com	/* xrstor (%ecx) */
653*13134Skuriakose.kuruvilla@oracle.com	.byte	0x0f, 0xae, 0x29	/* load clean initial state */
654*13134Skuriakose.kuruvilla@oracle.com	ret
6550Sstevel@tonic-gate	SET_SIZE(fpinit)
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate#endif	/* __i386 */
6580Sstevel@tonic-gate#endif	/* __lint */
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate/*
6610Sstevel@tonic-gate * Clears FPU exception state.
6620Sstevel@tonic-gate * Returns the FP status word.
6630Sstevel@tonic-gate */
6640Sstevel@tonic-gate
6650Sstevel@tonic-gate#if defined(__lint)
6660Sstevel@tonic-gate
6670Sstevel@tonic-gateuint32_t
6680Sstevel@tonic-gatefperr_reset(void)
6693446Smrj{ return (0); }
6700Sstevel@tonic-gate
6710Sstevel@tonic-gateuint32_t
6720Sstevel@tonic-gatefpxerr_reset(void)
6733446Smrj{ return (0); }
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate#else	/* __lint */
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate#if defined(__amd64)
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate	ENTRY_NP(fperr_reset)
6803446Smrj	CLTS
6810Sstevel@tonic-gate	xorl	%eax, %eax
6823446Smrj	fnstsw	%ax
6833446Smrj	fnclex
6840Sstevel@tonic-gate	ret
6850Sstevel@tonic-gate	SET_SIZE(fperr_reset)
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate	ENTRY_NP(fpxerr_reset)
6880Sstevel@tonic-gate	pushq	%rbp
6890Sstevel@tonic-gate	movq	%rsp, %rbp
6900Sstevel@tonic-gate	subq	$0x10, %rsp		/* make some temporary space */
6913446Smrj	CLTS
6923446Smrj	stmxcsr	(%rsp)
6930Sstevel@tonic-gate	movl	(%rsp), %eax
6940Sstevel@tonic-gate	andl	$_BITNOT(SSE_MXCSR_EFLAGS), (%rsp)
6950Sstevel@tonic-gate	ldmxcsr	(%rsp)			/* clear processor exceptions */
6960Sstevel@tonic-gate	leave
6970Sstevel@tonic-gate	ret
6980Sstevel@tonic-gate	SET_SIZE(fpxerr_reset)
6990Sstevel@tonic-gate
7000Sstevel@tonic-gate#elif defined(__i386)
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate	ENTRY_NP(fperr_reset)
7033446Smrj	CLTS
7040Sstevel@tonic-gate	xorl	%eax, %eax
7053446Smrj	fnstsw	%ax
7063446Smrj	fnclex
7070Sstevel@tonic-gate	ret
7080Sstevel@tonic-gate	SET_SIZE(fperr_reset)
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate	ENTRY_NP(fpxerr_reset)
7113446Smrj	CLTS
7123446Smrj	subl	$4, %esp		/* make some temporary space */
7133446Smrj	stmxcsr	(%esp)
7140Sstevel@tonic-gate	movl	(%esp), %eax
7150Sstevel@tonic-gate	andl	$_BITNOT(SSE_MXCSR_EFLAGS), (%esp)
7163446Smrj	ldmxcsr	(%esp)			/* clear processor exceptions */
7170Sstevel@tonic-gate	addl	$4, %esp
7180Sstevel@tonic-gate	ret
7190Sstevel@tonic-gate	SET_SIZE(fpxerr_reset)
7200Sstevel@tonic-gate
7210Sstevel@tonic-gate#endif	/* __i386 */
7220Sstevel@tonic-gate#endif	/* __lint */
7230Sstevel@tonic-gate
7240Sstevel@tonic-gate#if defined(__lint)
7250Sstevel@tonic-gate
7260Sstevel@tonic-gateuint32_t
7270Sstevel@tonic-gatefpgetcwsw(void)
7280Sstevel@tonic-gate{
7290Sstevel@tonic-gate	return (0);
7300Sstevel@tonic-gate}
7310Sstevel@tonic-gate
7320Sstevel@tonic-gate#else   /* __lint */
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate#if defined(__amd64)
7350Sstevel@tonic-gate
7360Sstevel@tonic-gate	ENTRY_NP(fpgetcwsw)
7370Sstevel@tonic-gate	pushq	%rbp
7380Sstevel@tonic-gate	movq	%rsp, %rbp
7390Sstevel@tonic-gate	subq	$0x10, %rsp		/* make some temporary space	*/
7403446Smrj	CLTS
7410Sstevel@tonic-gate	fnstsw	(%rsp)			/* store the status word	*/
7420Sstevel@tonic-gate	fnstcw	2(%rsp)			/* store the control word	*/
7430Sstevel@tonic-gate	movl	(%rsp), %eax		/* put both in %eax		*/
7440Sstevel@tonic-gate	leave
7450Sstevel@tonic-gate	ret
7460Sstevel@tonic-gate	SET_SIZE(fpgetcwsw)
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate#elif defined(__i386)
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate	ENTRY_NP(fpgetcwsw)
7513446Smrj	CLTS
7520Sstevel@tonic-gate	subl	$4, %esp		/* make some temporary space	*/
7530Sstevel@tonic-gate	fnstsw	(%esp)			/* store the status word	*/
7540Sstevel@tonic-gate	fnstcw	2(%esp)			/* store the control word	*/
7550Sstevel@tonic-gate	movl	(%esp), %eax		/* put both in %eax		*/
7560Sstevel@tonic-gate	addl	$4, %esp
7570Sstevel@tonic-gate	ret
7580Sstevel@tonic-gate	SET_SIZE(fpgetcwsw)
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate#endif	/* __i386 */
7610Sstevel@tonic-gate#endif  /* __lint */
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate/*
7640Sstevel@tonic-gate * Returns the MXCSR register.
7650Sstevel@tonic-gate */
7660Sstevel@tonic-gate
7670Sstevel@tonic-gate#if defined(__lint)
7680Sstevel@tonic-gate
7690Sstevel@tonic-gateuint32_t
7700Sstevel@tonic-gatefpgetmxcsr(void)
7710Sstevel@tonic-gate{
7720Sstevel@tonic-gate	return (0);
7730Sstevel@tonic-gate}
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate#else   /* __lint */
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate#if defined(__amd64)
7780Sstevel@tonic-gate
7790Sstevel@tonic-gate	ENTRY_NP(fpgetmxcsr)
7800Sstevel@tonic-gate	pushq	%rbp
7810Sstevel@tonic-gate	movq	%rsp, %rbp
7823446Smrj	subq	$0x10, %rsp		/* make some temporary space */
7833446Smrj	CLTS
7843446Smrj	stmxcsr	(%rsp)
7850Sstevel@tonic-gate	movl	(%rsp), %eax
7860Sstevel@tonic-gate	leave
7870Sstevel@tonic-gate	ret
7880Sstevel@tonic-gate	SET_SIZE(fpgetmxcsr)
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate#elif defined(__i386)
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate	ENTRY_NP(fpgetmxcsr)
7933446Smrj	CLTS
7943446Smrj	subl	$4, %esp		/* make some temporary space */
7953446Smrj	stmxcsr	(%esp)
7960Sstevel@tonic-gate	movl	(%esp), %eax
7970Sstevel@tonic-gate	addl	$4, %esp
7980Sstevel@tonic-gate	ret
7990Sstevel@tonic-gate	SET_SIZE(fpgetmxcsr)
8000Sstevel@tonic-gate
8010Sstevel@tonic-gate#endif	/* __i386 */
8020Sstevel@tonic-gate#endif  /* __lint */
803