xref: /illumos-gate/usr/src/test/os-tests/tests/xsave/xsave_asm32.S (revision f17620a4f72a29025a22655ba8735ccd20ae174f)
1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source.  A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright 2023 Oxide Computer Company
14 */
15
16	.file	"xsave_asm32.s"
17
18/*
19 * Test utility routines that we need assembler for. 32-bit addition.
20 */
21
22#include <sys/asm_linkage.h>
23#include "xsave_util.h"
24
25#define	GET_FPU_XMM(src, i)	\
26	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
27	movdqu	%xmm##i, (%eax)
28
29#define	GET_FPU_YMM(src, i)	\
30	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
31	vmovdqu	%ymm##i, (%eax)
32
33#define	GET_FPU_ZMM(src, i)	\
34	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
35	vmovdqu64	%zmm##i, (%eax)
36
37#define	GET_MASK(src, i)	\
38	leal	(0x800 + i * 8)(src), %eax; \
39	kmovq	%k##i, (%eax)
40
41	/*
42	 * void xsu_getfpu(xsu_fpu_t *data, uint32_t type)
43	 *
44	 * Our job is to get the entire contents of the FPU and save it into our
45	 * data structure.
46	 */
47	ENTRY(xsu_getfpu)
48	movl	8(%esp), %eax
49	movl	4(%esp), %edx
50	cmpl	$XSU_XMM, %eax
51	je	get_xmm
52	cmpl	$XSU_YMM, %eax
53	je	get_ymm
54	cmpl	$XSU_ZMM, %eax
55	je	get_zmm
56	call	abort
57get_xmm:
58	GET_FPU_XMM(%edx, 0)
59	GET_FPU_XMM(%edx, 1)
60	GET_FPU_XMM(%edx, 2)
61	GET_FPU_XMM(%edx, 3)
62	GET_FPU_XMM(%edx, 4)
63	GET_FPU_XMM(%edx, 5)
64	GET_FPU_XMM(%edx, 6)
65	GET_FPU_XMM(%edx, 7)
66	jmp	get_done
67get_ymm:
68	GET_FPU_YMM(%edx, 0)
69	GET_FPU_YMM(%edx, 1)
70	GET_FPU_YMM(%edx, 2)
71	GET_FPU_YMM(%edx, 3)
72	GET_FPU_YMM(%edx, 4)
73	GET_FPU_YMM(%edx, 5)
74	GET_FPU_YMM(%edx, 6)
75	GET_FPU_YMM(%edx, 7)
76	jmp	get_done
77get_zmm:
78	GET_FPU_ZMM(%edx, 0)
79	GET_FPU_ZMM(%edx, 1)
80	GET_FPU_ZMM(%edx, 2)
81	GET_FPU_ZMM(%edx, 3)
82	GET_FPU_ZMM(%edx, 4)
83	GET_FPU_ZMM(%edx, 5)
84	GET_FPU_ZMM(%edx, 6)
85	GET_FPU_ZMM(%edx, 7)
86	GET_MASK(%edx, 0)
87	GET_MASK(%edx, 1)
88	GET_MASK(%edx, 2)
89	GET_MASK(%edx, 3)
90	GET_MASK(%edx, 4)
91	GET_MASK(%edx, 5)
92	GET_MASK(%edx, 6)
93	GET_MASK(%edx, 7)
94get_done:
95	ret
96	SET_SIZE(xsu_getfpu)
97
98#define	SET_FPU_XMM(src, i)	\
99	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
100	movdqu	(%eax), %xmm##i
101
102#define	SET_FPU_YMM(src, i)	\
103	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
104	vmovdqu	(%eax), %ymm##i
105
106#define	SET_FPU_ZMM(src, i)	\
107	leal	(i * XSU_ZMM_U32 * 4)(src), %eax; \
108	vmovdqu64	(%eax), %zmm##i
109
110#define	SET_MASK(src, i)	\
111	leal	(0x800 + i * 8)(src), %eax; \
112	kmovq	(%eax), %k##i
113
114	/*
115	 * void xsu_setfpu(const xsu_fpu_t *data, uint32_t type)
116	 *
117	 * Our job is to override the contents of the FPU with this structure
118	 * that we've been given. The type indicates how much of it to use.
119	 */
120	ENTRY(xsu_setfpu)
121	movl	8(%esp), %eax
122	movl	4(%esp), %edx
123	cmpl	$XSU_XMM, %eax
124	je	set_xmm
125	cmpl	$XSU_YMM, %eax
126	je	set_ymm
127	cmpl	$XSU_ZMM, %eax
128	je	set_zmm
129	call	abort
130set_xmm:
131	SET_FPU_XMM(%edx, 0)
132	SET_FPU_XMM(%edx, 1)
133	SET_FPU_XMM(%edx, 2)
134	SET_FPU_XMM(%edx, 3)
135	SET_FPU_XMM(%edx, 4)
136	SET_FPU_XMM(%edx, 5)
137	SET_FPU_XMM(%edx, 6)
138	SET_FPU_XMM(%edx, 7)
139	jmp	set_done
140set_ymm:
141	SET_FPU_YMM(%edx, 0)
142	SET_FPU_YMM(%edx, 1)
143	SET_FPU_YMM(%edx, 2)
144	SET_FPU_YMM(%edx, 3)
145	SET_FPU_YMM(%edx, 4)
146	SET_FPU_YMM(%edx, 5)
147	SET_FPU_YMM(%edx, 6)
148	SET_FPU_YMM(%edx, 7)
149	jmp	set_done
150set_zmm:
151	SET_FPU_ZMM(%edx, 0)
152	SET_FPU_ZMM(%edx, 1)
153	SET_FPU_ZMM(%edx, 2)
154	SET_FPU_ZMM(%edx, 3)
155	SET_FPU_ZMM(%edx, 4)
156	SET_FPU_ZMM(%edx, 5)
157	SET_FPU_ZMM(%edx, 6)
158	SET_FPU_ZMM(%edx, 7)
159	SET_MASK(%edx, 0)
160	SET_MASK(%edx, 1)
161	SET_MASK(%edx, 2)
162	SET_MASK(%edx, 3)
163	SET_MASK(%edx, 4)
164	SET_MASK(%edx, 5)
165	SET_MASK(%edx, 6)
166	SET_MASK(%edx, 7)
167set_done:
168	ret
169	SET_SIZE(xsu_setfpu)
170