From eec7972808e751dd834043248ed7d64008faba53 Mon Sep 17 00:00:00 2001 From: lioncash Date: Mon, 20 Jun 2022 10:24:03 -0400 Subject: [PATCH] UContext: Add definitions for accessing XSAVE data Adds the layout of extended state for accessing/saving ymm high lanes --- .../FEXCore/include/FEXCore/Core/UContext.h | 98 ++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/External/FEXCore/include/FEXCore/Core/UContext.h b/External/FEXCore/include/FEXCore/Core/UContext.h index 9697924e5..38adb0b99 100644 --- a/External/FEXCore/include/FEXCore/Core/UContext.h +++ b/External/FEXCore/include/FEXCore/Core/UContext.h @@ -27,6 +27,57 @@ namespace FEXCore { }; static_assert(sizeof(FEXCore::x86_64::stack_t) == 24, "This needs to be the right size"); + /** + * Describes the software specific bytes added at the end of the + * fpstate to identify whether or not an extended context area is + * present and what kind of extended features are present in said + * context area. + */ + struct FEX_PACKED fpx_sw_bytes { + static constexpr uint32_t FP_XSTATE_MAGIC = 0x46505853; + + enum FeatureFlag : uint32_t { + FEATURE_FP = 1U << 0, + FEATURE_SSE = 1U << 1, + FEATURE_YMM = 1U << 2, + FEATURE_BNDREGS = 1U << 3, + FEATURE_BNDCSR = 1U << 4, + FEATURE_OPMASK = 1U << 5, + FEATURE_ZMM_Hi256 = 1U << 6, + FEATURE_Hi16_ZMM = 1U << 7, + FEATURE_PT_UNIMPL = 1U << 8, + FEATURE_PKRU = 1U << 9, + FEATURE_PASID = 1U << 10, + FEATURE_RESERVED11 = 1U << 11, + FEATURE_RESERVED12 = 1U << 12, + FEATURE_RESERVED13 = 1U << 13, + FEATURE_RESERVED14 = 1U << 14, + FEATURE_LBR = 1U << 15, + FEATURE_RESERVED16 = 1U << 16, + FEATURE_XTILE_CFG = 1U << 17, + FEATURE_XTILE_DATA = 1U << 18, + }; + + // If magic1 is set to FP_XSTATE_MAGIC, then the encompassing + // frame is an xstate frame. If 0, then it's a legacy frame. + uint32_t magic1; + + // Total size of the fpstate area + // - magic1 = 0 -> sizeof(fpstate) + // - magic1 = FP_XSTATE_MAGIC -> sizeof(xstate) + extensions (if any) + uint32_t extended_size; + + // Feature bitmask describing supported features. + uint64_t xfeatures; + + // Actual XSAVE state size, based on above xfeatures + uint32_t xstate_size; + + // Reserved data + uint32_t padding[7]; + }; + static_assert(sizeof(fpx_sw_bytes) == 48); + struct FEX_PACKED _libc_fpstate { // This is in FXSAVE format uint16_t fcw; @@ -39,10 +90,37 @@ namespace FEXCore { uint32_t mxcsr_mask; __uint128_t _st[8]; __uint128_t _xmm[16]; - uint32_t _res[24]; + uint32_t _res[12]; + + // Linux uses 12 of the bytes relegated for software purposes + // to store info describing any existing XSAVE context data. + fpx_sw_bytes sw_reserved; }; static_assert(sizeof(FEXCore::x86_64::_libc_fpstate) == 512, "This needs to be the right size"); + struct FEX_PACKED xstate_header { + uint64_t xfeatures; + uint64_t reserved1[2]; + uint64_t reserved2[5]; + }; + static_assert(sizeof(xstate_header) == 64); + + struct FEX_PACKED ymmh_state { + __uint128_t ymmh_space[16]; + }; + static_assert(sizeof(ymmh_state) == 256); + + /** + * Extended state that includes both the main fpstate + * and the extended state. + */ + struct FEX_PACKED xstate { + _libc_fpstate fpstate; + xstate_header xstate_hdr; + ymmh_state ymmh; + }; + static_assert(sizeof(xstate) == 832); + ///< The order of these must match the GNU ordering enum ContextRegs { FEX_REG_R8 = 0, @@ -233,6 +311,11 @@ namespace FEXCore { }; static_assert(sizeof(FEXCore::x86::_libc_fpreg) == 10, "This needs to be the right size"); + // Same layout on both x86 and x86_64 + using fpx_sw_bytes = x86_64::fpx_sw_bytes; + using xstate_header = x86_64::xstate_header; + using ymmh_state = x86_64::ymmh_state; + enum fpstate_magic { // Legacy fpstate MAGIC_FPU = 0xFFFF'0000, @@ -257,10 +340,21 @@ namespace FEXCore { __uint128_t _st_pad[8]; // Ignored st data __uint128_t _xmm[8]; // First 8 XMM registers uint32_t pad2[44]; // Second 8 XMM registers plus padding - uint32_t pad3[12]; // extended state encoding + fpx_sw_bytes sw_reserved; // extended state encoding }; static_assert(sizeof(FEXCore::x86::_libc_fpstate) == 624, "This needs to be the right size"); + /** + * Extended state that includes both the main fpstate + * and the extended state. + */ + struct FEX_PACKED xstate { + _libc_fpstate fpstate; + xstate_header xstate_hdr; + ymmh_state ymmh; + }; + static_assert(sizeof(xstate) == 944); + struct FEX_PACKED ucontext_t { uint32_t uc_flags; uint32_t uc_link; // XXX: should be a compat_ptr