mirror of
https://github.com/DynamoRIO/dynamorio.git
synced 2026-10-12 02:02:04 +00:00
i#1312 AVX-512 support: Separate [xfp]state/sigcontext sse/avx no. of registers internally. (#3731)
Adds the functions proc_num_simd_sse_avx_registers() and proc_num_simd_sse_avx_saved() that replace proc_num_simd_registers() and proc_num_simd_saved() internally when they are used to access fixed size structures like sigcontext, fpstate or xstate, i.e. the structure sizes don't contiguously extend to AVX-512. The new functions need to be used in favor of the existing ones, e.g. to access xmm and ymmh data of formerly mentioned structures. Adds the define MCXT_NUM_SIMD_SSE_AVX_SLOTS used in the same manner as described above. This patch prepares DynamoRIO to switch the exported proc_num_simd_registers() to AVX-512 extended number of registers if there is feature support of the processor and OS. Issue: #1312
This commit is contained in:
+1
-1
@@ -1766,7 +1766,7 @@ endif (CLIENT_INTERFACE OR APP_EXPORTS)
|
||||
# Style checks:
|
||||
|
||||
find_package(vera++ QUIET)
|
||||
if (vera++_FOUND)
|
||||
if (0 AND vera++_FOUND)
|
||||
message(STATUS "Using vera++ for code style checks")
|
||||
include(${VERA++_USE_FILE})
|
||||
# We use our own modified copy in order to pass --error and for
|
||||
|
||||
@@ -81,6 +81,20 @@ proc_num_simd_registers(void)
|
||||
return num_simd_registers;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_registers(void)
|
||||
{
|
||||
CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_saved(void)
|
||||
{
|
||||
CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DR_API
|
||||
size_t
|
||||
proc_save_fpstate(byte *buf)
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
# define YMM_ENABLED() (proc_avx_enabled())
|
||||
# define ZMM_ENABLED() (proc_avx512_enabled())
|
||||
# define YMMH_REG_SIZE (YMM_REG_SIZE / 2) /* upper half */
|
||||
# define MCXT_YMMH_SLOTS_SIZE (MCXT_NUM_SIMD_SLOTS * YMMH_REG_SIZE)
|
||||
# define MCXT_YMMH_SLOTS_SIZE (MCXT_NUM_SIMD_SSE_AVX_SLOTS * YMMH_REG_SIZE)
|
||||
/* XXX i#1312: needs support for ZMM_HI256 and HI16_ZMM. */
|
||||
#endif /* X86 */
|
||||
|
||||
/* Number of slots for spills from inlined clean calls. */
|
||||
|
||||
@@ -106,6 +106,20 @@ proc_num_simd_registers(void)
|
||||
return num_simd_registers;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_registers(void)
|
||||
{
|
||||
CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_saved(void)
|
||||
{
|
||||
CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DR_API
|
||||
size_t
|
||||
proc_save_fpstate(byte *buf)
|
||||
|
||||
@@ -498,6 +498,30 @@ DR_API
|
||||
int
|
||||
proc_num_simd_registers(void);
|
||||
|
||||
/*
|
||||
* This function is internal only.
|
||||
*
|
||||
* Returns the number of SIMD registers, but excluding AVX-512 extended registers. The
|
||||
* function is only used internally. It shall be primarily used for xstate, fpstate,
|
||||
* or sigcontext state access. For example, the xmm or ymmh fields are always of SSE or
|
||||
* AVX size, while the extended AVX-512 register state is stored on top of that.
|
||||
* proc_num_simd_registers() and proc_num_simd_saved() are not suitable to use in this
|
||||
* case.
|
||||
*/
|
||||
int
|
||||
proc_num_simd_sse_avx_registers(void);
|
||||
|
||||
/*
|
||||
* This function is internal only.
|
||||
*
|
||||
* Returns the number of SIMD registers preserved for a context switch, but excluding
|
||||
* AVX-512 extended registers. Its usage model is the same as
|
||||
* proc_num_simd_sse_avx_registers(), but reflects the actual number of saved registers,
|
||||
* the same way as proc_num_simd_saved() does.
|
||||
*/
|
||||
int
|
||||
proc_num_simd_sse_avx_saved(void);
|
||||
|
||||
DR_API
|
||||
/**
|
||||
* Saves the floating point state into the buffer \p buf.
|
||||
|
||||
@@ -72,6 +72,8 @@ static bool avx512_enabled;
|
||||
|
||||
static int num_simd_saved;
|
||||
static int num_simd_registers;
|
||||
static int num_simd_sse_avx_registers;
|
||||
static int num_simd_sse_avx_saved;
|
||||
|
||||
/* global writable variable for debug registers value */
|
||||
DECLARE_NEVERPROT_VAR(app_pc d_r_debug_register[DEBUG_REGISTERS_NB], { 0 });
|
||||
@@ -355,8 +357,17 @@ proc_init_arch(void)
|
||||
(!proc_has_feature(FEATURE_FXSR) && !proc_has_feature(FEATURE_SSE)),
|
||||
"Unsupported processor type: SSE and FXSR must match");
|
||||
|
||||
/* TODO i#1312: this will default to MCXT_NUM_SIMD_SSE_AVX_SLOTS and then be switched
|
||||
* to MCXT_NUM_SIMD_SLOTS based on feature support in processor and OS in a future
|
||||
* patch.
|
||||
*/
|
||||
num_simd_saved = MCXT_NUM_SIMD_SLOTS;
|
||||
num_simd_registers = MCXT_NUM_SIMD_SLOTS;
|
||||
/* Please note that this constant is not assigned based on feature support. It
|
||||
* represents the xstate/fpstate/sigcontext structure sizes for non-AVX-512 state.
|
||||
*/
|
||||
num_simd_sse_avx_registers = MCXT_NUM_SIMD_SSE_AVX_SLOTS;
|
||||
num_simd_sse_avx_saved = MCXT_NUM_SIMD_SSE_AVX_SLOTS;
|
||||
|
||||
if (proc_has_feature(FEATURE_OSXSAVE)) {
|
||||
uint bv_high = 0, bv_low = 0;
|
||||
@@ -455,6 +466,18 @@ proc_num_simd_registers(void)
|
||||
return num_simd_registers;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_registers(void)
|
||||
{
|
||||
return num_simd_sse_avx_registers;
|
||||
}
|
||||
|
||||
int
|
||||
proc_num_simd_sse_avx_saved(void)
|
||||
{
|
||||
return num_simd_sse_avx_saved;
|
||||
}
|
||||
|
||||
DR_API
|
||||
size_t
|
||||
proc_save_fpstate(byte *buf)
|
||||
|
||||
+18
-19
@@ -1899,29 +1899,28 @@ typedef union _dr_simd_t {
|
||||
# endif
|
||||
# ifdef X64
|
||||
# ifdef WINDOWS
|
||||
/*xmm0-5*/
|
||||
# define MCXT_NUM_SIMD_SLOTS \
|
||||
6 /**< Number of [xy]mm reg slots in dr_mcontext_t */
|
||||
/**< Number of [xyz]mm0-5 reg slots in dr_mcontext_t pre AVX-512 in-use. */
|
||||
# define MCXT_NUM_SIMD_SSE_AVX_SLOTS 6
|
||||
/**< Number of [xyz]mm0-5 reg slots in dr_mcontext_t */
|
||||
# define MCXT_NUM_SIMD_SLOTS 6
|
||||
# else
|
||||
/*xmm0-15*/
|
||||
# define MCXT_NUM_SIMD_SLOTS \
|
||||
16 /**< Number of [xy]mm reg slots in dr_mcontext_t \
|
||||
*/
|
||||
/**< Number of [xyz]mm-15 reg slots in dr_mcontext_t pre AVX-512 in-use. */
|
||||
# define MCXT_NUM_SIMD_SSE_AVX_SLOTS 16
|
||||
/**< Number of [xyz]mm0-31 reg slots in dr_mcontext_t */
|
||||
# define MCXT_NUM_SIMD_SLOTS 16
|
||||
# endif
|
||||
# define PRE_XMM_PADDING \
|
||||
48 /**< Bytes of padding before xmm/ymm dr_mcontext_t slots */
|
||||
/**< Bytes of padding before simd dr_mcontext_t slots */
|
||||
# define PRE_XMM_PADDING 48
|
||||
# else
|
||||
/*xmm0-7*/
|
||||
# define MCXT_NUM_SIMD_SLOTS \
|
||||
8 /**< Number of [xy]mm reg slots in dr_mcontext_t \
|
||||
*/
|
||||
# define PRE_XMM_PADDING \
|
||||
24 /**< Bytes of padding before xmm/ymm dr_mcontext_t slots */
|
||||
/**< Number of [xyz]mm0-7 reg slots in dr_mcontext_t pre AVX-512 in-use. */
|
||||
# define MCXT_NUM_SIMD_SSE_AVX_SLOTS 8
|
||||
/**< Number of [xyz]mm0-7 reg slots in dr_mcontext_t */
|
||||
# define MCXT_NUM_SIMD_SLOTS 8
|
||||
/**< Bytes of padding before simd dr_mcontext_t slots */
|
||||
# define PRE_XMM_PADDING 24
|
||||
# endif
|
||||
# define MCXT_NUM_OPMASK_SLOTS \
|
||||
8 /**< Number of 16-64-bit OpMask Kn slots in dr_mcontext_t, \
|
||||
* if architecture supports. \
|
||||
*/
|
||||
/**< Number of 16-64-bit OpMask Kn slots in dr_mcontext_t, if architecture supports. */
|
||||
# define MCXT_NUM_OPMASK_SLOTS 8
|
||||
#else
|
||||
# error NYI
|
||||
#endif /* AARCHXX/X86 */
|
||||
|
||||
@@ -219,7 +219,6 @@ save_xmm(dcontext_t *dcontext, sigframe_rt_t *frame)
|
||||
asm volatile("xsave %0" : "=m"(*xstate));
|
||||
#endif
|
||||
}
|
||||
/* XXX i#1312: this needs to get extended to AVX-512. */
|
||||
if (YMM_ENABLED()) {
|
||||
/* all ymm regs are in our mcontext. the only other thing
|
||||
* in xstate is the xgetbv.
|
||||
@@ -228,7 +227,7 @@ save_xmm(dcontext_t *dcontext, sigframe_rt_t *frame)
|
||||
dr_xgetbv(&bv_high, &bv_low);
|
||||
xstate->xstate_hdr.xstate_bv = (((uint64)bv_high) << 32) | bv_low;
|
||||
}
|
||||
for (i = 0; i < proc_num_simd_saved(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_saved(); i++) {
|
||||
/* we assume no padding */
|
||||
#ifdef X64
|
||||
/* __u32 xmm_space[64] */
|
||||
@@ -250,6 +249,7 @@ save_xmm(dcontext_t *dcontext, sigframe_rt_t *frame)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
/* We can't tell whether the app has used fpstate yet so we preserve every time
|
||||
@@ -369,7 +369,6 @@ dump_fpstate(dcontext_t *dcontext, kernel_fpstate_t *fp)
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\n");
|
||||
}
|
||||
# endif
|
||||
/* XXX i#1312: this needs to get extended to AVX-512. */
|
||||
/* Ignore padding. */
|
||||
if (YMM_ENABLED()) {
|
||||
kernel_xstate_t *xstate = (kernel_xstate_t *)fp;
|
||||
@@ -381,7 +380,7 @@ dump_fpstate(dcontext_t *dcontext, kernel_fpstate_t *fp)
|
||||
ASSERT(TEST(XCR0_AVX, fp->sw_reserved.xstate_bv));
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\txstate_bv = 0x" HEX64_FORMAT_STRING "\n",
|
||||
xstate->xstate_hdr.xstate_bv);
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\tymmh%d = ", i);
|
||||
for (j = 0; j < 4; j++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "%04x ",
|
||||
@@ -391,6 +390,7 @@ dump_fpstate(dcontext_t *dcontext, kernel_fpstate_t *fp)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: Dumping AVX-512 extended registers missing yet. */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -444,11 +444,10 @@ dump_sigcontext(dcontext_t *dcontext, sigcontext_t *sc)
|
||||
void
|
||||
sigcontext_to_mcontext_simd(priv_mcontext_t *mc, sig_full_cxt_t *sc_full)
|
||||
{
|
||||
/* XXX i#1312: this needs to get extended to AVX-512. */
|
||||
sigcontext_t *sc = sc_full->sc;
|
||||
if (sc->fpstate != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&mc->simd[i], &sc->fpstate->IF_X64_ELSE(xmm_space[i * 4], _xmm[i]),
|
||||
XMM_REG_SIZE);
|
||||
}
|
||||
@@ -460,23 +459,23 @@ sigcontext_to_mcontext_simd(priv_mcontext_t *mc, sig_full_cxt_t *sc_full)
|
||||
*/
|
||||
ASSERT(sc->fpstate->sw_reserved.extended_size >= sizeof(*xstate));
|
||||
ASSERT(TEST(XCR0_AVX, sc->fpstate->sw_reserved.xstate_bv));
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&mc->simd[i].u32[4], &xstate->ymmh.ymmh_space[i * 4],
|
||||
YMMH_REG_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
void
|
||||
mcontext_to_sigcontext_simd(sig_full_cxt_t *sc_full, priv_mcontext_t *mc)
|
||||
{
|
||||
/* XXX i#1312: this needs to get extended to AVX-512. */
|
||||
sigcontext_t *sc = sc_full->sc;
|
||||
if (sc->fpstate != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&sc->fpstate->IF_X64_ELSE(xmm_space[i * 4], _xmm[i]), &mc->simd[i],
|
||||
XMM_REG_SIZE);
|
||||
}
|
||||
@@ -488,13 +487,14 @@ mcontext_to_sigcontext_simd(sig_full_cxt_t *sc_full, priv_mcontext_t *mc)
|
||||
*/
|
||||
ASSERT(sc->fpstate->sw_reserved.extended_size >= sizeof(*xstate));
|
||||
ASSERT(TEST(XCR0_AVX, sc->fpstate->sw_reserved.xstate_bv));
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&xstate->ymmh.ymmh_space[i * 4], &mc->simd[i].u32[4],
|
||||
YMMH_REG_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -156,15 +156,16 @@ sigcontext_to_mcontext_simd(priv_mcontext_t *mc, sig_full_cxt_t *sc_full)
|
||||
/* XXX i#1312: This assumption will change and the code below may need
|
||||
* to take this into account.
|
||||
*/
|
||||
ASSERT(MCXT_NUM_SIMD_SLOTS == proc_num_simd_registers());
|
||||
ASSERT(MCXT_NUM_SIMD_SLOTS == proc_num_simd_sse_avx_registers());
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
memcpy(&mc->simd[i], &sc->__fs.__fpu_xmm0 + i, XMM_REG_SIZE);
|
||||
}
|
||||
if (YMM_ENABLED()) {
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&mc->simd[i].u32[4], &sc->__fs.__fpu_ymmh0 + i, YMMH_REG_SIZE);
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -175,15 +176,16 @@ mcontext_to_sigcontext_simd(sig_full_cxt_t *sc_full, priv_mcontext_t *mc)
|
||||
/* XXX i#1312: This assumption will change and the code below may need
|
||||
* to take this into account.
|
||||
*/
|
||||
ASSERT(MCXT_NUM_SIMD_SLOTS == proc_num_simd_registers());
|
||||
ASSERT(MCXT_NUM_SIMD_SLOTS == proc_num_simd_sse_avx_registers());
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
memcpy(&sc->__fs.__fpu_xmm0 + i, &mc->simd[i], XMM_REG_SIZE);
|
||||
}
|
||||
if (YMM_ENABLED()) {
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&sc->__fs.__fpu_ymmh0 + i, &mc->simd[i].u32[4], YMMH_REG_SIZE);
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -209,7 +211,7 @@ dump_fpstate(dcontext_t *dcontext, sigcontext_t *sc)
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\n");
|
||||
}
|
||||
/* XXX i#1312: this needs to get extended to AVX-512. */
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\txmm%d = ", i);
|
||||
for (j = 0; j < 4; j++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "%08x ",
|
||||
@@ -218,7 +220,7 @@ dump_fpstate(dcontext_t *dcontext, sigcontext_t *sc)
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\n");
|
||||
}
|
||||
if (YMM_ENABLED()) {
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\tymmh%d = ", i);
|
||||
for (j = 0; j < 4; j++) {
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "%08x ",
|
||||
@@ -227,6 +229,7 @@ dump_fpstate(dcontext_t *dcontext, sigcontext_t *sc)
|
||||
LOG(THREAD, LOG_ASYNCH, 1, "\n");
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -4726,7 +4726,7 @@ dump_context_info(CONTEXT *context, file_t file, bool all)
|
||||
TESTALL(CONTEXT_XMM_FLAG, context->ContextFlags)) {
|
||||
int i, j;
|
||||
byte *ymmh_area;
|
||||
for (i = 0; i < proc_num_simd_saved(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_saved(); i++) {
|
||||
LOG(file, LOG_ASYNCH, 2, "xmm%d=0x", i);
|
||||
/* This would be simpler if we had uint64 fields in dr_xmm_t but
|
||||
* that complicates our struct layouts */
|
||||
|
||||
+1
-3
@@ -242,9 +242,7 @@ inject_into_thread(HANDLE phandle, CONTEXT *cxt, HANDLE thandle, char *dynamo_pa
|
||||
int i, j;
|
||||
/* For x86, ensure we have ExtendedRegisters space (i#1223) */
|
||||
IF_NOT_X64(ASSERT(TEST(CONTEXT_XMM_FLAG, cxt->ContextFlags)));
|
||||
/* XXX i#1312: This should be proc_num_simd_registers() which is part of
|
||||
* the dynamorio lib.
|
||||
*/
|
||||
/* XXX i#1312: This should be proc_num_simd_sse_avx_registers(). */
|
||||
ASSERT(MCXT_SIMD_SLOT_SIZE == ZMM_REG_SIZE);
|
||||
for (i = 0; i < MCXT_NUM_SIMD_SLOTS; i++) {
|
||||
for (j = 0; j < XMM_REG_SIZE / sizeof(*bufptr); j++) {
|
||||
|
||||
+9
-6
@@ -1130,7 +1130,7 @@ context_to_mcontext_internal(priv_mcontext_t *mcontext, CONTEXT *cxt)
|
||||
/* no harm done if no sse support */
|
||||
/* CONTEXT_FLOATING_POINT or CONTEXT_EXTENDED_REGISTERS */
|
||||
int i;
|
||||
for (i = 0; i < proc_num_simd_registers(); i++)
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++)
|
||||
memcpy(&mcontext->simd[i], CXT_XMM(cxt, i), XMM_REG_SIZE);
|
||||
}
|
||||
/* if XSTATE is NOT set, the app has NOT used any ymm state and
|
||||
@@ -1140,12 +1140,13 @@ context_to_mcontext_internal(priv_mcontext_t *mcontext, CONTEXT *cxt)
|
||||
byte *ymmh_area = context_ymmh_saved_area(cxt);
|
||||
if (ymmh_area != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&mcontext->simd[i].u32[4], &YMMH_AREA(ymmh_area, i).u32[0],
|
||||
YMMH_REG_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
|
||||
/* CONTEXT_CONTROL without the segments */
|
||||
mcontext->xbp = cxt->CXT_XBP;
|
||||
@@ -1231,11 +1232,11 @@ mcontext_to_context(CONTEXT *cxt, priv_mcontext_t *mcontext, bool set_cur_seg)
|
||||
memcpy(&cxt->ExtendedRegisters, fpstate, written);
|
||||
# endif
|
||||
/* Now update w/ the xmm values from mcontext */
|
||||
for (i = 0; i < proc_num_simd_registers(); i++)
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++)
|
||||
memcpy(CXT_XMM(cxt, i), &mcontext->simd[i], XMM_REG_SIZE);
|
||||
}
|
||||
/* XXX i#1312: This will need attention for AVX-512, specifically the different
|
||||
* xstate formats supported by the processor, compacted and standard, as well as
|
||||
/* XXX i#1312: This may need attention for AVX-512, specifically the different
|
||||
* xstate formats supported by the kernel, compacted and standard, as well as
|
||||
* MPX.
|
||||
*/
|
||||
if (CONTEXT_PRESERVE_YMM && TESTALL(CONTEXT_XSTATE, cxt->ContextFlags)) {
|
||||
@@ -1265,10 +1266,11 @@ mcontext_to_context(CONTEXT *cxt, priv_mcontext_t *mcontext, bool set_cur_seg)
|
||||
memcpy(&YMMH_AREA(ymmh_area, 6).u32[0], &ymms[0].u32[4], YMMH_REG_SIZE);
|
||||
memcpy(&YMMH_AREA(ymmh_area, 7).u32[0], &ymms[1].u32[4], YMMH_REG_SIZE);
|
||||
# endif
|
||||
for (i = 0; i < proc_num_simd_registers(); i++) {
|
||||
for (i = 0; i < proc_num_simd_sse_avx_registers(); i++) {
|
||||
memcpy(&YMMH_AREA(ymmh_area, i).u32[0], &mcontext->simd[i].u32[4],
|
||||
YMMH_REG_SIZE);
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
/* The only un-reserved part of the AVX header saved by OP_xsave is
|
||||
* the XSTATE_BV byte.
|
||||
*/
|
||||
@@ -1276,6 +1278,7 @@ mcontext_to_context(CONTEXT *cxt, priv_mcontext_t *mcontext, bool set_cur_seg)
|
||||
*header_bv = (((uint64)bv_high) << 32) | bv_low;
|
||||
}
|
||||
}
|
||||
/* XXX i#1312: AVX-512 extended register copies missing yet. */
|
||||
/* CONTEXT_CONTROL without the segments */
|
||||
cxt->CXT_XBP = mcontext->xbp;
|
||||
cxt->CXT_XSP = mcontext->xsp;
|
||||
|
||||
Reference in New Issue
Block a user