target-i386: make xmm_regs 512-bit wide

Right now, the AVX512 registers are split in many different fields:
xmm_regs for the low 128 bits of the first 16 registers, ymmh_regs
for the next 128 bits of the same first 16 registers, zmmh_regs
for the next 256 bits of the same first 16 registers, and finally
hi16_zmm_regs for the full 512 bits of the second 16 bit registers.

This makes it simple to move data in and out of the xsave region,
but would be a nightmare for a hypothetical TCG implementation and
leads to a proliferation of [XYZ]MM_[BWLSQD] macros. Instead,
this patch marshals data manually from the xsave region to a single
32x512-bit array, simplifying the macro jungle and clarifying which
bits are in which vmstate subsection.

The migration format is unaffected.

Backports commit b7711471f551aa4419f9d46a11121f48ced422da from qemu
This commit is contained in:
Paolo Bonzini 2018-02-12 12:08:32 -05:00 committed by Lioncash
parent 73fa78f0bc
commit 5b02b2728a
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 22 additions and 80 deletions

View file

@ -704,24 +704,6 @@ typedef struct SegmentCache {
uint32_t flags;
} SegmentCache;
typedef union {
uint8_t _b[16];
uint16_t _w[8];
uint32_t _l[4];
uint64_t _q[2];
float32 _s[4];
float64 _d[2];
} XMMReg;
typedef union {
uint8_t _b[32];
uint16_t _w[16];
uint32_t _l[8];
uint64_t _q[4];
float32 _s[8];
float64 _d[4];
} YMMReg;
typedef union {
uint8_t _b[64];
uint16_t _w[32];
@ -729,7 +711,7 @@ typedef union {
uint64_t _q[8];
float32 _s[16];
float64 _d[8];
} ZMMReg;
} XMMReg; /* really zmm */
typedef union {
uint8_t _b[8];
@ -750,46 +732,18 @@ typedef struct BNDCSReg {
} BNDCSReg;
#ifdef HOST_WORDS_BIGENDIAN
#define ZMM_B(n) _b[63 - (n)]
#define ZMM_W(n) _w[31 - (n)]
#define ZMM_L(n) _l[15 - (n)]
#define ZMM_S(n) _s[15 - (n)]
#define ZMM_Q(n) _q[7 - (n)]
#define ZMM_D(n) _d[7 - (n)]
#define YMM_B(n) _b[31 - (n)]
#define YMM_W(n) _w[15 - (n)]
#define YMM_L(n) _l[7 - (n)]
#define YMM_S(n) _s[7 - (n)]
#define YMM_Q(n) _q[3 - (n)]
#define YMM_D(n) _d[3 - (n)]
#define XMM_B(n) _b[15 - (n)]
#define XMM_W(n) _w[7 - (n)]
#define XMM_L(n) _l[3 - (n)]
#define XMM_S(n) _s[3 - (n)]
#define XMM_Q(n) _q[1 - (n)]
#define XMM_D(n) _d[1 - (n)]
#define XMM_B(n) _b[63 - (n)]
#define XMM_W(n) _w[31 - (n)]
#define XMM_L(n) _l[15 - (n)]
#define XMM_S(n) _s[15 - (n)]
#define XMM_Q(n) _q[7 - (n)]
#define XMM_D(n) _d[7 - (n)]
#define MMX_B(n) _b[7 - (n)]
#define MMX_W(n) _w[3 - (n)]
#define MMX_L(n) _l[1 - (n)]
#define MMX_S(n) _s[1 - (n)]
#else
#define ZMM_B(n) _b[n]
#define ZMM_W(n) _w[n]
#define ZMM_L(n) _l[n]
#define ZMM_S(n) _s[n]
#define ZMM_Q(n) _q[n]
#define ZMM_D(n) _d[n]
#define YMM_B(n) _b[n]
#define YMM_W(n) _w[n]
#define YMM_L(n) _l[n]
#define YMM_S(n) _s[n]
#define YMM_Q(n) _q[n]
#define YMM_D(n) _d[n]
#define XMM_B(n) _b[n]
#define XMM_W(n) _w[n]
#define XMM_L(n) _l[n]
@ -890,17 +844,11 @@ typedef struct CPUX86State {
float_status mmx_status; /* for 3DNow! float ops */
float_status sse_status;
uint32_t mxcsr;
XMMReg xmm_regs[CPU_NB_REGS];
XMMReg xmm_regs[CPU_NB_REGS == 8 ? 8 : 32];
XMMReg xmm_t0;
MMXReg mmx_t0;
XMMReg ymmh_regs[CPU_NB_REGS];
uint64_t opmask_regs[NB_OPMASK_REGS];
YMMReg zmmh_regs[CPU_NB_REGS];
#ifdef TARGET_X86_64
ZMMReg hi16_zmm_regs[CPU_NB_REGS];
#endif
/* sysenter registers */
uint32_t sysenter_cs;

View file

@ -89,10 +89,7 @@ void x86_reg_reset(struct uc_struct *uc)
memset(&env->xmm_t0, 0, sizeof(env->xmm_t0));
memset(&env->mmx_t0, 0, sizeof(env->mmx_t0));
memset(env->ymmh_regs, 0, sizeof(env->ymmh_regs));
memset(env->opmask_regs, 0, sizeof(env->opmask_regs));
memset(env->zmmh_regs, 0, sizeof(env->zmmh_regs));
/* sysenter registers */
env->sysenter_cs = 0;
@ -120,7 +117,6 @@ void x86_reg_reset(struct uc_struct *uc)
memset(env->msr_gp_evtsel, 0, sizeof(env->msr_gp_evtsel));
#ifdef TARGET_X86_64
memset(env->hi16_zmm_regs, 0, sizeof(env->hi16_zmm_regs));
env->lstar = 0;
env->cstar = 0;
env->fmask = 0;
@ -280,8 +276,8 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
{
float64 *dst = (float64*)value;
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
dst[0] = reg->_d[0];
dst[1] = reg->_d[1];
dst[0] = reg->XMM_D(0);
dst[1] = reg->XMM_D(1);
continue;
}
case UC_X86_REG_YMM0:
@ -294,12 +290,11 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
case UC_X86_REG_YMM7:
{
float64 *dst = (float64*)value;
XMMReg *lo_reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_YMM0];
XMMReg *hi_reg = &X86_CPU(uc, mycpu)->env.ymmh_regs[regid - UC_X86_REG_YMM0];
dst[0] = lo_reg->_d[0];
dst[1] = lo_reg->_d[1];
dst[2] = hi_reg->_d[0];
dst[3] = hi_reg->_d[1];
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
dst[0] = reg->XMM_D(0);
dst[1] = reg->XMM_D(1);
dst[2] = reg->XMM_D(2);
dst[3] = reg->XMM_D(3);
continue;
}
}
@ -819,8 +814,8 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
{
float64 *src = (float64*)value;
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
reg->_d[0] = src[0];
reg->_d[1] = src[1];
reg->XMM_D(0) = src[0];
reg->XMM_D(1) = src[1];
continue;
}
case UC_X86_REG_YMM0:
@ -833,12 +828,11 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
case UC_X86_REG_YMM7:
{
float64 *src = (float64*)value;
XMMReg *lo_reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_YMM0];
XMMReg *hi_reg = &X86_CPU(uc, mycpu)->env.ymmh_regs[regid - UC_X86_REG_YMM0];
lo_reg->_d[0] = src[0];
lo_reg->_d[1] = src[1];
hi_reg->_d[0] = src[2];
hi_reg->_d[1] = src[3];
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
reg->XMM_D(4) = src[0];
reg->XMM_D(5) = src[1];
reg->XMM_D(6) = src[2];
reg->XMM_D(7) = src[3];
continue;
}
}