1 //===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/BitmaskEnum.h"
17 #include "llvm/Support/Compiler.h"
19 namespace lldb_private
{
20 // i386 ehframe, dwarf regnums
22 // Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems
31 // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus
32 // dwarf's reg numbering).
34 // i386+darwin eh_frame: 4 is ebp, 5 is esp
35 // i386+everyone else eh_frame: 4 is esp, 5 is ebp
36 // i386 dwarf: 4 is esp, 5 is ebp
37 // lldb will get the darwin-specific eh_frame reg numberings from debugserver,
39 // only encode the generally correct 4 == esp, 5 == ebp numbers in this
48 ehframe_st0_i386
= 12,
56 ehframe_xmm0_i386
= 21,
64 ehframe_mm0_i386
= 29,
74 // DWARF register numbers (eRegisterKindDWARF)
75 // Intel's x86 or IA-32
77 // General Purpose Registers.
88 // Floating Point Registers
115 dwarf_fctrl_i386
= 37, // x87 control word
116 dwarf_fstat_i386
= 38, // x87 status word
117 dwarf_mxcsr_i386
= 39,
125 // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
126 // then differentiate based on size of the register.
127 dwarf_bnd0_i386
= 101,
133 // AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums
135 // EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
136 // eRegisterKindDWARF)
137 // This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
138 // http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
141 dwarf_rax_x86_64
= 0,
149 // Extended GP Registers
158 // Return Address (RA) mapped to RIP
159 dwarf_rip_x86_64
= 16,
160 // SSE Vector Registers
161 dwarf_xmm0_x86_64
= 17,
177 // Floating Point Registers
178 dwarf_st0_x86_64
= 33,
187 dwarf_mm0_x86_64
= 41,
195 // Control and Status Flags Register
196 dwarf_rflags_x86_64
= 49,
197 // selector registers
198 dwarf_es_x86_64
= 50,
205 dwarf_fs_base_x86_64
= 58,
206 dwarf_gs_base_x86_64
= 59,
207 // Floating point control registers
208 dwarf_mxcsr_x86_64
= 64, // Media Control and Status
209 dwarf_fctrl_x86_64
, // x87 control word
210 dwarf_fstat_x86_64
, // x87 status word
211 // Upper Vector Registers
212 dwarf_ymm0h_x86_64
= 67,
229 dwarf_bnd0_x86_64
= 126,
233 // AVX2 Vector Mask Registers
234 // dwarf_k0_x86_64 = 118,
244 // Generic floating-point registers
261 static_assert(sizeof(MMSRegComp
) == 10, "MMSRegComp is not 10 bytes of size");
262 static_assert(sizeof(MMSReg
) == 16, "MMSReg is not 16 bytes of size");
265 uint8_t bytes
[16]; // 128-bits for each XMM register
268 // i387_fxsave_struct
270 uint16_t fctrl
; // FPU Control Word (fcw)
271 uint16_t fstat
; // FPU Status Word (fsw)
272 uint16_t ftag
; // FPU Tag Word (ftw)
273 uint16_t fop
; // Last Instruction Opcode (fop)
276 uint64_t fip
; // Instruction Pointer
277 uint64_t fdp
; // Data Pointer
280 uint32_t fioff
; // FPU IP Offset (fip)
281 uint32_t fiseg
; // FPU IP Selector (fcs)
282 uint32_t fooff
; // FPU Operand Pointer Offset (foo)
283 uint32_t foseg
; // FPU Operand Pointer Selector (fos)
284 } i386_
; // Added _ in the end to avoid error with gcc defining i386 in some
287 uint32_t mxcsr
; // MXCSR Register State
288 uint32_t mxcsrmask
; // MXCSR Mask
289 MMSReg stmm
[8]; // 8*16 bytes for each FP-reg = 128 bytes
290 XMMReg xmm
[16]; // 16*16 bytes for each XMM-reg = 256 bytes
291 uint8_t padding1
[48];
293 uint8_t padding2
[40];
296 // Extended floating-point registers
299 uint8_t bytes
[16]; // 16 * 8 bits for the high bytes of each YMM register
303 uint8_t bytes
[32]; // 16 * 16 bits for each YMM register
307 YMMReg ymm
[16]; // assembled from ymmh and xmm registers
311 uint8_t bytes
[16]; // MPX 128 bit bound registers
315 uint8_t bytes
[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively
326 enum class XFeature
: uint64_t {
331 BNDCSR
= BNDREGS
<< 1,
332 OPMASK
= BNDCSR
<< 1,
333 ZMM_Hi256
= OPMASK
<< 1,
334 Hi16_ZMM
= ZMM_Hi256
<< 1,
337 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU
)
340 XFeature xstate_bv
; // OS enabled xstate mask to determine the extended states
341 // supported by the processor
342 XFeature xcomp_bv
; // Mask to indicate the format of the XSAVE area and of
343 // the XRSTOR instruction
344 uint64_t reserved1
[1];
345 uint64_t reserved2
[5];
347 static_assert(sizeof(XSAVE_HDR
) == 64, "XSAVE_HDR layout incorrect");
350 // x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
353 FXSAVE i387
; // floating point registers typical in i387_fxsave_struct
354 XSAVE_HDR header
; // The xsave_hdr_struct can be used to determine if the
355 // following extensions are usable
356 YMMHReg ymmh
[16]; // High 16 bytes of each of 16 YMM registers (the low bytes
357 // are in FXSAVE.xmm for compatibility with SSE)
358 uint64_t reserved3
[16];
359 MPXReg mpxr
[4]; // MPX BNDREG state, containing 128-bit bound registers
360 MPXCsr mpxc
[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and
361 // BNDSTATUS registers
365 // Floating-point registers
367 FXSAVE fxsave
; // Generic floating-point registers.
368 XSAVE xsave
; // x86 extended processor state.
371 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
373 // Convenience function to combine YMM register data from XSAVE-style input.
374 inline YMMReg
XStateToYMM(const void* xmm_bytes
, const void* ymmh_bytes
) {
377 ::memcpy(ret
.bytes
, xmm_bytes
, sizeof(XMMReg
));
378 ::memcpy(ret
.bytes
+ sizeof(XMMReg
), ymmh_bytes
, sizeof(YMMHReg
));
383 // Convenience function to copy YMM register data into XSAVE-style output.
384 inline void YMMToXState(const YMMReg
& input
, void* xmm_bytes
, void* ymmh_bytes
) {
385 ::memcpy(xmm_bytes
, input
.bytes
, sizeof(XMMReg
));
386 ::memcpy(ymmh_bytes
, input
.bytes
+ sizeof(XMMReg
), sizeof(YMMHReg
));
389 uint16_t AbridgedToFullTagWord(uint8_t abridged_tw
, uint16_t sw
,
390 llvm::ArrayRef
<MMSReg
> st_regs
);
391 uint8_t FullToAbridgedTagWord(uint16_t tw
);
393 } // namespace lldb_private