Added support for dynamic detection of AVX, and

fixed a few bugs that revealed.  Now the "register
read" command should show AVX registers
(ymm0-ymm15) on Mac OS X platforms that support
them.

When testing this on Mac OS X, run debugserver
manually, like this:

debugserver --native-regs localhost:1111 /path/to/executable

Then

lldb /path/to/executable
...
(lldb) process connect connect://localhost:1111

llvm-svn: 135331
This commit is contained in:
Sean Callanan 2011-07-16 00:49:19 +00:00
parent f5a8cc7ef8
commit c4ffe37cf1
8 changed files with 84 additions and 17 deletions

View File

@ -28,7 +28,7 @@ namespace lldb_private {
public:
enum
{
kMaxRegisterByteSize = 16u
kMaxRegisterByteSize = 32u
};
enum Type
{

View File

@ -41,6 +41,7 @@
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; };
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -125,6 +126,8 @@
26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = "<group>"; };
26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = "<group>"; };
26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = "<group>"; };
4971AE7013D10F4F00649E37 /* HasAVX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasAVX.h; sourceTree = "<group>"; };
4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = "<group>"; };
49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = "<group>"; };
49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = "<group>"; };
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = "<group>"; };
@ -278,6 +281,8 @@
26C637E90C71334A0024798E /* i386 */,
26C637FA0C71334A0024798E /* ppc */,
26CF99A11142EB7400011AAB /* x86_64 */,
4971AE7013D10F4F00649E37 /* HasAVX.h */,
4971AE7113D10F4F00649E37 /* HasAVX.s */,
26C637E80C71334A0024798E /* dbgnub-mig.defs */,
26C637ED0C71334A0024798E /* MachDYLD.h */,
26C637EC0C71334A0024798E /* MachDYLD.cpp */,
@ -452,6 +457,7 @@
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,27 @@
//===-- HasAVX.h ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef HasAVX_h
#define HasAVX_h
#if defined (__i386__) || defined (__x86_64__)
#ifdef __cplusplus
extern "C" {
#endif
int HasAVX ();
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -0,0 +1,32 @@
//===-- HasAVX.s ---------------------------------------*- x86 Assembly -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#if defined (__i386__) || defined (__x86_64__)
.globl _HasAVX
_HasAVX:
mov $1, %eax
cpuid
and $0x018000000, %ecx
cmp $0x018000000, %ecx
jne not_supported
mov $0, %ecx
.byte 0x0f, 0x01, 0xd0 // xgetbv, for those assemblers that don't know it
and $0x06, %eax
cmp $0x06, %eax
jne not_supported
mov $1, %eax
jmp done
not_supported:
mov $0, %eax
done:
ret
#endif

View File

@ -330,7 +330,7 @@ DNBArchImplI386::GetFPUState(bool force)
{
if (DEBUG_FPU_REGS)
{
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.context.fpu.avx.__fpu_reserved[0] = -1;
m_state.context.fpu.avx.__fpu_reserved[1] = -1;
@ -460,7 +460,7 @@ DNBArchImplI386::GetFPUState(bool force)
}
else
{
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
@ -503,7 +503,7 @@ DNBArchImplI386::SetFPUState()
}
else
{
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
else
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPR));
@ -813,7 +813,7 @@ const DNBRegisterSetInfo *
DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
*num_reg_sets = k_num_register_sets;
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
return g_reg_sets_avx;
else
return g_reg_sets_no_avx;
@ -886,7 +886,7 @@ DNBArchImplI386::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
break;
case e_regSetFPU:
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
@ -1033,7 +1033,7 @@ DNBArchImplI386::SetRegisterValue(int set, int reg, const DNBRegisterValue *valu
break;
case e_regSetFPU:
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{

View File

@ -17,6 +17,7 @@
#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
#include "../HasAVX.h"
#include "MachRegisterStatesI386.h"
class MachThread;
@ -199,10 +200,10 @@ protected:
GetRegisterSetInfo(nub_size_t *num_reg_sets);
static bool
HasAVX()
CPUHasAVX()
{
if (s_has_avx == kAVXUnknown)
s_has_avx = kAVXNotPresent;
s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent);
return (s_has_avx == kAVXPresent);
}

View File

@ -213,7 +213,7 @@ DNBArchImplX86_64::GetFPUState(bool force)
if (force || m_state.GetError(e_regSetFPU, Read))
{
if (DEBUG_FPU_REGS) {
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.context.fpu.avx.__fpu_reserved[0] = -1;
m_state.context.fpu.avx.__fpu_reserved[1] = -1;
@ -365,7 +365,7 @@ DNBArchImplX86_64::GetFPUState(bool force)
}
else
{
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
@ -427,7 +427,7 @@ DNBArchImplX86_64::SetFPUState()
}
else
{
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
return m_state.GetError(e_regSetFPU, Write);
@ -1013,7 +1013,7 @@ DNBArchImplX86_64::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
*num_reg_sets = k_num_register_sets;
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
return g_reg_sets_avx;
else
return g_reg_sets_no_avx;
@ -1085,7 +1085,7 @@ DNBArchImplX86_64::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
break;
case e_regSetFPU:
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
@ -1264,7 +1264,7 @@ DNBArchImplX86_64::SetRegisterValue(int set, int reg, const DNBRegisterValue *va
break;
case e_regSetFPU:
if (HasAVX() || FORCE_AVX_REGS)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{

View File

@ -16,6 +16,7 @@
#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
#include "../HasAVX.h"
#include "MachRegisterStatesX86_64.h"
class MachThread;
@ -206,10 +207,10 @@ protected:
GetRegisterSetInfo(nub_size_t *num_reg_sets);
static bool
HasAVX()
CPUHasAVX()
{
if (s_has_avx == kAVXUnknown)
s_has_avx = kAVXNotPresent;
s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent);
return (s_has_avx == kAVXPresent);
}