1 //===-- RegisterInfos_i386.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 #include "llvm/Support/Compiler.h" 10 #include <cstddef> 11 #include <cstdint> 12 13 14 #ifdef DECLARE_REGISTER_INFOS_I386_STRUCT 15 16 // Computes the offset of the given GPR in the user data area. 17 #define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) 18 19 // Computes the offset of the given FPR in the extended data area. 20 #define FPR_OFFSET(regname) \ 21 (LLVM_EXTENSION offsetof(UserArea, i387) + \ 22 LLVM_EXTENSION offsetof(FPR_i386, regname)) 23 24 // Computes the offset of the YMM register assembled from register halves. 25 // Based on DNBArchImplI386.cpp from debugserver 26 #define YMM_OFFSET(reg_index) \ 27 (LLVM_EXTENSION offsetof(UserArea, i387) + \ 28 LLVM_EXTENSION offsetof(FPR, fxsave) + \ 29 LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \ 30 (32 * reg_index)) 31 32 #define BNDR_OFFSET(reg_index) \ 33 (LLVM_EXTENSION offsetof(UserArea, i387) + \ 34 LLVM_EXTENSION offsetof(FPR, xsave) + \ 35 LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) 36 37 #define BNDC_OFFSET(reg_index) \ 38 (LLVM_EXTENSION offsetof(UserArea, i387) + \ 39 LLVM_EXTENSION offsetof(FPR, xsave) + \ 40 LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) 41 42 // Number of bytes needed to represent a FPR. 43 #if !defined(FPR_SIZE) 44 #define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) 45 #endif 46 47 // Number of bytes needed to represent the i'th FP register. 48 #define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) 49 50 // Number of bytes needed to represent an XMM register. 51 #define XMM_SIZE sizeof(XMMReg) 52 53 // Number of bytes needed to represent a YMM register. 54 #define YMM_SIZE sizeof(YMMReg) 55 56 // Number of bytes needed to represent MPX registers. 57 #define BNDR_SIZE sizeof(MPXReg) 58 #define BNDC_SIZE sizeof(MPXCsr) 59 60 // Note that the size and offset will be updated by platform-specific classes. 61 #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ 62 { \ 63 #reg, alt, sizeof(((GPR *)nullptr)->reg), \ 64 GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ 65 {kind1, kind2, kind3, kind4, \ 66 lldb_##reg##_i386 }, \ 67 nullptr, nullptr, nullptr, 0 \ 68 } 69 70 #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ 71 { \ 72 #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ 73 {kind1, kind2, kind3, kind4, \ 74 lldb_##name##_i386 }, \ 75 nullptr, nullptr, nullptr, 0 \ 76 } 77 78 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB 79 80 #define DEFINE_FP_ST(reg, i) \ 81 { \ 82 #reg #i, nullptr, FP_SIZE, \ 83 LLVM_EXTENSION FPR_OFFSET( \ 84 stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ 85 {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \ 86 LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \ 87 nullptr, nullptr, nullptr, 0 \ 88 } 89 90 #define DEFINE_FP_MM(reg, i) \ 91 { \ 92 #reg #i, nullptr, sizeof(uint64_t), \ 93 LLVM_EXTENSION FPR_OFFSET( \ 94 stmm[i]), eEncodingUint, eFormatHex, \ 95 {ehframe_mm##i##_i386, dwarf_mm##i##_i386, \ 96 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 97 lldb_mm##i##_i386 }, \ 98 nullptr, nullptr, nullptr, 0 \ 99 } 100 101 #define DEFINE_XMM(reg, i) \ 102 { \ 103 #reg #i, nullptr, XMM_SIZE, \ 104 LLVM_EXTENSION FPR_OFFSET( \ 105 reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ 106 {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \ 107 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ 108 nullptr, nullptr, nullptr, 0 \ 109 } 110 111 // I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then 112 // differentiate based on register size. 113 #define DEFINE_YMM(reg, i) \ 114 { \ 115 #reg #i, nullptr, YMM_SIZE, \ 116 LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ 117 {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \ 118 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 119 lldb_##reg##i##_i386 }, \ 120 nullptr, nullptr, nullptr, 0 \ 121 } 122 123 #define DEFINE_BNDR(reg, i) \ 124 { \ 125 #reg #i, nullptr, BNDR_SIZE, \ 126 LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ 127 {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ 128 LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ 129 nullptr, nullptr, nullptr, 0 \ 130 } 131 132 #define DEFINE_BNDC(name, i) \ 133 { \ 134 #name, nullptr, BNDC_SIZE, \ 135 LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ 136 eFormatVectorOfUInt8, \ 137 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 138 LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ 139 nullptr, nullptr, nullptr, 0 \ 140 } 141 142 #define DEFINE_DR(reg, i) \ 143 { \ 144 #reg #i, nullptr, DR_SIZE, \ 145 DR_OFFSET(i), eEncodingUint, eFormatHex, \ 146 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 147 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 148 LLDB_INVALID_REGNUM }, \ 149 nullptr, nullptr, nullptr, 0 \ 150 } 151 152 #define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ 153 { \ 154 #reg16, nullptr, 2, \ 155 GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ 156 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 157 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 158 lldb_##reg16##_i386 }, \ 159 RegisterContextPOSIX_x86::g_contained_##reg32, \ 160 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 161 } 162 163 #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ 164 { \ 165 #reg8, nullptr, 1, \ 166 GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \ 167 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 168 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 169 lldb_##reg8##_i386 }, \ 170 RegisterContextPOSIX_x86::g_contained_##reg32, \ 171 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 172 } 173 174 #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ 175 { \ 176 #reg8, nullptr, 1, \ 177 GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ 178 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 179 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 180 lldb_##reg8##_i386 }, \ 181 RegisterContextPOSIX_x86::g_contained_##reg32, \ 182 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 183 } 184 185 static RegisterInfo g_register_infos_i386[] = { 186 // General purpose registers. 187 DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, 188 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 189 DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, 190 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 191 DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, 192 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 193 DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, 194 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 195 DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, 196 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 197 DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, 198 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 199 DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, 200 LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), 201 DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, 202 LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), 203 DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, 204 LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), 205 DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, 206 LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), 207 DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, 208 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 209 DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, 210 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 211 DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, 212 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 213 DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, 214 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 215 DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, 216 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 217 DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, 218 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 219 220 DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx), 221 DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx), 222 DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi), 223 DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp), 224 DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx), 225 DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx), 226 DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx), 227 DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx), 228 229 // i387 Floating point registers. 230 DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, 231 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 232 DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, 233 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 234 DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 235 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 236 DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 237 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 238 DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 239 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 240 DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 241 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 242 DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 243 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 244 DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 245 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 246 DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, 247 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 248 DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 249 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 250 251 // FP registers. 252 DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), 253 DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), 254 DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0), 255 DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3), 256 DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6), 257 DEFINE_FP_MM(mm, 7), 258 259 // XMM registers 260 DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), 261 DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), 262 DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), 263 264 // Copy of YMM registers assembled from xmm and ymmh 265 DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), 266 DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), 267 DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), 268 269 // MPX registers 270 DEFINE_BNDR(bnd, 0), 271 DEFINE_BNDR(bnd, 1), 272 DEFINE_BNDR(bnd, 2), 273 DEFINE_BNDR(bnd, 3), 274 275 DEFINE_BNDC(bndcfgu, 0), 276 DEFINE_BNDC(bndstatus, 1), 277 278 // Debug registers for lldb internal use 279 DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), 280 DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; 281 282 static_assert((sizeof(g_register_infos_i386) / 283 sizeof(g_register_infos_i386[0])) == k_num_registers_i386, 284 "g_register_infos_x86_64 has wrong number of register infos"); 285 286 #undef GPR_OFFSET 287 #undef FPR_OFFSET 288 #undef YMM_OFFSET 289 #undef FPR_SIZE 290 #undef FP_SIZE 291 #undef XMM_SIZE 292 #undef YMM_SIZE 293 #undef DEFINE_GPR 294 #undef DEFINE_FPR 295 #undef DEFINE_FP 296 #undef DEFINE_XMM 297 #undef DEFINE_YMM 298 #undef DEFINE_BNDR 299 #undef DEFINE_BNDC 300 #undef DEFINE_DR 301 #undef DEFINE_GPR_PSEUDO_16 302 #undef DEFINE_GPR_PSEUDO_8H 303 #undef DEFINE_GPR_PSEUDO_8L 304 305 #endif // DECLARE_REGISTER_INFOS_I386_STRUCT 306