xref: /openbsd/lib/libc/arch/amd64/gen/fpsetround.S (revision 274d7c50)
1/*	$OpenBSD: fpsetround.S,v 1.3 2018/07/03 23:14:05 mortimer Exp $	*/
2/*	$NetBSD: fpsetround.S,v 1.3 2002/06/12 19:17:22 fvdl Exp $	*/
3
4/*
5 * Written by Frank van der Linden at Wasabi Systems for NetBSD.
6 * Public domain.
7 */
8
9#include <machine/asm.h>
10
11/*
12 * XXX set both the x87 control word and the SSE mxcsr register.
13 * Applications should only set exception and round flags
14 * via the fp*() interface, otherwise the status words
15 * will get our of sync.
16 */
17
18
19#ifdef WEAK_ALIAS
20WEAK_ALIAS(fpsetround, _fpsetround)
21ENTRY(_fpsetround)
22#else
23ENTRY(fpsetround)
24#endif
25	RETGUARD_SETUP(fpsetround, r11)
26	fnstcw	-4(%rsp)
27	stmxcsr	-8(%rsp)
28
29	andl	$3,%edi
30
31	movl	-4(%rsp),%edx
32	rorl	$10,%edx
33	movl	%edx,%eax
34	andl	$3,%eax
35
36	andl	$~3,%edx
37	orl	%edi,%edx
38	roll	$10,%edx
39	movl	%edx,-4(%rsp)
40
41	movl	-8(%rsp),%edx
42	rorl	$13,%edx
43	andl	$~3,%edx
44	orl	%edi,%edx
45	roll	$13,%edx
46	movl	%edx,-8(%rsp)
47
48	ldmxcsr	-8(%rsp)
49	fldcw	-4(%rsp)
50	RETGUARD_CHECK(fpsetround, r11)
51	ret
52#ifdef WEAK_ALIAS
53END(_fpsetround)
54#else
55END(fpsetround)
56#endif
57