Reduce x86 register context boilerplate.

Summary:
The x86 FPR struct was defined as a struct containing a union between
two members: XSAVE and FXSAVE. This patch makes FPR a union directly to
remove one layer of indirection when trying to access the members.

The initial layout of these two structs is identical, which is
recognised by the fact that XSAVE has FXSAVE as its first member, so we
also considered removing one more layer and leave FPR identical to XSAVE
struct, but stopped short of doing that, as the FPR may be used to store
different layouts in the future (e.g., ones generated by the FSAVE
instruction).

Reviewers: clayborg, krytarowski

Subscribers: emaste, lldb-commits

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

llvm-svn: 320966
This commit is contained in:
Pavel Labath 2017-12-18 10:50:59 +00:00
parent 9097a07e4e
commit a0e3c6f6f5
5 changed files with 71 additions and 82 deletions

View File

@ -332,11 +332,11 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
// Initialize m_iovec to point to the buffer and buffer size // Initialize m_iovec to point to the buffer and buffer size
// using the conventions of Berkeley style UIO structures, as required // using the conventions of Berkeley style UIO structures, as required
// by PTRACE extensions. // by PTRACE extensions.
m_iovec.iov_base = &m_fpr.xstate.xsave; m_iovec.iov_base = &m_fpr;
m_iovec.iov_len = sizeof(m_fpr.xstate.xsave); m_iovec.iov_len = sizeof(m_fpr);
// Clear out the FPR state. // Clear out the FPR state.
::memset(&m_fpr, 0, sizeof(FPR)); ::memset(&m_fpr, 0, sizeof(m_fpr));
// Store byte offset of fctrl (i.e. first register of FPR) // Store byte offset of fctrl (i.e. first register of FPR)
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl"); const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
@ -439,17 +439,14 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
if (byte_order != lldb::eByteOrderInvalid) { if (byte_order != lldb::eByteOrderInvalid) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
reg_value.SetBytes( reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
reg_value.SetBytes( reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
reg_value.SetBytes( reg_value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) { if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
// Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
if (CopyXSTATEtoYMM(reg, byte_order)) if (CopyXSTATEtoYMM(reg, byte_order))
@ -490,7 +487,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error; return error;
} }
// Get pointer to m_fpr.xstate.fxsave variable and set the data from it. // Get pointer to m_fpr.fxsave variable and set the data from it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure. // Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)} // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
@ -530,7 +527,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite( void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
uint32_t reg_index) { uint32_t reg_index) {
XSAVE_HDR::XFeature &xstate_bv = m_fpr.xstate.xsave.header.xstate_bv; XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv;
if (IsFPR(reg_index)) { if (IsFPR(reg_index)) {
// IsFPR considers both %st and %xmm registers as floating point, but these // IsFPR considers both %st and %xmm registers as floating point, but these
// map to two features. Set both flags, just in case. // map to two features. Set both flags, just in case.
@ -562,19 +559,16 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) { if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
if (reg_info->encoding == lldb::eEncodingVector) { if (reg_info->encoding == lldb::eEncodingVector) {
if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st) if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
::memcpy( ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm) if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
::memcpy( ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm) if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
::memcpy( ::memcpy(m_fpr.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_ymm && if (reg_index >= m_reg_info.first_ymm &&
reg_index <= m_reg_info.last_ymm) { reg_index <= m_reg_info.last_ymm) {
@ -602,7 +596,7 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
return Status("CopyMPXtoXSTATE() failed"); return Status("CopyMPXtoXSTATE() failed");
} }
} else { } else {
// Get pointer to m_fpr.xstate.fxsave variable and set the data to it. // Get pointer to m_fpr.fxsave variable and set the data to it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure. // Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, WriteFPR() takes m_fpr (of type FPR structure) and writes only // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
@ -674,7 +668,7 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize(); dst += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE) if (m_xstate_type == XStateType::FXSAVE)
::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE) { else if (m_xstate_type == XStateType::XSAVE) {
lldb::ByteOrder byte_order = GetByteOrder(); lldb::ByteOrder byte_order = GetByteOrder();
@ -765,9 +759,9 @@ Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
src += GetRegisterInfoInterface().GetGPRSize(); src += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE) if (m_xstate_type == XStateType::FXSAVE)
::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave)); ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE) else if (m_xstate_type == XStateType::XSAVE)
::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave)); ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
error = WriteFPR(); error = WriteFPR();
if (error.Fail()) if (error.Fail())
@ -821,12 +815,12 @@ bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
return true; return true;
case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
// reading in the XCR0 area of XSAVE. // reading in the XCR0 area of XSAVE.
if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX) if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
return true; return true;
break; break;
case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
// reading in the XCR0 area of XSAVE. // reading in the XCR0 area of XSAVE.
if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX) if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
return true; return true;
break; break;
} }
@ -863,11 +857,10 @@ Status NativeRegisterContextLinux_x86_64::WriteFPR() {
switch (m_xstate_type) { switch (m_xstate_type) {
case XStateType::FXSAVE: case XStateType::FXSAVE:
return WriteRegisterSet( return WriteRegisterSet(
&m_iovec, sizeof(m_fpr.xstate.xsave), &m_iovec, sizeof(m_fpr.fxsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
case XStateType::XSAVE: case XStateType::XSAVE:
return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
NT_X86_XSTATE);
default: default:
return Status("Unrecognized FPR type."); return Status("Unrecognized FPR type.");
} }
@ -887,11 +880,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderLittle) { if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg), sizeof(XMMReg),
m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }
@ -899,10 +892,10 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderBig) { if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg), sizeof(XMMReg),
m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }
@ -915,19 +908,19 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
return false; return false;
if (byte_order == lldb::eByteOrderLittle) { if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, ::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)); m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }
if (byte_order == lldb::eByteOrderBig) { if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, ::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), m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, ::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)); m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true; return true;
} }
@ -937,7 +930,7 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() { void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
switch (m_xstate_type) { switch (m_xstate_type) {
case XStateType::FXSAVE: case XStateType::FXSAVE:
return &m_fpr.xstate.fxsave; return &m_fpr.fxsave;
case XStateType::XSAVE: case XStateType::XSAVE:
return &m_iovec; return &m_iovec;
default: default:
@ -948,7 +941,7 @@ void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
size_t NativeRegisterContextLinux_x86_64::GetFPRSize() { size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
switch (m_xstate_type) { switch (m_xstate_type) {
case XStateType::FXSAVE: case XStateType::FXSAVE:
return sizeof(m_fpr.xstate.fxsave); return sizeof(m_fpr.fxsave);
case XStateType::XSAVE: case XStateType::XSAVE:
return sizeof(m_iovec); return sizeof(m_iovec);
default: default:
@ -961,15 +954,14 @@ Status NativeRegisterContextLinux_x86_64::ReadFPR() {
// Probe XSAVE and if it is not supported fall back to FXSAVE. // Probe XSAVE and if it is not supported fall back to FXSAVE.
if (m_xstate_type != XStateType::FXSAVE) { if (m_xstate_type != XStateType::FXSAVE) {
error = error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
if (!error.Fail()) { if (!error.Fail()) {
m_xstate_type = XStateType::XSAVE; m_xstate_type = XStateType::XSAVE;
return error; return error;
} }
} }
error = ReadRegisterSet( error = ReadRegisterSet(
&m_iovec, sizeof(m_fpr.xstate.xsave), &m_iovec, sizeof(m_fpr.xsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
if (!error.Fail()) { if (!error.Fail()) {
m_xstate_type = XStateType::FXSAVE; m_xstate_type = XStateType::FXSAVE;
@ -991,11 +983,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
sizeof(MPXReg)); sizeof(MPXReg));
} else { } else {
::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
sizeof(MPXCsr)); sizeof(MPXCsr));
} }
return true; return true;
@ -1006,10 +998,10 @@ bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
return false; return false;
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, ::memcpy(m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
} else { } else {
::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, ::memcpy(m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
} }
return true; return true;

View File

@ -475,19 +475,19 @@ bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
return false; return false;
if (byte_order == eByteOrderLittle) { if (byte_order == eByteOrderLittle) {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, ::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)); m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }
if (byte_order == eByteOrderBig) { if (byte_order == eByteOrderBig) {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, ::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), m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, ::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)); m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true; return true;
} }
@ -502,20 +502,20 @@ bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
if (byte_order == eByteOrderLittle) { if (byte_order == eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }
if (byte_order == eByteOrderBig) { if (byte_order == eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg)); sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg)); sizeof(YMMHReg));
return true; return true;
} }

