Author: valentinagiusti
Date: Wed Sep 21 08:33:01 2016
New Revision: 282072

URL: http://llvm.org/viewvc/llvm-project?rev=282072&view=rev
Log:
Refactor NativeRegisterContextLinux_x86_64 code.

This patch refactors the way the XState type is checked and, in order to
simplify the code, it removes the usage of the 'cpuid' instruction: just 
checking
if the ptrace calls done throuhg ReadFPR is enough to verify both if there is
HW support and if there is kernel support. Also the XCR0 bits are enough to 
check if
there is both HW and kernel support for AVX and MPX.

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

Modified:
    
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h

Modified: 
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp?rev=282072&r1=282071&r2=282072&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp 
(original)
+++ 
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp 
Wed Sep 21 08:33:01 2016
@@ -20,8 +20,6 @@
 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 
-#include <cpuid.h>
-
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
 
@@ -664,9 +662,9 @@ Error NativeRegisterContextLinux_x86_64:
 
   ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
   dst += GetRegisterInfoInterface().GetGPRSize();
-  if (GetXStateType() == XStateType::FXSAVE)
+  if (m_xstate_type == XStateType::FXSAVE)
     ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
-  else if (GetXStateType() == XStateType::XSAVE) {
+  else if (m_xstate_type == XStateType::XSAVE) {
     lldb::ByteOrder byte_order = GetByteOrder();
 
     if (IsCPUFeatureAvailable(RegSet::avx)) {
@@ -756,16 +754,16 @@ Error NativeRegisterContextLinux_x86_64:
     return error;
 
   src += GetRegisterInfoInterface().GetGPRSize();
-  if (GetXStateType() == XStateType::FXSAVE)
+  if (m_xstate_type == XStateType::FXSAVE)
     ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
-  else if (GetXStateType() == XStateType::XSAVE)
+  else if (m_xstate_type == XStateType::XSAVE)
     ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
 
   error = WriteFPR();
   if (error.Fail())
     return error;
 
-  if (GetXStateType() == XStateType::XSAVE) {
+  if (m_xstate_type == XStateType::XSAVE) {
     lldb::ByteOrder byte_order = GetByteOrder();
 
     if (IsCPUFeatureAvailable(RegSet::avx)) {
@@ -801,58 +799,28 @@ Error NativeRegisterContextLinux_x86_64:
   return error;
 }
 
-bool NativeRegisterContextLinux_x86_64::HasFXSAVE() const {
-  unsigned int rax, rbx, rcx, rdx;
-
-  // Check if FXSAVE is enabled.
-  if (!__get_cpuid(1, &rax, &rbx, &rcx, &rdx))
-    return false;
-  if ((rdx & bit_FXSAVE) == bit_FXSAVE) {
-    m_xstate_type = XStateType::FXSAVE;
-    if (const_cast<NativeRegisterContextLinux_x86_64 
*>(this)->ReadFPR().Fail())
-      return false;
-    return true;
-  }
-  return false;
-}
-
-bool NativeRegisterContextLinux_x86_64::HasXSAVE() const {
-  unsigned int rax, rbx, rcx, rdx;
-
-  // Check if XSAVE is enabled.
-  if (!__get_cpuid(1, &rax, &rbx, &rcx, &rdx))
-    return false;
-  if ((rcx & bit_OSXSAVE) == bit_OSXSAVE) {
-    m_xstate_type = XStateType::XSAVE;
+bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
+    RegSet feature_code) const {
+  if (m_xstate_type == XStateType::Invalid) {
     if (const_cast<NativeRegisterContextLinux_x86_64 
*>(this)->ReadFPR().Fail())
       return false;
-    return true;
   }
-  return false;
-}
-
-bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
-    RegSet feature_code) const {
-  unsigned int rax, rbx, rcx, rdx;
-
-  // Check if XSAVE is enabled.
-  if (!HasXSAVE())
-    return false;
-
-  __get_cpuid(1, &rax, &rbx, &rcx, &rdx);
   switch (feature_code) {
-  case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by 
reading in the XCR0 area of XSAVE.
-    if (((rcx & bit_AVX) != 0) && ((m_fpr.xstate.xsave.i387.xcr0 & 
mask_XSTATE_AVX) == mask_XSTATE_AVX))
+  case RegSet::gpr:
+  case RegSet::fpu:
+    return true;
+  case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
+                    // reading in the XCR0 area of XSAVE.
+    if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
       return true;
-  case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by 
reading in the XCR0 area of XSAVE.
-    if (__get_cpuid_max(0, NULL) > 7) {
-      __cpuid_count(7, 0, rax, rbx, rcx, rdx);
-      if (((rbx & bit_MPX) != 0) && ((m_fpr.xstate.xsave.i387.xcr0 & 
mask_XSTATE_MPX) == mask_XSTATE_MPX))
-        return true;
-    }
-  default:
-    return false;
+     break;
+  case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
+                    // reading in the XCR0 area of XSAVE.
+    if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
+      return true;
+    break;
   }
+  return false;
 }
 
 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
@@ -867,9 +835,8 @@ bool NativeRegisterContextLinux_x86_64::
     return IsCPUFeatureAvailable(RegSet::avx);
   case RegSet::mpx:
     return IsCPUFeatureAvailable(RegSet::mpx);
-  default:
-    return false;
   }
+  return false;
 }
 
 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
@@ -877,47 +844,21 @@ bool NativeRegisterContextLinux_x86_64::
   return reg_index <= m_reg_info.last_gpr;
 }
 
-NativeRegisterContextLinux_x86_64::XStateType
-NativeRegisterContextLinux_x86_64::GetXStateType() const {
-  if (m_xstate_type == XStateType::Invalid) {
-    if (HasXSAVE())
-      m_xstate_type = XStateType::XSAVE;
-    else if (HasFXSAVE())
-      m_xstate_type = XStateType::FXSAVE;
-  }
-  return m_xstate_type;
-}
-
 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
   return (m_reg_info.first_fpr <= reg_index &&
           reg_index <= m_reg_info.last_fpr);
 }
 
 Error NativeRegisterContextLinux_x86_64::WriteFPR() {
-  const XStateType fpr_type = GetXStateType();
-  const lldb_private::ArchSpec &target_arch =
-      GetRegisterInfoInterface().GetTargetArchitecture();
-  switch (fpr_type) {
+  switch (m_xstate_type) {
   case XStateType::FXSAVE:
-    // For 32-bit inferiors on x86_32/x86_64 architectures,
-    // FXSAVE area can be written using PTRACE_SETREGSET ptrace api
-    // For 64-bit inferiors on x86_64 architectures,
-    // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api
-    switch (target_arch.GetMachine()) {
-    case llvm::Triple::x86:
       return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
                               NT_PRXFPREG);
-    case llvm::Triple::x86_64:
-      return NativeRegisterContextLinux::WriteFPR();
-    default:
-      assert(false && "Unhandled target architecture.");
-      break;
-    }
   case XStateType::XSAVE:
     return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
                             NT_X86_XSTATE);
   default:
-    return Error("Unrecognized FPR type");
+    return Error("Unrecognized FPR type.");
   }
 }
 
