[haiku-commits] haiku: hrev54931 - src/kits/debugger/arch/x86_64 headers/posix/arch/x86_64 src/system/kernel/arch/x86 headers/os/arch/x86_64

  • From: Adrien Destugues <pulkomandy@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 29 Jan 2021 13:29:20 +0000 (UTC)

hrev54931 adds 1 changeset to branch 'master'
old head: 094b8dcf70f188d0f3044e0b3e5d18a98324f1e1
new head: 6f3a5c9ab0c2f388ef0ff6efff713732a710cd93
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=6f3a5c9ab0c2+%5E094b8dcf70f1

----------------------------------------------------------------------------

6f3a5c9ab0c2: Debugger: add AVX support
  
  - Unify storage of "FPU" registers between debugger and signal handler
    to use xsave format on both sides
  - Handle YMM registers in Debugger (they are the same as XMM, but wider)
  
  Tested:
  - The system still boots with and without AVX
  - The hello_avx test program can be debugged and the full value of YMM is 
visible
  
  This changes the API of vregs in signal.h but not the ABI (structure are
  declared differently but memory layout is the same). This changes the
  API and ABI of arch_debugger.h for x86_64, but I don't think anything
  outside Haiku uses it (did we ever have a 64bit compatible gdb?)
  
  Change-Id: If93680ffa0339c19bab517876b4e029f5d66b240
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/3038
  Reviewed-by: Rene Gollent <rene@xxxxxxxxxxx>

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev54931
Commit:      6f3a5c9ab0c2f388ef0ff6efff713732a710cd93
URL:         https://git.haiku-os.org/haiku/commit/?id=6f3a5c9ab0c2
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Thu Jul 16 18:53:50 2020 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Fri Jan 29 13:29:10 2021 UTC

----------------------------------------------------------------------------

7 files changed, 203 insertions(+), 167 deletions(-)
headers/os/arch/x86_64/arch_debugger.h           |  33 +-----
headers/posix/arch/x86_64/signal.h               |  79 ++++---------
.../debugger/arch/x86_64/ArchitectureX8664.cpp   | 114 +++++++++++++------
.../debugger/arch/x86_64/ArchitectureX8664.h     |   7 ++
src/kits/debugger/arch/x86_64/CpuStateX8664.cpp  | 104 ++++++++++-------
src/kits/debugger/arch/x86_64/CpuStateX8664.h    |  10 +-
.../kernel/arch/x86/arch_user_debugger.cpp       |  23 +++-

----------------------------------------------------------------------------

diff --git a/headers/os/arch/x86_64/arch_debugger.h 
b/headers/os/arch/x86_64/arch_debugger.h
index e4607d2fd9..ca89c14825 100644
--- a/headers/os/arch/x86_64/arch_debugger.h
+++ b/headers/os/arch/x86_64/arch_debugger.h
@@ -6,38 +6,14 @@
 #define _ARCH_X86_64_DEBUGGER_H
 
 
-typedef struct x86_64_fp_register {
-       uint8           value[10];
-       uint8           reserved[6];
-} x86_64_fp_register;
+#if __x86_64__
 
 
-typedef struct x86_64_xmm_register {
-       uint8           value[16];
-} x86_64_xmm_register;
-
-
-typedef struct x86_64_extended_registers {
-       uint16                                  control;
-       uint16                                  status;
-       uint8                                   tag;
-       uint8                                   reserved1;
-       uint16                                  opcode;
-       uint64                                  instruction_pointer;
-       uint64                                  data_pointer;
-       uint32                                  mxcsr;
-       uint32                                  mxcsr_mask;
-       union {
-               x86_64_fp_register      fp_registers[8];        // st0-st7
-               x86_64_fp_register      mmx_registers[8];       // mm0-mm7
-       };
-       x86_64_xmm_register             xmm_registers[16];      // xmm0-xmm15
-       uint8                                   reserved2[96];          // 416 
- 512
-} x86_64_extended_registers;
+#include <posix/arch/x86_64/signal.h>
 
 
 struct x86_64_debug_cpu_state {
-       x86_64_extended_registers       extended_registers;
+       struct savefpu  extended_registers;
 
        uint64  gs;
        uint64  fs;
@@ -68,4 +44,7 @@ struct x86_64_debug_cpu_state {
 } __attribute__((aligned(16)));
 
 
+#endif
+
+
 #endif // _ARCH_X86_64_DEBUGGER_H
diff --git a/headers/posix/arch/x86_64/signal.h 
b/headers/posix/arch/x86_64/signal.h
index ad4fa4b128..e9146569ea 100644
--- a/headers/posix/arch/x86_64/signal.h
+++ b/headers/posix/arch/x86_64/signal.h
@@ -12,64 +12,18 @@
 
 #if __x86_64__
 
-
-struct fp_stack {
-       unsigned char           st0[10];
-       unsigned char           _reserved_42_47[6];
-       unsigned char           st1[10];
-       unsigned char           _reserved_58_63[6];
-       unsigned char           st2[10];
-       unsigned char           _reserved_74_79[6];
-       unsigned char           st3[10];
-       unsigned char           _reserved_90_95[6];
-       unsigned char           st4[10];
-       unsigned char           _reserved_106_111[6];
-       unsigned char           st5[10];
-       unsigned char           _reserved_122_127[6];
-       unsigned char           st6[10];
-       unsigned char           _reserved_138_143[6];
-       unsigned char           st7[10];
-       unsigned char           _reserved_154_159[6];
+struct x86_64_fp_register {
+       unsigned char value[10];
+       unsigned char reserved[6];
 };
 
-struct mmx_regs {
-       unsigned char           mm0[10];
-       unsigned char           _reserved_42_47[6];
-       unsigned char           mm1[10];
-       unsigned char           _reserved_58_63[6];
-       unsigned char           mm2[10];
-       unsigned char           _reserved_74_79[6];
-       unsigned char           mm3[10];
-       unsigned char           _reserved_90_95[6];
-       unsigned char           mm4[10];
-       unsigned char           _reserved_106_111[6];
-       unsigned char           mm5[10];
-       unsigned char           _reserved_122_127[6];
-       unsigned char           mm6[10];
-       unsigned char           _reserved_138_143[6];
-       unsigned char           mm7[10];
-       unsigned char           _reserved_154_159[6];
-};
 
-struct xmm_regs {
-       unsigned char           xmm0[16];
-       unsigned char           xmm1[16];
-       unsigned char           xmm2[16];
-       unsigned char           xmm3[16];
-       unsigned char           xmm4[16];
-       unsigned char           xmm5[16];
-       unsigned char           xmm6[16];
-       unsigned char           xmm7[16];
-       unsigned char           xmm8[16];
-       unsigned char           xmm9[16];
-       unsigned char           xmm10[16];
-       unsigned char           xmm11[16];
-       unsigned char           xmm12[16];
-       unsigned char           xmm13[16];
-       unsigned char           xmm14[16];
-       unsigned char           xmm15[16];
+struct x86_64_xmm_register {
+       unsigned char value[16];
 };
 
+
+// The layout of this struct matches the one used by the FXSAVE instruction
 struct fpu_state {
        unsigned short          control;
        unsigned short          status;
@@ -81,26 +35,33 @@ struct fpu_state {
        unsigned int            mscsr_mask;
 
        union {
-               struct fp_stack fp;
-               struct mmx_regs mmx;
+               struct x86_64_fp_register fp[8];
+               struct x86_64_fp_register mmx[8];
        };
 
-       struct xmm_regs         xmm;
+       struct x86_64_xmm_register              xmm[16];
        unsigned char           _reserved_416_511[96];
 };
 
+
 struct xstate_hdr {
        unsigned long           bv;
        unsigned long           xcomp_bv;
        unsigned char           _reserved[48];
 };
 
+
+// The layout of this struct matches the one used by the FXSAVE instruction on
+// an AVX CPU
 struct savefpu {
-       struct fpu_state        fp_fxsave;
-       struct xstate_hdr       fp_xstate;
-       unsigned long           fp_ymm[16][2];
+       struct fpu_state                        fp_fxsave;
+       struct xstate_hdr                       fp_xstate;
+       struct x86_64_xmm_register      fp_ymm[16];
+               // The high half of the YMM registers, to combine with the low 
half
+               // found in fp_fxsave.xmm
 };
 
+
 struct vregs {
        unsigned long           rax;
        unsigned long           rbx;
diff --git a/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp 
b/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp
index cb03343633..995ecee58f 100644
--- a/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp
+++ b/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp
@@ -29,6 +29,7 @@
 
 #include "disasm/DisassemblerX8664.h"
 
+#define X86_64_EXTENDED_FEATURE_AVX    (1 << 28)
 
 static const int32 kFromDwarfRegisters[] = {
        X86_64_REGISTER_RAX,
@@ -170,6 +171,20 @@ ArchitectureX8664::Init()
        if (fAssemblyLanguage == NULL)
                return B_NO_MEMORY;
 
+       int featureFlags = 0;
+#ifdef __x86_64__
+       // TODO: this needs to be determined/retrieved indirectly from the
+       // target host interface, as in the remote case the CPU features may
+       // differ from those of the local CPU.
+       cpuid_info info;
+       status_t error = get_cpuid(&info, 1, 0);
+       if (error != B_OK)
+               return error;
+
+       if ((info.eax_1.extended_features & X86_64_EXTENDED_FEATURE_AVX) != 0)
+               featureFlags |= X86_64_CPU_FEATURE_FLAG_AVX;
+#endif
+
        try {
                _AddIntegerRegister(X86_64_REGISTER_RIP, "rip", B_UINT64_TYPE,
                        REGISTER_TYPE_INSTRUCTION_POINTER, false);
@@ -240,38 +255,73 @@ ArchitectureX8664::Init()
                _AddSIMDRegister(X86_64_REGISTER_MM6, "mm6", sizeof(uint64));
                _AddSIMDRegister(X86_64_REGISTER_MM7, "mm7", sizeof(uint64));
 
-               _AddSIMDRegister(X86_64_REGISTER_XMM0, "xmm0",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM1, "xmm1",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM2, "xmm2",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM3, "xmm3",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM4, "xmm4",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM5, "xmm5",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM6, "xmm6",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM7, "xmm7",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM8, "xmm8",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM9, "xmm9",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM10, "xmm10",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM11, "xmm11",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM12, "xmm12",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM13, "xmm13",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM14, "xmm14",
-                       sizeof(x86_64_xmm_register));
-               _AddSIMDRegister(X86_64_REGISTER_XMM15, "xmm15",
-                       sizeof(x86_64_xmm_register));
+               if ((featureFlags & X86_64_CPU_FEATURE_FLAG_AVX) != 0) {
+                       _AddSIMDRegister(X86_64_REGISTER_XMM0, "ymm0",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM1, "ymm1",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM2, "ymm2",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM3, "ymm3",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM4, "ymm4",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM5, "ymm5",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM6, "ymm6",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM7, "ymm7",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM8, "ymm8",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM9, "ymm9",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM10, "ymm10",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM11, "ymm11",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM12, "ymm12",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM13, "ymm13",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM14, "ymm14",
+                                       sizeof(x86_64_xmm_register) * 2);
+                       _AddSIMDRegister(X86_64_REGISTER_XMM15, "ymm15",
+                                       sizeof(x86_64_xmm_register) * 2);
+               } else {
+                       _AddSIMDRegister(X86_64_REGISTER_XMM0, "xmm0",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM1, "xmm1",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM2, "xmm2",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM3, "xmm3",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM4, "xmm4",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM5, "xmm5",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM6, "xmm6",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM7, "xmm7",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM8, "xmm8",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM9, "xmm9",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM10, "xmm10",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM11, "xmm11",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM12, "xmm12",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM13, "xmm13",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM14, "xmm14",
+                                       sizeof(x86_64_xmm_register));
+                       _AddSIMDRegister(X86_64_REGISTER_XMM15, "xmm15",
+                                       sizeof(x86_64_xmm_register));
+               }
 
        } catch (std::bad_alloc&) {
                return B_NO_MEMORY;
diff --git a/src/kits/debugger/arch/x86_64/ArchitectureX8664.h 
b/src/kits/debugger/arch/x86_64/ArchitectureX8664.h
index dfeb2ed886..6d84c908b0 100644
--- a/src/kits/debugger/arch/x86_64/ArchitectureX8664.h
+++ b/src/kits/debugger/arch/x86_64/ArchitectureX8664.h
@@ -14,6 +14,13 @@
 #include "Register.h"
 
 
+enum {
+       X86_64_CPU_FEATURE_FLAG_NONE = 0,
+       X86_64_CPU_FEATURE_FLAG_AVX = 1,
+       X86_64_CPU_FEATURE_FLAG_AVX512 = 2
+};
+
+
 class SourceLanguage;
 
 
diff --git a/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp 
b/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp
index 36e4b089b8..00c9946c5a 100644
--- a/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp
+++ b/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp
@@ -50,50 +50,70 @@ CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state& 
state)
        SetIntRegister(X86_64_REGISTER_GS, state.gs);
        SetIntRegister(X86_64_REGISTER_SS, state.ss);
 
-       const x86_64_extended_registers& extended = state.extended_registers;
+       const struct savefpu& extended = state.extended_registers;
 
        SetFloatRegister(X86_64_REGISTER_ST0,
-               (double)(*(long double*)(extended.fp_registers[0].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[0].value)));
        SetFloatRegister(X86_64_REGISTER_ST1,
-               (double)(*(long double*)(extended.fp_registers[1].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[1].value)));
        SetFloatRegister(X86_64_REGISTER_ST2,
-               (double)(*(long double*)(extended.fp_registers[2].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[2].value)));
        SetFloatRegister(X86_64_REGISTER_ST3,
-               (double)(*(long double*)(extended.fp_registers[3].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[3].value)));
        SetFloatRegister(X86_64_REGISTER_ST4,
-               (double)(*(long double*)(extended.fp_registers[4].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[4].value)));
        SetFloatRegister(X86_64_REGISTER_ST5,
-               (double)(*(long double*)(extended.fp_registers[5].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[5].value)));
        SetFloatRegister(X86_64_REGISTER_ST6,
-               (double)(*(long double*)(extended.fp_registers[6].value)));
+               (double)(*(long double*)(extended.fp_fxsave.fp[6].value)));
        SetFloatRegister(X86_64_REGISTER_ST7,
-               (double)(*(long double*)(extended.fp_registers[7].value)));
-
-       SetMMXRegister(X86_64_REGISTER_MM0, extended.mmx_registers[0].value);
-       SetMMXRegister(X86_64_REGISTER_MM1, extended.mmx_registers[1].value);
-       SetMMXRegister(X86_64_REGISTER_MM2, extended.mmx_registers[2].value);
-       SetMMXRegister(X86_64_REGISTER_MM3, extended.mmx_registers[3].value);
-       SetMMXRegister(X86_64_REGISTER_MM4, extended.mmx_registers[4].value);
-       SetMMXRegister(X86_64_REGISTER_MM5, extended.mmx_registers[5].value);
-       SetMMXRegister(X86_64_REGISTER_MM6, extended.mmx_registers[6].value);
-       SetMMXRegister(X86_64_REGISTER_MM7, extended.mmx_registers[7].value);
-
-       SetXMMRegister(X86_64_REGISTER_XMM0, extended.xmm_registers[0].value);
-       SetXMMRegister(X86_64_REGISTER_XMM1, extended.xmm_registers[1].value);
-       SetXMMRegister(X86_64_REGISTER_XMM2, extended.xmm_registers[2].value);
-       SetXMMRegister(X86_64_REGISTER_XMM3, extended.xmm_registers[3].value);
-       SetXMMRegister(X86_64_REGISTER_XMM4, extended.xmm_registers[4].value);
-       SetXMMRegister(X86_64_REGISTER_XMM5, extended.xmm_registers[5].value);
-       SetXMMRegister(X86_64_REGISTER_XMM6, extended.xmm_registers[6].value);
-       SetXMMRegister(X86_64_REGISTER_XMM7, extended.xmm_registers[7].value);
-       SetXMMRegister(X86_64_REGISTER_XMM8, extended.xmm_registers[8].value);
-       SetXMMRegister(X86_64_REGISTER_XMM9, extended.xmm_registers[9].value);
-       SetXMMRegister(X86_64_REGISTER_XMM10, extended.xmm_registers[10].value);
-       SetXMMRegister(X86_64_REGISTER_XMM11, extended.xmm_registers[11].value);
-       SetXMMRegister(X86_64_REGISTER_XMM12, extended.xmm_registers[12].value);
-       SetXMMRegister(X86_64_REGISTER_XMM13, extended.xmm_registers[13].value);
-       SetXMMRegister(X86_64_REGISTER_XMM14, extended.xmm_registers[14].value);
-       SetXMMRegister(X86_64_REGISTER_XMM15, extended.xmm_registers[15].value);
+               (double)(*(long double*)(extended.fp_fxsave.fp[7].value)));
+
+       SetMMXRegister(X86_64_REGISTER_MM0, extended.fp_fxsave.mmx[0].value);
+       SetMMXRegister(X86_64_REGISTER_MM1, extended.fp_fxsave.mmx[1].value);
+       SetMMXRegister(X86_64_REGISTER_MM2, extended.fp_fxsave.mmx[2].value);
+       SetMMXRegister(X86_64_REGISTER_MM3, extended.fp_fxsave.mmx[3].value);
+       SetMMXRegister(X86_64_REGISTER_MM4, extended.fp_fxsave.mmx[4].value);
+       SetMMXRegister(X86_64_REGISTER_MM5, extended.fp_fxsave.mmx[5].value);
+       SetMMXRegister(X86_64_REGISTER_MM6, extended.fp_fxsave.mmx[6].value);
+       SetMMXRegister(X86_64_REGISTER_MM7, extended.fp_fxsave.mmx[7].value);
+
+       // The YMM register value is split in two halves in the saved CPU 
context,
+       // so we have to reassemble it here.
+       // TODO check extended.xstate_hdr to see if the YMM values are present 
at
+       // all.
+       SetXMMRegister(X86_64_REGISTER_XMM0, extended.fp_ymm[0].value,
+               extended.fp_fxsave.xmm[0].value);
+       SetXMMRegister(X86_64_REGISTER_XMM1, extended.fp_ymm[1].value,
+               extended.fp_fxsave.xmm[1].value);
+       SetXMMRegister(X86_64_REGISTER_XMM2, extended.fp_ymm[2].value,
+               extended.fp_fxsave.xmm[2].value);
+       SetXMMRegister(X86_64_REGISTER_XMM3, extended.fp_ymm[3].value,
+               extended.fp_fxsave.xmm[3].value);
+       SetXMMRegister(X86_64_REGISTER_XMM4, extended.fp_ymm[4].value,
+               extended.fp_fxsave.xmm[4].value);
+       SetXMMRegister(X86_64_REGISTER_XMM5, extended.fp_ymm[5].value,
+               extended.fp_fxsave.xmm[5].value);
+       SetXMMRegister(X86_64_REGISTER_XMM6, extended.fp_ymm[6].value,
+               extended.fp_fxsave.xmm[6].value);
+       SetXMMRegister(X86_64_REGISTER_XMM7, extended.fp_ymm[7].value,
+               extended.fp_fxsave.xmm[7].value);
+       SetXMMRegister(X86_64_REGISTER_XMM8, extended.fp_ymm[8].value,
+               extended.fp_fxsave.xmm[8].value);
+       SetXMMRegister(X86_64_REGISTER_XMM9, extended.fp_ymm[9].value,
+               extended.fp_fxsave.xmm[9].value);
+       SetXMMRegister(X86_64_REGISTER_XMM10, extended.fp_ymm[10].value,
+               extended.fp_fxsave.xmm[10].value);
+       SetXMMRegister(X86_64_REGISTER_XMM11, extended.fp_ymm[11].value,
+               extended.fp_fxsave.xmm[11].value);
+       SetXMMRegister(X86_64_REGISTER_XMM12, extended.fp_ymm[12].value,
+               extended.fp_fxsave.xmm[12].value);
+       SetXMMRegister(X86_64_REGISTER_XMM13, extended.fp_ymm[13].value,
+               extended.fp_fxsave.xmm[13].value);
+       SetXMMRegister(X86_64_REGISTER_XMM14, extended.fp_ymm[14].value,
+               extended.fp_fxsave.xmm[14].value);
+       SetXMMRegister(X86_64_REGISTER_XMM15, extended.fp_ymm[15].value,
+               extended.fp_fxsave.xmm[15].value);
 
        fInterruptVector = state.vector;
 }
@@ -160,21 +180,21 @@ CpuStateX8664::UpdateDebugState(void* state, size_t size) 
const
        x64State->ss = IntRegisterValue(X86_64_REGISTER_SS);
 
        for (int32 i = 0; i < 8; i++) {
-               *(long 
double*)(x64State->extended_registers.fp_registers[i].value)
+               *(long 
double*)(x64State->extended_registers.fp_fxsave.fp[i].value)
                        = (long double)FloatRegisterValue(X86_64_REGISTER_ST0 + 
i);
 
                if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) {
-                       memcpy(&x64State->extended_registers.mmx_registers[i],
+                       memcpy(&x64State->extended_registers.fp_fxsave.mmx[i],
                                &fMMXRegisters[i], sizeof(x86_64_fp_register));
                }
        }
 
        for (int32 i = 0; i < 16; i++) {
                if (IsRegisterSet(X86_64_REGISTER_XMM0 + i)) {
-                       memcpy(&x64State->extended_registers.xmm_registers[i],
+                       memcpy(&x64State->extended_registers.fp_fxsave.xmm[i],
                                &fXMMRegisters[i], sizeof(x86_64_xmm_register));
                } else {
-                       memset(&x64State->extended_registers.xmm_registers[i],
+                       memset(&x64State->extended_registers.fp_fxsave.xmm[i],
                                0, sizeof(x86_64_xmm_register));
                }
        }
@@ -372,12 +392,14 @@ CpuStateX8664::XMMRegisterValue(int32 index) const
 
 
 void
-CpuStateX8664::SetXMMRegister(int32 index, const uint8* value)
+CpuStateX8664::SetXMMRegister(int32 index, const uint8* highValue, const 
uint8* lowValue)
 {
        if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END)
                return;
 
-       memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, value,
+       memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[0], lowValue,
+               sizeof(x86_64_xmm_register));
+       memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[2], highValue,
                sizeof(x86_64_xmm_register));
        fSetRegisters[index] = 1;
 }
diff --git a/src/kits/debugger/arch/x86_64/CpuStateX8664.h 
b/src/kits/debugger/arch/x86_64/CpuStateX8664.h
index da7ca8aa0f..8e4c83721b 100644
--- a/src/kits/debugger/arch/x86_64/CpuStateX8664.h
+++ b/src/kits/debugger/arch/x86_64/CpuStateX8664.h
@@ -99,6 +99,11 @@ enum {
        - X86_64_MMX_REGISTER_END)
 
 
+struct x86_64_ymm_register {
+       unsigned long value[4];
+};
+
+
 class CpuStateX8664 : public CpuState {
 public:
                                                                CpuStateX8664();
@@ -128,6 +133,7 @@ public:
                        uint64                          IntRegisterValue(int32 
index) const;
                        void                            SetIntRegister(int32 
index, uint64 value);
 
+private:
                        double                          
FloatRegisterValue(int32 index) const;
                        void                            SetFloatRegister(int32 
index, double value);
 
@@ -137,7 +143,7 @@ public:
 
                        const void*                     XMMRegisterValue(int32 
index) const;
                        void                            SetXMMRegister(int32 
index,
-                                                                       const 
uint8* value);
+                                                                       const 
uint8* highValue, const uint8* lowValue);
 
                        void                            UnsetRegister(int32 
index);
 
@@ -148,7 +154,7 @@ private:
                        uint64                          
fIntRegisters[X86_64_INT_REGISTER_COUNT];
                        double                          
fFloatRegisters[X86_64_FP_REGISTER_COUNT];
                        x86_64_fp_register      
fMMXRegisters[X86_64_MMX_REGISTER_COUNT];
-                       x86_64_xmm_register     
fXMMRegisters[X86_64_XMM_REGISTER_COUNT];
+                       x86_64_ymm_register     
fXMMRegisters[X86_64_XMM_REGISTER_COUNT];
                        RegisterBitSet          fSetRegisters;
                        uint64                          fInterruptVector;
 };
diff --git a/src/system/kernel/arch/x86/arch_user_debugger.cpp 
b/src/system/kernel/arch/x86/arch_user_debugger.cpp
index 952c091924..f1d8dcc6b0 100644
--- a/src/system/kernel/arch/x86/arch_user_debugger.cpp
+++ b/src/system/kernel/arch/x86/arch_user_debugger.cpp
@@ -33,7 +33,9 @@
        // TODO: Make those real error codes.
 
 
-#ifndef __x86_64__
+#ifdef __x86_64__
+extern bool gHasXsave;
+#else
 extern bool gHasSSE;
 #endif
 
@@ -202,12 +204,21 @@ get_cpu_state(Thread* thread, iframe* frame, 
debug_cpu_state* cpuState)
        // For the floating point state to be correct the calling function must
        // not use these registers (not even indirectly).
 #ifdef __x86_64__
+       memset(&cpuState->extended_registers, 0,
+               sizeof(cpuState->extended_registers));
+
        if (frame->fpu != nullptr) {
-               memcpy(&cpuState->extended_registers, frame->fpu,
-                       sizeof(cpuState->extended_registers));
-       } else {
-               memset(&cpuState->extended_registers, 0,
-                       sizeof(cpuState->extended_registers));
+               if (gHasXsave) {
+                       // TODO check the xsave header to know the actual size 
of the
+                       // register context depending on what is saved. For now 
we assume
+                       // there is only the YMM AVX registers
+                       memcpy(&cpuState->extended_registers, frame->fpu,
+                               sizeof(cpuState->extended_registers));
+               } else {
+                       // Only the "legacy area" saved by fxsave is available
+                       memcpy(&cpuState->extended_registers, frame->fpu,
+                               sizeof(cpuState->extended_registers.fp_fxsave));
+               }
        }
 #else
        Thread* thisThread = thread_get_current_thread();


Other related posts:

  • » [haiku-commits] haiku: hrev54931 - src/kits/debugger/arch/x86_64 headers/posix/arch/x86_64 src/system/kernel/arch/x86 headers/os/arch/x86_64 - Adrien Destugues