View File

@ -355,12 +355,9 @@ struct LLVM_ALIGNAS(64) XSAVE {
LLVM_PACKED_END LLVM_PACKED_END
// Floating-point registers // Floating-point registers
struct FPR { union FPR {
// Thread state for the floating-point unit of the processor read by ptrace. FXSAVE fxsave; // Generic floating-point registers.
union XSTATE { XSAVE xsave; // x86 extended processor state.
FXSAVE fxsave; // Generic floating-point registers.
XSAVE xsave; // x86 extended processor state.
} xstate;
}; };
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();

View File

@ -27,19 +27,19 @@
// Based on DNBArchImplI386.cpp from debugserver // Based on DNBArchImplI386.cpp from debugserver
#define YMM_OFFSET(reg_index) \ #define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \ (LLVM_EXTENSION offsetof(UserArea, i387) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \ LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \
(32 * reg_index)) (32 * reg_index))
#define BNDR_OFFSET(reg_index) \ #define BNDR_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \ (LLVM_EXTENSION offsetof(UserArea, i387) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
#define BNDC_OFFSET(reg_index) \ #define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \ (LLVM_EXTENSION offsetof(UserArea, i387) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
// Number of bytes needed to represent a FPR. // Number of bytes needed to represent a FPR.
#if !defined(FPR_SIZE) #if !defined(FPR_SIZE)

View File

@ -16,25 +16,25 @@
// Computes the offset of the given FPR in the extended data area. // Computes the offset of the given FPR in the extended data area.
#define FPR_OFFSET(regname) \ #define FPR_OFFSET(regname) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, regname)) LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves. // Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver // Based on DNBArchImplX86_64.cpp from debugserver
#define YMM_OFFSET(reg_index) \ #define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
#define BNDR_OFFSET(reg_index) \ #define BNDR_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
#define BNDC_OFFSET(reg_index) \ #define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT #ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT