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
57 get_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
67 get_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
77 get_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)
94 get_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
130 set_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
140 set_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
150 set_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)
167 set_done:
168 ret
169 SET_SIZE(xsu_setfpu)