1//===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_RegisterContext_x86_H_
10#define liblldb_RegisterContext_x86_H_
11
12#include <cstddef>
13#include <cstdint>
14
15#include "llvm/ADT/BitmaskEnum.h"
16#include "llvm/Support/Compiler.h"
17
18namespace lldb_private {
19// i386 ehframe, dwarf regnums
20
21// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems
22// (non-Darwin)
23//
24enum {
25  ehframe_eax_i386 = 0,
26  ehframe_ecx_i386,
27  ehframe_edx_i386,
28  ehframe_ebx_i386,
29
30  // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus
31  // dwarf's reg numbering).
32  // To be specific:
33  //    i386+darwin eh_frame:        4 is ebp, 5 is esp
34  //    i386+everyone else eh_frame: 4 is esp, 5 is ebp
35  //    i386 dwarf:                  4 is esp, 5 is ebp
36  // lldb will get the darwin-specific eh_frame reg numberings from debugserver,
37  // or the ABI, so we
38  // only encode the generally correct 4 == esp, 5 == ebp numbers in this
39  // generic header.
40
41  ehframe_esp_i386,
42  ehframe_ebp_i386,
43  ehframe_esi_i386,
44  ehframe_edi_i386,
45  ehframe_eip_i386,
46  ehframe_eflags_i386,
47  ehframe_st0_i386 = 12,
48  ehframe_st1_i386,
49  ehframe_st2_i386,
50  ehframe_st3_i386,
51  ehframe_st4_i386,
52  ehframe_st5_i386,
53  ehframe_st6_i386,
54  ehframe_st7_i386,
55  ehframe_xmm0_i386 = 21,
56  ehframe_xmm1_i386,
57  ehframe_xmm2_i386,
58  ehframe_xmm3_i386,
59  ehframe_xmm4_i386,
60  ehframe_xmm5_i386,
61  ehframe_xmm6_i386,
62  ehframe_xmm7_i386,
63  ehframe_mm0_i386 = 29,
64  ehframe_mm1_i386,
65  ehframe_mm2_i386,
66  ehframe_mm3_i386,
67  ehframe_mm4_i386,
68  ehframe_mm5_i386,
69  ehframe_mm6_i386,
70  ehframe_mm7_i386,
71};
72
73// DWARF register numbers (eRegisterKindDWARF)
74// Intel's x86 or IA-32
75enum {
76  // General Purpose Registers.
77  dwarf_eax_i386 = 0,
78  dwarf_ecx_i386,
79  dwarf_edx_i386,
80  dwarf_ebx_i386,
81  dwarf_esp_i386,
82  dwarf_ebp_i386,
83  dwarf_esi_i386,
84  dwarf_edi_i386,
85  dwarf_eip_i386,
86  dwarf_eflags_i386,
87  // Floating Point Registers
88  dwarf_st0_i386 = 11,
89  dwarf_st1_i386,
90  dwarf_st2_i386,
91  dwarf_st3_i386,
92  dwarf_st4_i386,
93  dwarf_st5_i386,
94  dwarf_st6_i386,
95  dwarf_st7_i386,
96  // SSE Registers
97  dwarf_xmm0_i386 = 21,
98  dwarf_xmm1_i386,
99  dwarf_xmm2_i386,
100  dwarf_xmm3_i386,
101  dwarf_xmm4_i386,
102  dwarf_xmm5_i386,
103  dwarf_xmm6_i386,
104  dwarf_xmm7_i386,
105  // MMX Registers
106  dwarf_mm0_i386 = 29,
107  dwarf_mm1_i386,
108  dwarf_mm2_i386,
109  dwarf_mm3_i386,
110  dwarf_mm4_i386,
111  dwarf_mm5_i386,
112  dwarf_mm6_i386,
113  dwarf_mm7_i386,
114  dwarf_fctrl_i386 = 37, // x87 control word
115  dwarf_fstat_i386 = 38, // x87 status word
116  dwarf_mxcsr_i386 = 39,
117  dwarf_es_i386 = 40,
118  dwarf_cs_i386 = 41,
119  dwarf_ss_i386 = 42,
120  dwarf_ds_i386 = 43,
121  dwarf_fs_i386 = 44,
122  dwarf_gs_i386 = 45,
123
124  // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
125  //  then differentiate based on size of the register.
126  dwarf_bnd0_i386 = 101,
127  dwarf_bnd1_i386,
128  dwarf_bnd2_i386,
129  dwarf_bnd3_i386,
130};
131
132// AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums
133
134// EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
135// eRegisterKindDWARF)
136//  This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
137//  http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
138enum {
139  // GP Registers
140  dwarf_rax_x86_64 = 0,
141  dwarf_rdx_x86_64,
142  dwarf_rcx_x86_64,
143  dwarf_rbx_x86_64,
144  dwarf_rsi_x86_64,
145  dwarf_rdi_x86_64,
146  dwarf_rbp_x86_64,
147  dwarf_rsp_x86_64,
148  // Extended GP Registers
149  dwarf_r8_x86_64 = 8,
150  dwarf_r9_x86_64,
151  dwarf_r10_x86_64,
152  dwarf_r11_x86_64,
153  dwarf_r12_x86_64,
154  dwarf_r13_x86_64,
155  dwarf_r14_x86_64,
156  dwarf_r15_x86_64,
157  // Return Address (RA) mapped to RIP
158  dwarf_rip_x86_64 = 16,
159  // SSE Vector Registers
160  dwarf_xmm0_x86_64 = 17,
161  dwarf_xmm1_x86_64,
162  dwarf_xmm2_x86_64,
163  dwarf_xmm3_x86_64,
164  dwarf_xmm4_x86_64,
165  dwarf_xmm5_x86_64,
166  dwarf_xmm6_x86_64,
167  dwarf_xmm7_x86_64,
168  dwarf_xmm8_x86_64,
169  dwarf_xmm9_x86_64,
170  dwarf_xmm10_x86_64,
171  dwarf_xmm11_x86_64,
172  dwarf_xmm12_x86_64,
173  dwarf_xmm13_x86_64,
174  dwarf_xmm14_x86_64,
175  dwarf_xmm15_x86_64,
176  // Floating Point Registers
177  dwarf_st0_x86_64 = 33,
178  dwarf_st1_x86_64,
179  dwarf_st2_x86_64,
180  dwarf_st3_x86_64,
181  dwarf_st4_x86_64,
182  dwarf_st5_x86_64,
183  dwarf_st6_x86_64,
184  dwarf_st7_x86_64,
185  // MMX Registers
186  dwarf_mm0_x86_64 = 41,
187  dwarf_mm1_x86_64,
188  dwarf_mm2_x86_64,
189  dwarf_mm3_x86_64,
190  dwarf_mm4_x86_64,
191  dwarf_mm5_x86_64,
192  dwarf_mm6_x86_64,
193  dwarf_mm7_x86_64,
194  // Control and Status Flags Register
195  dwarf_rflags_x86_64 = 49,
196  //  selector registers
197  dwarf_es_x86_64 = 50,
198  dwarf_cs_x86_64,
199  dwarf_ss_x86_64,
200  dwarf_ds_x86_64,
201  dwarf_fs_x86_64,
202  dwarf_gs_x86_64,
203  // Floating point control registers
204  dwarf_mxcsr_x86_64 = 64, // Media Control and Status
205  dwarf_fctrl_x86_64,      // x87 control word
206  dwarf_fstat_x86_64,      // x87 status word
207  // Upper Vector Registers
208  dwarf_ymm0h_x86_64 = 67,
209  dwarf_ymm1h_x86_64,
210  dwarf_ymm2h_x86_64,
211  dwarf_ymm3h_x86_64,
212  dwarf_ymm4h_x86_64,
213  dwarf_ymm5h_x86_64,
214  dwarf_ymm6h_x86_64,
215  dwarf_ymm7h_x86_64,
216  dwarf_ymm8h_x86_64,
217  dwarf_ymm9h_x86_64,
218  dwarf_ymm10h_x86_64,
219  dwarf_ymm11h_x86_64,
220  dwarf_ymm12h_x86_64,
221  dwarf_ymm13h_x86_64,
222  dwarf_ymm14h_x86_64,
223  dwarf_ymm15h_x86_64,
224  // MPX registers
225  dwarf_bnd0_x86_64 = 126,
226  dwarf_bnd1_x86_64,
227  dwarf_bnd2_x86_64,
228  dwarf_bnd3_x86_64,
229  // AVX2 Vector Mask Registers
230  // dwarf_k0_x86_64 = 118,
231  // dwarf_k1_x86_64,
232  // dwarf_k2_x86_64,
233  // dwarf_k3_x86_64,
234  // dwarf_k4_x86_64,
235  // dwarf_k5_x86_64,
236  // dwarf_k6_x86_64,
237  // dwarf_k7_x86_64,
238};
239
240// Generic floating-point registers
241
242struct MMSReg {
243  uint8_t bytes[10];
244  uint8_t pad[6];
245};
246
247struct XMMReg {
248  uint8_t bytes[16]; // 128-bits for each XMM register
249};
250
251// i387_fxsave_struct
252struct FXSAVE {
253  uint16_t fctrl;     // FPU Control Word (fcw)
254  uint16_t fstat;     // FPU Status Word (fsw)
255  uint16_t ftag;      // FPU Tag Word (ftw)
256  uint16_t fop;       // Last Instruction Opcode (fop)
257  union {
258    struct {
259      uint64_t fip; // Instruction Pointer
260      uint64_t fdp; // Data Pointer
261    } x86_64;
262    struct {
263      uint32_t fioff; // FPU IP Offset (fip)
264      uint32_t fiseg; // FPU IP Selector (fcs)
265      uint32_t fooff; // FPU Operand Pointer Offset (foo)
266      uint32_t foseg; // FPU Operand Pointer Selector (fos)
267    } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
268             // cases
269  } ptr;
270  uint32_t mxcsr;     // MXCSR Register State
271  uint32_t mxcsrmask; // MXCSR Mask
272  MMSReg stmm[8];     // 8*16 bytes for each FP-reg = 128 bytes
273  XMMReg xmm[16];     // 16*16 bytes for each XMM-reg = 256 bytes
274  uint8_t padding1[48];
275  uint64_t xcr0;
276  uint8_t padding2[40];
277};
278
279// Extended floating-point registers
280
281struct YMMHReg {
282  uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
283};
284
285struct YMMReg {
286  uint8_t bytes[32]; // 16 * 16 bits for each YMM register
287};
288
289struct YMM {
290  YMMReg ymm[16]; // assembled from ymmh and xmm registers
291};
292
293struct MPXReg {
294  uint8_t bytes[16]; // MPX 128 bit bound registers
295};
296
297struct MPXCsr {
298  uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively
299                    // BNDCSR state)
300};
301
302struct MPX {
303  MPXReg mpxr[4];
304  MPXCsr mpxc[2];
305};
306
307LLVM_PACKED_START
308struct XSAVE_HDR {
309  enum class XFeature : uint64_t {
310    FP = 1,
311    SSE = FP << 1,
312    YMM = SSE << 1,
313    BNDREGS = YMM << 1,
314    BNDCSR = BNDREGS << 1,
315    OPMASK = BNDCSR << 1,
316    ZMM_Hi256 = OPMASK << 1,
317    Hi16_ZMM = ZMM_Hi256 << 1,
318    PT = Hi16_ZMM << 1,
319    PKRU = PT << 1,
320    LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU)
321  };
322
323  XFeature xstate_bv; // OS enabled xstate mask to determine the extended states
324                      // supported by the processor
325  XFeature xcomp_bv;  // Mask to indicate the format of the XSAVE area and of
326                      // the XRSTOR instruction
327  uint64_t reserved1[1];
328  uint64_t reserved2[5];
329};
330static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect");
331LLVM_PACKED_END
332
333// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
334LLVM_PACKED_START
335struct XSAVE {
336  FXSAVE i387;      // floating point registers typical in i387_fxsave_struct
337  XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the
338                    // following extensions are usable
339  YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes
340                    // are in FXSAVE.xmm for compatibility with SSE)
341  uint64_t reserved3[16];
342  MPXReg mpxr[4];   // MPX BNDREG state, containing 128-bit bound registers
343  MPXCsr mpxc[2];   // MPX BNDCSR state, containing 64-bit BNDCFGU and
344                    // BNDSTATUS registers
345};
346LLVM_PACKED_END
347
348// Floating-point registers
349union FPR {
350  FXSAVE fxsave; // Generic floating-point registers.
351  XSAVE xsave;   // x86 extended processor state.
352};
353
354LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
355
356// Convenience function to combine YMM register data from XSAVE-style input.
357inline YMMReg XStateToYMM(const void* xmm_bytes, const void* ymmh_bytes) {
358  YMMReg ret;
359
360  ::memcpy(ret.bytes, xmm_bytes, sizeof(XMMReg));
361  ::memcpy(ret.bytes + sizeof(XMMReg), ymmh_bytes, sizeof(YMMHReg));
362
363  return ret;
364}
365
366// Convenience function to copy YMM register data into XSAVE-style output.
367inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes) {
368  ::memcpy(xmm_bytes, input.bytes, sizeof(XMMReg));
369  ::memcpy(ymmh_bytes, input.bytes + sizeof(XMMReg), sizeof(YMMHReg));
370}
371
372} // namespace lldb_private
373
374#endif
375