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_asm64.s" 17 18/* 19 * Test utility routines that we need assembler for. 64-bit addition. 20 */ 21 22#include <sys/asm_linkage.h> 23#include "xsave_util.h" 24 25#define GET_FPU_XMM(src, i) \ 26 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 27 movdqu %xmm##i, (%rax) 28 29#define GET_FPU_YMM(src, i) \ 30 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 31 vmovdqu %ymm##i, (%rax) 32 33#define GET_FPU_ZMM(src, i) \ 34 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 35 vmovdqu64 %zmm##i, (%rax) 36 37#define GET_MASK(src, i) \ 38 leaq (0x800 + i * 8)(src), %rax; \ 39 kmovq %k##i, (%rax) 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 cmpl $XSU_XMM, %esi 49 je get_xmm 50 cmpl $XSU_YMM, %esi 51 je get_ymm 52 cmpl $XSU_ZMM, %esi 53 je get_zmm 54 call abort 55get_xmm: 56 GET_FPU_XMM(%rdi, 0) 57 GET_FPU_XMM(%rdi, 1) 58 GET_FPU_XMM(%rdi, 2) 59 GET_FPU_XMM(%rdi, 3) 60 GET_FPU_XMM(%rdi, 4) 61 GET_FPU_XMM(%rdi, 5) 62 GET_FPU_XMM(%rdi, 6) 63 GET_FPU_XMM(%rdi, 7) 64 GET_FPU_XMM(%rdi, 8) 65 GET_FPU_XMM(%rdi, 9) 66 GET_FPU_XMM(%rdi, 10) 67 GET_FPU_XMM(%rdi, 11) 68 GET_FPU_XMM(%rdi, 12) 69 GET_FPU_XMM(%rdi, 13) 70 GET_FPU_XMM(%rdi, 14) 71 GET_FPU_XMM(%rdi, 15) 72 jmp get_done 73get_ymm: 74 GET_FPU_YMM(%rdi, 0) 75 GET_FPU_YMM(%rdi, 1) 76 GET_FPU_YMM(%rdi, 2) 77 GET_FPU_YMM(%rdi, 3) 78 GET_FPU_YMM(%rdi, 4) 79 GET_FPU_YMM(%rdi, 5) 80 GET_FPU_YMM(%rdi, 6) 81 GET_FPU_YMM(%rdi, 7) 82 GET_FPU_YMM(%rdi, 8) 83 GET_FPU_YMM(%rdi, 9) 84 GET_FPU_YMM(%rdi, 10) 85 GET_FPU_YMM(%rdi, 11) 86 GET_FPU_YMM(%rdi, 12) 87 GET_FPU_YMM(%rdi, 13) 88 GET_FPU_YMM(%rdi, 14) 89 GET_FPU_YMM(%rdi, 15) 90 jmp get_done 91get_zmm: 92 GET_FPU_ZMM(%rdi, 0) 93 GET_FPU_ZMM(%rdi, 1) 94 GET_FPU_ZMM(%rdi, 2) 95 GET_FPU_ZMM(%rdi, 3) 96 GET_FPU_ZMM(%rdi, 4) 97 GET_FPU_ZMM(%rdi, 5) 98 GET_FPU_ZMM(%rdi, 6) 99 GET_FPU_ZMM(%rdi, 7) 100 GET_FPU_ZMM(%rdi, 8) 101 GET_FPU_ZMM(%rdi, 9) 102 GET_FPU_ZMM(%rdi, 10) 103 GET_FPU_ZMM(%rdi, 11) 104 GET_FPU_ZMM(%rdi, 12) 105 GET_FPU_ZMM(%rdi, 13) 106 GET_FPU_ZMM(%rdi, 14) 107 GET_FPU_ZMM(%rdi, 15) 108 GET_FPU_ZMM(%rdi, 16) 109 GET_FPU_ZMM(%rdi, 17) 110 GET_FPU_ZMM(%rdi, 18) 111 GET_FPU_ZMM(%rdi, 19) 112 GET_FPU_ZMM(%rdi, 20) 113 GET_FPU_ZMM(%rdi, 21) 114 GET_FPU_ZMM(%rdi, 22) 115 GET_FPU_ZMM(%rdi, 23) 116 GET_FPU_ZMM(%rdi, 24) 117 GET_FPU_ZMM(%rdi, 25) 118 GET_FPU_ZMM(%rdi, 25) 119 GET_FPU_ZMM(%rdi, 26) 120 GET_FPU_ZMM(%rdi, 27) 121 GET_FPU_ZMM(%rdi, 28) 122 GET_FPU_ZMM(%rdi, 29) 123 GET_FPU_ZMM(%rdi, 30) 124 GET_FPU_ZMM(%rdi, 31) 125 GET_MASK(%rdi, 0) 126 GET_MASK(%rdi, 1) 127 GET_MASK(%rdi, 2) 128 GET_MASK(%rdi, 3) 129 GET_MASK(%rdi, 4) 130 GET_MASK(%rdi, 5) 131 GET_MASK(%rdi, 6) 132 GET_MASK(%rdi, 7) 133get_done: 134 ret 135 SET_SIZE(xsu_getfpu) 136 137#define SET_FPU_XMM(src, i) \ 138 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 139 movdqu (%rax), %xmm##i 140 141#define SET_FPU_YMM(src, i) \ 142 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 143 vmovdqu (%rax), %ymm##i 144 145#define SET_FPU_ZMM(src, i) \ 146 leaq (i * XSU_ZMM_U32 * 4)(src), %rax; \ 147 vmovdqu64 (%rax), %zmm##i 148 149#define SET_MASK(src, i) \ 150 leaq (0x800 + i * 8)(src), %rax; \ 151 kmovq (%rax), %k##i 152 153 /* 154 * void xsu_setfpu(const xsu_fpu_t *data, uint32_t type) 155 * 156 * Our job is to override the contents of the FPU with this structure 157 * that we've been given. The type indicates how much of it to use. 158 */ 159 ENTRY(xsu_setfpu) 160 cmpl $XSU_XMM, %esi 161 je set_xmm 162 cmpl $XSU_YMM, %esi 163 je set_ymm 164 cmpl $XSU_ZMM, %esi 165 je set_zmm 166 call abort 167set_xmm: 168 SET_FPU_XMM(%rdi, 0) 169 SET_FPU_XMM(%rdi, 1) 170 SET_FPU_XMM(%rdi, 2) 171 SET_FPU_XMM(%rdi, 3) 172 SET_FPU_XMM(%rdi, 4) 173 SET_FPU_XMM(%rdi, 5) 174 SET_FPU_XMM(%rdi, 6) 175 SET_FPU_XMM(%rdi, 7) 176 SET_FPU_XMM(%rdi, 8) 177 SET_FPU_XMM(%rdi, 9) 178 SET_FPU_XMM(%rdi, 10) 179 SET_FPU_XMM(%rdi, 11) 180 SET_FPU_XMM(%rdi, 12) 181 SET_FPU_XMM(%rdi, 13) 182 SET_FPU_XMM(%rdi, 14) 183 SET_FPU_XMM(%rdi, 15) 184 jmp set_done 185set_ymm: 186 SET_FPU_YMM(%rdi, 0) 187 SET_FPU_YMM(%rdi, 1) 188 SET_FPU_YMM(%rdi, 2) 189 SET_FPU_YMM(%rdi, 3) 190 SET_FPU_YMM(%rdi, 4) 191 SET_FPU_YMM(%rdi, 5) 192 SET_FPU_YMM(%rdi, 6) 193 SET_FPU_YMM(%rdi, 7) 194 SET_FPU_YMM(%rdi, 8) 195 SET_FPU_YMM(%rdi, 9) 196 SET_FPU_YMM(%rdi, 10) 197 SET_FPU_YMM(%rdi, 11) 198 SET_FPU_YMM(%rdi, 12) 199 SET_FPU_YMM(%rdi, 13) 200 SET_FPU_YMM(%rdi, 14) 201 SET_FPU_YMM(%rdi, 15) 202 jmp set_done 203set_zmm: 204 SET_FPU_ZMM(%rdi, 0) 205 SET_FPU_ZMM(%rdi, 1) 206 SET_FPU_ZMM(%rdi, 2) 207 SET_FPU_ZMM(%rdi, 3) 208 SET_FPU_ZMM(%rdi, 4) 209 SET_FPU_ZMM(%rdi, 5) 210 SET_FPU_ZMM(%rdi, 6) 211 SET_FPU_ZMM(%rdi, 7) 212 SET_FPU_ZMM(%rdi, 8) 213 SET_FPU_ZMM(%rdi, 9) 214 SET_FPU_ZMM(%rdi, 10) 215 SET_FPU_ZMM(%rdi, 11) 216 SET_FPU_ZMM(%rdi, 12) 217 SET_FPU_ZMM(%rdi, 13) 218 SET_FPU_ZMM(%rdi, 14) 219 SET_FPU_ZMM(%rdi, 15) 220 SET_FPU_ZMM(%rdi, 16) 221 SET_FPU_ZMM(%rdi, 17) 222 SET_FPU_ZMM(%rdi, 18) 223 SET_FPU_ZMM(%rdi, 19) 224 SET_FPU_ZMM(%rdi, 20) 225 SET_FPU_ZMM(%rdi, 21) 226 SET_FPU_ZMM(%rdi, 22) 227 SET_FPU_ZMM(%rdi, 23) 228 SET_FPU_ZMM(%rdi, 24) 229 SET_FPU_ZMM(%rdi, 25) 230 SET_FPU_ZMM(%rdi, 25) 231 SET_FPU_ZMM(%rdi, 26) 232 SET_FPU_ZMM(%rdi, 27) 233 SET_FPU_ZMM(%rdi, 28) 234 SET_FPU_ZMM(%rdi, 29) 235 SET_FPU_ZMM(%rdi, 30) 236 SET_FPU_ZMM(%rdi, 31) 237 SET_MASK(%rdi, 0) 238 SET_MASK(%rdi, 1) 239 SET_MASK(%rdi, 2) 240 SET_MASK(%rdi, 3) 241 SET_MASK(%rdi, 4) 242 SET_MASK(%rdi, 5) 243 SET_MASK(%rdi, 6) 244 SET_MASK(%rdi, 7) 245set_done: 246 ret 247 SET_SIZE(xsu_setfpu) 248