15ffd83dbSDimitry Andric //===-- RegisterContextPOSIX_x86.cpp --------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9*5f7ddb14SDimitry Andric #include <cerrno>
10*5f7ddb14SDimitry Andric #include <cstdint>
110b57cec5SDimitry Andric #include <cstring>
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "lldb/Target/Process.h"
140b57cec5SDimitry Andric #include "lldb/Target/Target.h"
150b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
160b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
170b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h"
180b57cec5SDimitry Andric #include "lldb/Utility/Endian.h"
190b57cec5SDimitry Andric #include "lldb/Utility/RegisterValue.h"
200b57cec5SDimitry Andric #include "lldb/Utility/Scalar.h"
210b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #include "RegisterContextPOSIX_x86.h"
240b57cec5SDimitry Andric #include "RegisterContext_x86.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace lldb_private;
270b57cec5SDimitry Andric using namespace lldb;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric const uint32_t g_gpr_regnums_i386[] = {
300b57cec5SDimitry Andric     lldb_eax_i386,       lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
310b57cec5SDimitry Andric     lldb_edi_i386,       lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
320b57cec5SDimitry Andric     lldb_eip_i386,       lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
330b57cec5SDimitry Andric     lldb_gs_i386,        lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
340b57cec5SDimitry Andric     lldb_ax_i386,        lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
350b57cec5SDimitry Andric     lldb_di_i386,        lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
360b57cec5SDimitry Andric     lldb_ah_i386,        lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
370b57cec5SDimitry Andric     lldb_al_i386,        lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
380b57cec5SDimitry Andric     LLDB_INVALID_REGNUM, // Register sets must be terminated with
390b57cec5SDimitry Andric                          // LLDB_INVALID_REGNUM.
400b57cec5SDimitry Andric };
410b57cec5SDimitry Andric static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
420b57cec5SDimitry Andric                       1 ==
430b57cec5SDimitry Andric                   k_num_gpr_registers_i386,
440b57cec5SDimitry Andric               "g_gpr_regnums_i386 has wrong number of register infos");
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric const uint32_t g_lldb_regnums_i386[] = {
470b57cec5SDimitry Andric     lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
480b57cec5SDimitry Andric     lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
490b57cec5SDimitry Andric     lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
500b57cec5SDimitry Andric     lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
510b57cec5SDimitry Andric     lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
520b57cec5SDimitry Andric     lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
530b57cec5SDimitry Andric     lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
540b57cec5SDimitry Andric     lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
550b57cec5SDimitry Andric     lldb_xmm6_i386,     lldb_xmm7_i386,
560b57cec5SDimitry Andric     LLDB_INVALID_REGNUM // Register sets must be terminated with
570b57cec5SDimitry Andric                         // LLDB_INVALID_REGNUM.
580b57cec5SDimitry Andric };
590b57cec5SDimitry Andric static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
600b57cec5SDimitry Andric                       1 ==
610b57cec5SDimitry Andric                   k_num_fpr_registers_i386,
620b57cec5SDimitry Andric               "g_lldb_regnums_i386 has wrong number of register infos");
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric const uint32_t g_avx_regnums_i386[] = {
650b57cec5SDimitry Andric     lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
660b57cec5SDimitry Andric     lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
670b57cec5SDimitry Andric     LLDB_INVALID_REGNUM // Register sets must be terminated with
680b57cec5SDimitry Andric                         // LLDB_INVALID_REGNUM.
690b57cec5SDimitry Andric };
700b57cec5SDimitry Andric static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
710b57cec5SDimitry Andric                       1 ==
720b57cec5SDimitry Andric                   k_num_avx_registers_i386,
730b57cec5SDimitry Andric               " g_avx_regnums_i386 has wrong number of register infos");
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric static const uint32_t g_gpr_regnums_x86_64[] = {
760b57cec5SDimitry Andric     lldb_rax_x86_64,    lldb_rbx_x86_64,    lldb_rcx_x86_64, lldb_rdx_x86_64,
770b57cec5SDimitry Andric     lldb_rdi_x86_64,    lldb_rsi_x86_64,    lldb_rbp_x86_64, lldb_rsp_x86_64,
780b57cec5SDimitry Andric     lldb_r8_x86_64,     lldb_r9_x86_64,     lldb_r10_x86_64, lldb_r11_x86_64,
790b57cec5SDimitry Andric     lldb_r12_x86_64,    lldb_r13_x86_64,    lldb_r14_x86_64, lldb_r15_x86_64,
800b57cec5SDimitry Andric     lldb_rip_x86_64,    lldb_rflags_x86_64, lldb_cs_x86_64,  lldb_fs_x86_64,
810b57cec5SDimitry Andric     lldb_gs_x86_64,     lldb_ss_x86_64,     lldb_ds_x86_64,  lldb_es_x86_64,
820b57cec5SDimitry Andric     lldb_eax_x86_64,    lldb_ebx_x86_64,    lldb_ecx_x86_64, lldb_edx_x86_64,
830b57cec5SDimitry Andric     lldb_edi_x86_64,    lldb_esi_x86_64,    lldb_ebp_x86_64, lldb_esp_x86_64,
840b57cec5SDimitry Andric     lldb_r8d_x86_64,  // Low 32 bits or r8
850b57cec5SDimitry Andric     lldb_r9d_x86_64,  // Low 32 bits or r9
860b57cec5SDimitry Andric     lldb_r10d_x86_64, // Low 32 bits or r10
870b57cec5SDimitry Andric     lldb_r11d_x86_64, // Low 32 bits or r11
880b57cec5SDimitry Andric     lldb_r12d_x86_64, // Low 32 bits or r12
890b57cec5SDimitry Andric     lldb_r13d_x86_64, // Low 32 bits or r13
900b57cec5SDimitry Andric     lldb_r14d_x86_64, // Low 32 bits or r14
910b57cec5SDimitry Andric     lldb_r15d_x86_64, // Low 32 bits or r15
920b57cec5SDimitry Andric     lldb_ax_x86_64,     lldb_bx_x86_64,     lldb_cx_x86_64,  lldb_dx_x86_64,
930b57cec5SDimitry Andric     lldb_di_x86_64,     lldb_si_x86_64,     lldb_bp_x86_64,  lldb_sp_x86_64,
940b57cec5SDimitry Andric     lldb_r8w_x86_64,  // Low 16 bits or r8
950b57cec5SDimitry Andric     lldb_r9w_x86_64,  // Low 16 bits or r9
960b57cec5SDimitry Andric     lldb_r10w_x86_64, // Low 16 bits or r10
970b57cec5SDimitry Andric     lldb_r11w_x86_64, // Low 16 bits or r11
980b57cec5SDimitry Andric     lldb_r12w_x86_64, // Low 16 bits or r12
990b57cec5SDimitry Andric     lldb_r13w_x86_64, // Low 16 bits or r13
1000b57cec5SDimitry Andric     lldb_r14w_x86_64, // Low 16 bits or r14
1010b57cec5SDimitry Andric     lldb_r15w_x86_64, // Low 16 bits or r15
1020b57cec5SDimitry Andric     lldb_ah_x86_64,     lldb_bh_x86_64,     lldb_ch_x86_64,  lldb_dh_x86_64,
1030b57cec5SDimitry Andric     lldb_al_x86_64,     lldb_bl_x86_64,     lldb_cl_x86_64,  lldb_dl_x86_64,
1040b57cec5SDimitry Andric     lldb_dil_x86_64,    lldb_sil_x86_64,    lldb_bpl_x86_64, lldb_spl_x86_64,
1050b57cec5SDimitry Andric     lldb_r8l_x86_64,    // Low 8 bits or r8
1060b57cec5SDimitry Andric     lldb_r9l_x86_64,    // Low 8 bits or r9
1070b57cec5SDimitry Andric     lldb_r10l_x86_64,   // Low 8 bits or r10
1080b57cec5SDimitry Andric     lldb_r11l_x86_64,   // Low 8 bits or r11
1090b57cec5SDimitry Andric     lldb_r12l_x86_64,   // Low 8 bits or r12
1100b57cec5SDimitry Andric     lldb_r13l_x86_64,   // Low 8 bits or r13
1110b57cec5SDimitry Andric     lldb_r14l_x86_64,   // Low 8 bits or r14
1120b57cec5SDimitry Andric     lldb_r15l_x86_64,   // Low 8 bits or r15
1130b57cec5SDimitry Andric     LLDB_INVALID_REGNUM // Register sets must be terminated with
1140b57cec5SDimitry Andric                         // LLDB_INVALID_REGNUM.
1150b57cec5SDimitry Andric };
1160b57cec5SDimitry Andric static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
1170b57cec5SDimitry Andric                       1 ==
1180b57cec5SDimitry Andric                   k_num_gpr_registers_x86_64,
1190b57cec5SDimitry Andric               "g_gpr_regnums_x86_64 has wrong number of register infos");
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric static const uint32_t g_lldb_regnums_x86_64[] = {
1220b57cec5SDimitry Andric     lldb_fctrl_x86_64,  lldb_fstat_x86_64, lldb_ftag_x86_64,
1230b57cec5SDimitry Andric     lldb_fop_x86_64,    lldb_fiseg_x86_64, lldb_fioff_x86_64,
124af732203SDimitry Andric     lldb_fip_x86_64,    lldb_foseg_x86_64, lldb_fooff_x86_64,
125af732203SDimitry Andric     lldb_fdp_x86_64,    lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,
126af732203SDimitry Andric     lldb_st0_x86_64,    lldb_st1_x86_64,   lldb_st2_x86_64,
127af732203SDimitry Andric     lldb_st3_x86_64,    lldb_st4_x86_64,   lldb_st5_x86_64,
128af732203SDimitry Andric     lldb_st6_x86_64,    lldb_st7_x86_64,   lldb_mm0_x86_64,
129af732203SDimitry Andric     lldb_mm1_x86_64,    lldb_mm2_x86_64,   lldb_mm3_x86_64,
130af732203SDimitry Andric     lldb_mm4_x86_64,    lldb_mm5_x86_64,   lldb_mm6_x86_64,
131af732203SDimitry Andric     lldb_mm7_x86_64,    lldb_xmm0_x86_64,  lldb_xmm1_x86_64,
132af732203SDimitry Andric     lldb_xmm2_x86_64,   lldb_xmm3_x86_64,  lldb_xmm4_x86_64,
133af732203SDimitry Andric     lldb_xmm5_x86_64,   lldb_xmm6_x86_64,  lldb_xmm7_x86_64,
134af732203SDimitry Andric     lldb_xmm8_x86_64,   lldb_xmm9_x86_64,  lldb_xmm10_x86_64,
135af732203SDimitry Andric     lldb_xmm11_x86_64,  lldb_xmm12_x86_64, lldb_xmm13_x86_64,
136af732203SDimitry Andric     lldb_xmm14_x86_64,  lldb_xmm15_x86_64,
1370b57cec5SDimitry Andric     LLDB_INVALID_REGNUM // Register sets must be terminated with
1380b57cec5SDimitry Andric                         // LLDB_INVALID_REGNUM.
1390b57cec5SDimitry Andric };
1400b57cec5SDimitry Andric static_assert((sizeof(g_lldb_regnums_x86_64) /
1410b57cec5SDimitry Andric                sizeof(g_lldb_regnums_x86_64[0])) -
1420b57cec5SDimitry Andric                       1 ==
1430b57cec5SDimitry Andric                   k_num_fpr_registers_x86_64,
1440b57cec5SDimitry Andric               "g_lldb_regnums_x86_64 has wrong number of register infos");
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric static const uint32_t g_avx_regnums_x86_64[] = {
1470b57cec5SDimitry Andric     lldb_ymm0_x86_64,   lldb_ymm1_x86_64,  lldb_ymm2_x86_64,  lldb_ymm3_x86_64,
1480b57cec5SDimitry Andric     lldb_ymm4_x86_64,   lldb_ymm5_x86_64,  lldb_ymm6_x86_64,  lldb_ymm7_x86_64,
1490b57cec5SDimitry Andric     lldb_ymm8_x86_64,   lldb_ymm9_x86_64,  lldb_ymm10_x86_64, lldb_ymm11_x86_64,
1500b57cec5SDimitry Andric     lldb_ymm12_x86_64,  lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
1510b57cec5SDimitry Andric     LLDB_INVALID_REGNUM // Register sets must be terminated with
1520b57cec5SDimitry Andric                         // LLDB_INVALID_REGNUM.
1530b57cec5SDimitry Andric };
1540b57cec5SDimitry Andric static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
1550b57cec5SDimitry Andric                       1 ==
1560b57cec5SDimitry Andric                   k_num_avx_registers_x86_64,
1570b57cec5SDimitry Andric               "g_avx_regnums_x86_64 has wrong number of register infos");
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386,
1600b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1610b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386,
1620b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1630b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386,
1640b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1650b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386,
1660b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1670b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386,
1680b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1690b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386,
1700b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1710b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386,
1720b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1730b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386,
1740b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = {
1770b57cec5SDimitry Andric     lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386,
1780b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
1790b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = {
1800b57cec5SDimitry Andric     lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386,
1810b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
1820b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = {
1830b57cec5SDimitry Andric     lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386,
1840b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
1850b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = {
1860b57cec5SDimitry Andric     lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386,
1870b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
1880b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = {
1890b57cec5SDimitry Andric     lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM};
1900b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = {
1910b57cec5SDimitry Andric     lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM};
1920b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = {
1930b57cec5SDimitry Andric     lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM};
1940b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = {
1950b57cec5SDimitry Andric     lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM};
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64,
1980b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
1990b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64,
2000b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2010b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64,
2020b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2030b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64,
2040b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2050b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64,
2060b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2070b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64,
2080b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2090b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64,
2100b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2110b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64,
2120b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2130b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64,
2140b57cec5SDimitry Andric                                                        LLDB_INVALID_REGNUM};
2150b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64,
2160b57cec5SDimitry Andric                                                        LLDB_INVALID_REGNUM};
2170b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64,
2180b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2190b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64,
2200b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2210b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64,
2220b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2230b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64,
2240b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2250b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64,
2260b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2270b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64,
2280b57cec5SDimitry Andric                                                         LLDB_INVALID_REGNUM};
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = {
2310b57cec5SDimitry Andric     lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64,
2320b57cec5SDimitry Andric     lldb_ah_x86_64,  lldb_al_x86_64,  LLDB_INVALID_REGNUM};
2330b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = {
2340b57cec5SDimitry Andric     lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64,
2350b57cec5SDimitry Andric     lldb_bh_x86_64,  lldb_bl_x86_64,  LLDB_INVALID_REGNUM};
2360b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = {
2370b57cec5SDimitry Andric     lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64,
2380b57cec5SDimitry Andric     lldb_ch_x86_64,  lldb_cl_x86_64,  LLDB_INVALID_REGNUM};
2390b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = {
2400b57cec5SDimitry Andric     lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64,
2410b57cec5SDimitry Andric     lldb_dh_x86_64,  lldb_dl_x86_64,  LLDB_INVALID_REGNUM};
2420b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = {
2430b57cec5SDimitry Andric     lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64,
2440b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2450b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = {
2460b57cec5SDimitry Andric     lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64,
2470b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2480b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = {
2490b57cec5SDimitry Andric     lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64,
2500b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2510b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = {
2520b57cec5SDimitry Andric     lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64,
2530b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2540b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = {
2550b57cec5SDimitry Andric     lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64,
2560b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2570b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = {
2580b57cec5SDimitry Andric     lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64,
2590b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2600b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = {
2610b57cec5SDimitry Andric     lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64,
2620b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2630b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = {
2640b57cec5SDimitry Andric     lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64,
2650b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2660b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = {
2670b57cec5SDimitry Andric     lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64,
2680b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2690b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = {
2700b57cec5SDimitry Andric     lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64,
2710b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2720b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = {
2730b57cec5SDimitry Andric     lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64,
2740b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2750b57cec5SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
2760b57cec5SDimitry Andric     lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
2770b57cec5SDimitry Andric     LLDB_INVALID_REGNUM};
2780b57cec5SDimitry Andric 
279af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_fip[] = {lldb_fip_x86_64,
280af732203SDimitry Andric                                                         LLDB_INVALID_REGNUM};
281af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_fdp[] = {lldb_fdp_x86_64,
282af732203SDimitry Andric                                                         LLDB_INVALID_REGNUM};
283af732203SDimitry Andric 
284af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_fip[] = {
285af732203SDimitry Andric     lldb_fip_x86_64, lldb_fioff_x86_64, lldb_fiseg_x86_64, LLDB_INVALID_REGNUM};
286af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_fdp[] = {
287af732203SDimitry Andric     lldb_fdp_x86_64, lldb_fooff_x86_64, lldb_foseg_x86_64, LLDB_INVALID_REGNUM};
288af732203SDimitry Andric 
289af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st0_32[] = {lldb_st0_i386,
290af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
291af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st1_32[] = {lldb_st1_i386,
292af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
293af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st2_32[] = {lldb_st2_i386,
294af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
295af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st3_32[] = {lldb_st3_i386,
296af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
297af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st4_32[] = {lldb_st4_i386,
298af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
299af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st5_32[] = {lldb_st5_i386,
300af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
301af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st6_32[] = {lldb_st6_i386,
302af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
303af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st7_32[] = {lldb_st7_i386,
304af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
305af732203SDimitry Andric 
306af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_32[] = {
307af732203SDimitry Andric     lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM};
308af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_32[] = {
309af732203SDimitry Andric     lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM};
310af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_32[] = {
311af732203SDimitry Andric     lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM};
312af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_32[] = {
313af732203SDimitry Andric     lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM};
314af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_32[] = {
315af732203SDimitry Andric     lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM};
316af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_32[] = {
317af732203SDimitry Andric     lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM};
318af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_32[] = {
319af732203SDimitry Andric     lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM};
320af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_32[] = {
321af732203SDimitry Andric     lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM};
322af732203SDimitry Andric 
323af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st0_64[] = {lldb_st0_x86_64,
324af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
325af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st1_64[] = {lldb_st1_x86_64,
326af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
327af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st2_64[] = {lldb_st2_x86_64,
328af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
329af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st3_64[] = {lldb_st3_x86_64,
330af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
331af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st4_64[] = {lldb_st4_x86_64,
332af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
333af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st5_64[] = {lldb_st5_x86_64,
334af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
335af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st6_64[] = {lldb_st6_x86_64,
336af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
337af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_st7_64[] = {lldb_st7_x86_64,
338af732203SDimitry Andric                                                            LLDB_INVALID_REGNUM};
339af732203SDimitry Andric 
340af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_64[] = {
341af732203SDimitry Andric     lldb_st0_x86_64, lldb_mm0_x86_64, LLDB_INVALID_REGNUM};
342af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_64[] = {
343af732203SDimitry Andric     lldb_st1_x86_64, lldb_mm1_x86_64, LLDB_INVALID_REGNUM};
344af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_64[] = {
345af732203SDimitry Andric     lldb_st2_x86_64, lldb_mm2_x86_64, LLDB_INVALID_REGNUM};
346af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_64[] = {
347af732203SDimitry Andric     lldb_st3_x86_64, lldb_mm3_x86_64, LLDB_INVALID_REGNUM};
348af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_64[] = {
349af732203SDimitry Andric     lldb_st4_x86_64, lldb_mm4_x86_64, LLDB_INVALID_REGNUM};
350af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_64[] = {
351af732203SDimitry Andric     lldb_st5_x86_64, lldb_mm5_x86_64, LLDB_INVALID_REGNUM};
352af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_64[] = {
353af732203SDimitry Andric     lldb_st6_x86_64, lldb_mm6_x86_64, LLDB_INVALID_REGNUM};
354af732203SDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_64[] = {
355af732203SDimitry Andric     lldb_st7_x86_64, lldb_mm7_x86_64, LLDB_INVALID_REGNUM};
356af732203SDimitry Andric 
3570b57cec5SDimitry Andric // Number of register sets provided by this context.
3580b57cec5SDimitry Andric enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
3610b57cec5SDimitry Andric     {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
3620b57cec5SDimitry Andric      g_gpr_regnums_i386},
3630b57cec5SDimitry Andric     {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
3640b57cec5SDimitry Andric      g_lldb_regnums_i386},
3650b57cec5SDimitry Andric     {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
3660b57cec5SDimitry Andric      g_avx_regnums_i386}};
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
3690b57cec5SDimitry Andric     {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
3700b57cec5SDimitry Andric      g_gpr_regnums_x86_64},
3710b57cec5SDimitry Andric     {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
3720b57cec5SDimitry Andric      g_lldb_regnums_x86_64},
3730b57cec5SDimitry Andric     {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
3740b57cec5SDimitry Andric      g_avx_regnums_x86_64}};
3750b57cec5SDimitry Andric 
IsGPR(unsigned reg)3760b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) {
3770b57cec5SDimitry Andric   return reg <= m_reg_info.last_gpr; // GPR's come first.
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
IsFPR(unsigned reg)3800b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) {
3810b57cec5SDimitry Andric   return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric 
IsAVX(unsigned reg)3840b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) {
3850b57cec5SDimitry Andric   return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
IsFPR(unsigned reg,FPRType fpr_type)3880b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) {
3890b57cec5SDimitry Andric   bool generic_fpr = IsFPR(reg);
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   if (fpr_type == eXSAVE)
3920b57cec5SDimitry Andric     return generic_fpr || IsAVX(reg);
3930b57cec5SDimitry Andric   return generic_fpr;
3940b57cec5SDimitry Andric }
3950b57cec5SDimitry Andric 
RegisterContextPOSIX_x86(Thread & thread,uint32_t concrete_frame_idx,RegisterInfoInterface * register_info)3960b57cec5SDimitry Andric RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
3970b57cec5SDimitry Andric     Thread &thread, uint32_t concrete_frame_idx,
3980b57cec5SDimitry Andric     RegisterInfoInterface *register_info)
3990b57cec5SDimitry Andric     : RegisterContext(thread, concrete_frame_idx) {
4000b57cec5SDimitry Andric   m_register_info_up.reset(register_info);
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   switch (register_info->m_target_arch.GetMachine()) {
4030b57cec5SDimitry Andric   case llvm::Triple::x86:
4040b57cec5SDimitry Andric     m_reg_info.num_registers = k_num_registers_i386;
4050b57cec5SDimitry Andric     m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
4060b57cec5SDimitry Andric     m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
4070b57cec5SDimitry Andric     m_reg_info.num_avx_registers = k_num_avx_registers_i386;
4080b57cec5SDimitry Andric     m_reg_info.last_gpr = k_last_gpr_i386;
4090b57cec5SDimitry Andric     m_reg_info.first_fpr = k_first_fpr_i386;
4100b57cec5SDimitry Andric     m_reg_info.last_fpr = k_last_fpr_i386;
4110b57cec5SDimitry Andric     m_reg_info.first_st = lldb_st0_i386;
4120b57cec5SDimitry Andric     m_reg_info.last_st = lldb_st7_i386;
4130b57cec5SDimitry Andric     m_reg_info.first_mm = lldb_mm0_i386;
4140b57cec5SDimitry Andric     m_reg_info.last_mm = lldb_mm7_i386;
4150b57cec5SDimitry Andric     m_reg_info.first_xmm = lldb_xmm0_i386;
4160b57cec5SDimitry Andric     m_reg_info.last_xmm = lldb_xmm7_i386;
4170b57cec5SDimitry Andric     m_reg_info.first_ymm = lldb_ymm0_i386;
4180b57cec5SDimitry Andric     m_reg_info.last_ymm = lldb_ymm7_i386;
4190b57cec5SDimitry Andric     m_reg_info.first_dr = lldb_dr0_i386;
4200b57cec5SDimitry Andric     m_reg_info.gpr_flags = lldb_eflags_i386;
4210b57cec5SDimitry Andric     break;
4220b57cec5SDimitry Andric   case llvm::Triple::x86_64:
4230b57cec5SDimitry Andric     m_reg_info.num_registers = k_num_registers_x86_64;
4240b57cec5SDimitry Andric     m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
4250b57cec5SDimitry Andric     m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
4260b57cec5SDimitry Andric     m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
4270b57cec5SDimitry Andric     m_reg_info.last_gpr = k_last_gpr_x86_64;
4280b57cec5SDimitry Andric     m_reg_info.first_fpr = k_first_fpr_x86_64;
4290b57cec5SDimitry Andric     m_reg_info.last_fpr = k_last_fpr_x86_64;
4300b57cec5SDimitry Andric     m_reg_info.first_st = lldb_st0_x86_64;
4310b57cec5SDimitry Andric     m_reg_info.last_st = lldb_st7_x86_64;
4320b57cec5SDimitry Andric     m_reg_info.first_mm = lldb_mm0_x86_64;
4330b57cec5SDimitry Andric     m_reg_info.last_mm = lldb_mm7_x86_64;
4340b57cec5SDimitry Andric     m_reg_info.first_xmm = lldb_xmm0_x86_64;
4350b57cec5SDimitry Andric     m_reg_info.last_xmm = lldb_xmm15_x86_64;
4360b57cec5SDimitry Andric     m_reg_info.first_ymm = lldb_ymm0_x86_64;
4370b57cec5SDimitry Andric     m_reg_info.last_ymm = lldb_ymm15_x86_64;
4380b57cec5SDimitry Andric     m_reg_info.first_dr = lldb_dr0_x86_64;
4390b57cec5SDimitry Andric     m_reg_info.gpr_flags = lldb_rflags_x86_64;
4400b57cec5SDimitry Andric     break;
4410b57cec5SDimitry Andric   default:
4420b57cec5SDimitry Andric     assert(false && "Unhandled target architecture.");
4430b57cec5SDimitry Andric     break;
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   ::memset(&m_fpr, 0, sizeof(FPR));
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   m_fpr_type = eNotValid;
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric 
451*5f7ddb14SDimitry Andric RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default;
4520b57cec5SDimitry Andric 
GetFPRType()4530b57cec5SDimitry Andric RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
4540b57cec5SDimitry Andric   if (m_fpr_type == eNotValid) {
4550b57cec5SDimitry Andric     // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
4560b57cec5SDimitry Andric     m_fpr_type = eXSAVE; // extended floating-point registers, if available
4570b57cec5SDimitry Andric     if (!ReadFPR())
4580b57cec5SDimitry Andric       m_fpr_type = eFXSAVE; // assume generic floating-point registers
4590b57cec5SDimitry Andric   }
4600b57cec5SDimitry Andric   return m_fpr_type;
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
Invalidate()4630b57cec5SDimitry Andric void RegisterContextPOSIX_x86::Invalidate() {}
4640b57cec5SDimitry Andric 
InvalidateAllRegisters()4650b57cec5SDimitry Andric void RegisterContextPOSIX_x86::InvalidateAllRegisters() {}
4660b57cec5SDimitry Andric 
GetRegisterOffset(unsigned reg)4670b57cec5SDimitry Andric unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) {
4680b57cec5SDimitry Andric   assert(reg < m_reg_info.num_registers && "Invalid register number.");
4690b57cec5SDimitry Andric   return GetRegisterInfo()[reg].byte_offset;
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric 
GetRegisterSize(unsigned reg)4720b57cec5SDimitry Andric unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) {
4730b57cec5SDimitry Andric   assert(reg < m_reg_info.num_registers && "Invalid register number.");
4740b57cec5SDimitry Andric   return GetRegisterInfo()[reg].byte_size;
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric 
GetRegisterCount()4770b57cec5SDimitry Andric size_t RegisterContextPOSIX_x86::GetRegisterCount() {
4780b57cec5SDimitry Andric   size_t num_registers =
4790b57cec5SDimitry Andric       m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
4800b57cec5SDimitry Andric   if (GetFPRType() == eXSAVE)
4810b57cec5SDimitry Andric     return num_registers + m_reg_info.num_avx_registers;
4820b57cec5SDimitry Andric   return num_registers;
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric 
GetGPRSize()4850b57cec5SDimitry Andric size_t RegisterContextPOSIX_x86::GetGPRSize() {
4860b57cec5SDimitry Andric   return m_register_info_up->GetGPRSize();
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric 
GetFXSAVEOffset()4890b57cec5SDimitry Andric size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
4900b57cec5SDimitry Andric   return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset;
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric 
GetRegisterInfo()4930b57cec5SDimitry Andric const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
4940b57cec5SDimitry Andric   // Commonly, this method is overridden and g_register_infos is copied and
4950b57cec5SDimitry Andric   // specialized. So, use GetRegisterInfo() rather than g_register_infos in
4960b57cec5SDimitry Andric   // this scope.
4970b57cec5SDimitry Andric   return m_register_info_up->GetRegisterInfo();
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)5010b57cec5SDimitry Andric RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) {
5020b57cec5SDimitry Andric   if (reg < m_reg_info.num_registers)
5030b57cec5SDimitry Andric     return &GetRegisterInfo()[reg];
5040b57cec5SDimitry Andric   else
5050b57cec5SDimitry Andric     return nullptr;
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric 
GetRegisterSetCount()5080b57cec5SDimitry Andric size_t RegisterContextPOSIX_x86::GetRegisterSetCount() {
5090b57cec5SDimitry Andric   size_t sets = 0;
5100b57cec5SDimitry Andric   for (size_t set = 0; set < k_num_register_sets; ++set) {
5110b57cec5SDimitry Andric     if (IsRegisterSetAvailable(set))
5120b57cec5SDimitry Andric       ++sets;
5130b57cec5SDimitry Andric   }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   return sets;
5160b57cec5SDimitry Andric }
5170b57cec5SDimitry Andric 
GetRegisterSet(size_t set)5180b57cec5SDimitry Andric const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) {
5190b57cec5SDimitry Andric   if (IsRegisterSetAvailable(set)) {
5200b57cec5SDimitry Andric     switch (m_register_info_up->m_target_arch.GetMachine()) {
5210b57cec5SDimitry Andric     case llvm::Triple::x86:
5220b57cec5SDimitry Andric       return &g_reg_sets_i386[set];
5230b57cec5SDimitry Andric     case llvm::Triple::x86_64:
5240b57cec5SDimitry Andric       return &g_reg_sets_x86_64[set];
5250b57cec5SDimitry Andric     default:
5260b57cec5SDimitry Andric       assert(false && "Unhandled target architecture.");
5270b57cec5SDimitry Andric       return nullptr;
5280b57cec5SDimitry Andric     }
5290b57cec5SDimitry Andric   }
5300b57cec5SDimitry Andric   return nullptr;
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric 
GetRegisterName(unsigned reg)5330b57cec5SDimitry Andric const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {
5340b57cec5SDimitry Andric   assert(reg < m_reg_info.num_registers && "Invalid register offset.");
5350b57cec5SDimitry Andric   return GetRegisterInfo()[reg].name;
5360b57cec5SDimitry Andric }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric // Parse ymm registers and into xmm.bytes and ymmh.bytes.
CopyYMMtoXSTATE(uint32_t reg,lldb::ByteOrder byte_order)5390b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
5400b57cec5SDimitry Andric                                                lldb::ByteOrder byte_order) {
5410b57cec5SDimitry Andric   if (!IsAVX(reg))
5420b57cec5SDimitry Andric     return false;
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   if (byte_order == eByteOrderLittle) {
5450b57cec5SDimitry Andric     uint32_t reg_no = reg - m_reg_info.first_ymm;
5460b57cec5SDimitry Andric     YMMToXState(m_ymm_set.ymm[reg_no],
5470b57cec5SDimitry Andric         m_fpr.fxsave.xmm[reg_no].bytes,
5480b57cec5SDimitry Andric         m_fpr.xsave.ymmh[reg_no].bytes);
5490b57cec5SDimitry Andric     return true;
5500b57cec5SDimitry Andric   }
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   return false; // unsupported or invalid byte order
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric // Concatenate xmm.bytes with ymmh.bytes
CopyXSTATEtoYMM(uint32_t reg,lldb::ByteOrder byte_order)5560b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
5570b57cec5SDimitry Andric                                                lldb::ByteOrder byte_order) {
5580b57cec5SDimitry Andric   if (!IsAVX(reg))
5590b57cec5SDimitry Andric     return false;
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   if (byte_order == eByteOrderLittle) {
5620b57cec5SDimitry Andric     uint32_t reg_no = reg - m_reg_info.first_ymm;
5630b57cec5SDimitry Andric     m_ymm_set.ymm[reg_no] = XStateToYMM(
5640b57cec5SDimitry Andric         m_fpr.fxsave.xmm[reg_no].bytes,
5650b57cec5SDimitry Andric         m_fpr.xsave.ymmh[reg_no].bytes);
5660b57cec5SDimitry Andric     return true;
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   return false; // unsupported or invalid byte order
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
IsRegisterSetAvailable(size_t set_index)5720b57cec5SDimitry Andric bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
5730b57cec5SDimitry Andric   // Note: Extended register sets are assumed to be at the end of g_reg_sets...
5740b57cec5SDimitry Andric   size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
5770b57cec5SDimitry Andric     ++num_sets;
5780b57cec5SDimitry Andric   return (set_index < num_sets);
5790b57cec5SDimitry Andric }
580