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