@@ -983,8 +924,7 @@ bool NativeRegisterContextLinux_x86_64::
 }
 
 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
-  const XStateType xstate_type = GetXStateType();
-  switch (xstate_type) {
+  switch (m_xstate_type) {
   case XStateType::FXSAVE:
     return &m_fpr.xstate.fxsave;
   case XStateType::XSAVE:
@@ -995,8 +935,7 @@ void *NativeRegisterContextLinux_x86_64:
 }
 
 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
-  const XStateType xstate_type = GetXStateType();
-  switch (xstate_type) {
+  switch (m_xstate_type) {
   case XStateType::FXSAVE:
     return sizeof(m_fpr.xstate.fxsave);
   case XStateType::XSAVE:
@@ -1007,29 +946,23 @@ size_t NativeRegisterContextLinux_x86_64
 }
 
 Error NativeRegisterContextLinux_x86_64::ReadFPR() {
-  const XStateType xstate_type = GetXStateType();
-  const lldb_private::ArchSpec &target_arch =
-      GetRegisterInfoInterface().GetTargetArchitecture();
-  switch (xstate_type) {
-  case XStateType::FXSAVE:
-    // For 32-bit inferiors on x86_32/x86_64 architectures,
-    // FXSAVE area can be read using PTRACE_GETREGSET ptrace api
-    // For 64-bit inferiors on x86_64 architectures,
-    // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api
-    switch (target_arch.GetMachine()) {
-    case llvm::Triple::x86:
-      return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), 
NT_PRXFPREG);
-    case llvm::Triple::x86_64:
-      return NativeRegisterContextLinux::ReadFPR();
-    default:
-      assert(false && "Unhandled target architecture.");
-      break;
+  Error error;
+
+  // Probe XSAVE and if it is not supported fall back to FXSAVE.
+  if (m_xstate_type != XStateType::FXSAVE) {
+    error =
+        ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+    if (!error.Fail()) {
+      m_xstate_type = XStateType::XSAVE;
+      return error;
     }
-  case XStateType::XSAVE:
-    return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), 
NT_X86_XSTATE);
-  default:
-    return Error("Unrecognized FPR type");
   }
+  error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
+  if (!error.Fail()) {
+    m_xstate_type = XStateType::FXSAVE;
+    return error;
+  }
+  return Error("Unrecognized FPR type.");
 }
 
 bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {

Modified: 
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h?rev=282072&r1=282071&r2=282072&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h 
(original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h 
Wed Sep 21 08:33:01 2016
@@ -117,18 +117,12 @@ private:
   uint32_t m_fctrl_offset_in_userarea;
 
   // Private member methods.
-  bool HasFXSAVE() const;
-
-  bool HasXSAVE() const;
-
   bool IsCPUFeatureAvailable(RegSet feature_code) const;
 
   bool IsRegisterSetAvailable(uint32_t set_index) const;
 
   bool IsGPR(uint32_t reg_index) const;
 
-  XStateType GetXStateType() const;
-
   bool IsFPR(uint32_t reg_index) const;
 
   bool CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to