Merge tag 'ide-pull-request' of https://gitlab.com/jsnow/qemu into staging
[qemu.git] / target / i386 / xsave_helper.c
1 /*
2 * This work is licensed under the terms of the GNU GPL, version 2 or later.
3 * See the COPYING file in the top-level directory.
4 */
5 #include "qemu/osdep.h"
6
7 #include "cpu.h"
8
9 void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
10 {
11 CPUX86State *env = &cpu->env;
12 X86XSaveArea *xsave = buf;
13
14 uint16_t cwd, swd, twd;
15 int i;
16 memset(xsave, 0, sizeof(X86XSaveArea));
17 twd = 0;
18 swd = env->fpus & ~(7 << 11);
19 swd |= (env->fpstt & 7) << 11;
20 cwd = env->fpuc;
21 for (i = 0; i < 8; ++i) {
22 twd |= (!env->fptags[i]) << i;
23 }
24 xsave->legacy.fcw = cwd;
25 xsave->legacy.fsw = swd;
26 xsave->legacy.ftw = twd;
27 xsave->legacy.fpop = env->fpop;
28 xsave->legacy.fpip = env->fpip;
29 xsave->legacy.fpdp = env->fpdp;
30 memcpy(&xsave->legacy.fpregs, env->fpregs,
31 sizeof env->fpregs);
32 xsave->legacy.mxcsr = env->mxcsr;
33 xsave->header.xstate_bv = env->xstate_bv;
34 memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs,
35 sizeof env->bnd_regs);
36 xsave->bndcsr_state.bndcsr = env->bndcs_regs;
37 memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs,
38 sizeof env->opmask_regs);
39
40 for (i = 0; i < CPU_NB_REGS; i++) {
41 uint8_t *xmm = xsave->legacy.xmm_regs[i];
42 uint8_t *ymmh = xsave->avx_state.ymmh[i];
43 uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
44 stq_p(xmm, env->xmm_regs[i].ZMM_Q(0));
45 stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1));
46 stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2));
47 stq_p(ymmh+8, env->xmm_regs[i].ZMM_Q(3));
48 stq_p(zmmh, env->xmm_regs[i].ZMM_Q(4));
49 stq_p(zmmh+8, env->xmm_regs[i].ZMM_Q(5));
50 stq_p(zmmh+16, env->xmm_regs[i].ZMM_Q(6));
51 stq_p(zmmh+24, env->xmm_regs[i].ZMM_Q(7));
52 }
53
54 #ifdef TARGET_X86_64
55 memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
56 16 * sizeof env->xmm_regs[16]);
57 memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
58 #endif
59
60 }
61
62 void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
63 {
64
65 CPUX86State *env = &cpu->env;
66 const X86XSaveArea *xsave = buf;
67
68 int i;
69 uint16_t cwd, swd, twd;
70 cwd = xsave->legacy.fcw;
71 swd = xsave->legacy.fsw;
72 twd = xsave->legacy.ftw;
73 env->fpop = xsave->legacy.fpop;
74 env->fpstt = (swd >> 11) & 7;
75 env->fpus = swd;
76 env->fpuc = cwd;
77 for (i = 0; i < 8; ++i) {
78 env->fptags[i] = !((twd >> i) & 1);
79 }
80 env->fpip = xsave->legacy.fpip;
81 env->fpdp = xsave->legacy.fpdp;
82 env->mxcsr = xsave->legacy.mxcsr;
83 memcpy(env->fpregs, &xsave->legacy.fpregs,
84 sizeof env->fpregs);
85 env->xstate_bv = xsave->header.xstate_bv;
86 memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs,
87 sizeof env->bnd_regs);
88 env->bndcs_regs = xsave->bndcsr_state.bndcsr;
89 memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs,
90 sizeof env->opmask_regs);
91
92 for (i = 0; i < CPU_NB_REGS; i++) {
93 const uint8_t *xmm = xsave->legacy.xmm_regs[i];
94 const uint8_t *ymmh = xsave->avx_state.ymmh[i];
95 const uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
96 env->xmm_regs[i].ZMM_Q(0) = ldq_p(xmm);
97 env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8);
98 env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh);
99 env->xmm_regs[i].ZMM_Q(3) = ldq_p(ymmh+8);
100 env->xmm_regs[i].ZMM_Q(4) = ldq_p(zmmh);
101 env->xmm_regs[i].ZMM_Q(5) = ldq_p(zmmh+8);
102 env->xmm_regs[i].ZMM_Q(6) = ldq_p(zmmh+16);
103 env->xmm_regs[i].ZMM_Q(7) = ldq_p(zmmh+24);
104 }
105
106 #ifdef TARGET_X86_64
107 memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm,
108 16 * sizeof env->xmm_regs[16]);
109 memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
110 #endif
111
112 }