Skip to content

Commit

Permalink
[lldb] [Process] Introduce common helpers to split/recombine YMM data
Browse files Browse the repository at this point in the history
Introduce two common helpers to take care of splitting and recombining
YMM registers to/from XSAVE-like data.  Since FreeBSD, Linux and NetBSD
all use XSAVE-like data structures but with potentially different field
layouts, the function takes two pointers -- to XMM register and to YMM
high bits, and copies the data from/to YMMReg type.

While at it, remove support for big endian.  To mine and Pavel Labath's
combined knowledge, there is no such thing on x86.  Furthermore,
assuming that the YMM register data would be swapped for big endian
seems to be a weird assumption.

Differential Revision: https://reviews.llvm.org/D63610

llvm-svn: 364042
  • Loading branch information
mgorny committed Jun 21, 2019
1 parent 0c7af66 commit 8805829
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 58 deletions.
Expand Up @@ -903,26 +903,13 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
return false; return false;


if (byte_order == lldb::eByteOrderLittle) { if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, uint32_t reg_no = reg_index - m_reg_info.first_ymm;
m_xstate->fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg_no] = XStateToYMM(
sizeof(XMMReg)); m_xstate->fxsave.xmm[reg_no].bytes,
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + m_xstate->xsave.ymmh[reg_no].bytes);
sizeof(XMMReg),
m_xstate->xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true; return true;
} }


if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg),
m_xstate->fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
m_xstate->xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
return false; // unsupported or invalid byte order return false; // unsupported or invalid byte order
} }


Expand All @@ -932,22 +919,13 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
return false; return false;


if (byte_order == lldb::eByteOrderLittle) { if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_xstate->fxsave.xmm[reg - m_reg_info.first_ymm].bytes, uint32_t reg_no = reg - m_reg_info.first_ymm;
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); YMMToXState(m_ymm_set.ymm[reg_no],
::memcpy(m_xstate->xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_xstate->fxsave.xmm[reg_no].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), m_xstate->xsave.ymmh[reg_no].bytes);
sizeof(YMMHReg));
return true; return true;
} }


if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_xstate->fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
::memcpy(m_xstate->xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
return false; // unsupported or invalid byte order return false; // unsupported or invalid byte order
} }


Expand Down
36 changes: 8 additions & 28 deletions lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
Expand Up @@ -474,22 +474,13 @@ bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
return false; return false;


if (byte_order == eByteOrderLittle) { if (byte_order == eByteOrderLittle) {
::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, uint32_t reg_no = reg - m_reg_info.first_ymm;
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); YMMToXState(m_ymm_set.ymm[reg_no],
::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_fpr.fxsave.xmm[reg_no].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), m_fpr.xsave.ymmh[reg_no].bytes);
sizeof(YMMHReg));
return true; return true;
} }


if (byte_order == eByteOrderBig) {
::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
return false; // unsupported or invalid byte order return false; // unsupported or invalid byte order
} }


Expand All @@ -500,24 +491,13 @@ bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
return false; return false;


if (byte_order == eByteOrderLittle) { if (byte_order == eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, uint32_t reg_no = reg - m_reg_info.first_ymm;
m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg_no] = XStateToYMM(
sizeof(XMMReg)); m_fpr.fxsave.xmm[reg_no].bytes,
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), m_fpr.xsave.ymmh[reg_no].bytes);
m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true; return true;
} }


if (byte_order == eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
return false; // unsupported or invalid byte order return false; // unsupported or invalid byte order
} }


Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
Expand Up @@ -353,6 +353,22 @@ union FPR {


LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();


// Convenience function to combine YMM register data from XSAVE-style input.
inline YMMReg XStateToYMM(const void* xmm_bytes, const void* ymmh_bytes) {
YMMReg ret;

::memcpy(ret.bytes, xmm_bytes, sizeof(XMMReg));
::memcpy(ret.bytes + sizeof(XMMReg), ymmh_bytes, sizeof(YMMHReg));

return ret;
}

// Convenience function to copy YMM register data into XSAVE-style output.
inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes) {
::memcpy(xmm_bytes, input.bytes, sizeof(XMMReg));
::memcpy(ymmh_bytes, input.bytes + sizeof(XMMReg), sizeof(YMMHReg));
}

} // namespace lldb_private } // namespace lldb_private


#endif #endif

0 comments on commit 8805829

Please sign in to comment.