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, \ 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, \ 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, \ 88 } 89 90 #define DEFINE_FP_MM(reg, i, streg) \ 91 { \ 92 #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ 93 eEncodingUint, eFormatHex, \ 94 {dwarf_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, \ 95 LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \ 96 RegisterContextPOSIX_x86::g_contained_##streg##_32, \ 97 RegisterContextPOSIX_x86::g_invalidate_##streg##_32, \ 98 nullptr, \ 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, \ 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, \ 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, \ 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, \ 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_##reg##i##_i386 }, \ 149 nullptr, nullptr, nullptr, \ 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, \ 161 nullptr, \ 162 } 163 164 #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ 165 { \ 166 #reg8, nullptr, 1, \ 167 GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \ 168 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 169 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 170 lldb_##reg8##_i386 }, \ 171 RegisterContextPOSIX_x86::g_contained_##reg32, \ 172 RegisterContextPOSIX_x86::g_invalidate_##reg32, \ 173 nullptr, \ 174 } 175 176 #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ 177 { \ 178 #reg8, nullptr, 1, \ 179 GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ 180 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 181 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 182 lldb_##reg8##_i386 }, \ 183 RegisterContextPOSIX_x86::g_contained_##reg32, \ 184 RegisterContextPOSIX_x86::g_invalidate_##reg32, \ 185 nullptr, \ 186 } 187 188 static RegisterInfo g_register_infos_i386[] = { 189 // General purpose registers. 190 DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, 191 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 192 DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, 193 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 194 DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, 195 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 196 DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, 197 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 198 DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, 199 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 200 DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, 201 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 202 DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, 203 LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), 204 DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, 205 LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), 206 DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, 207 LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), 208 DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, 209 LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), 210 DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, 211 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 212 DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, 213 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 214 DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, 215 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 216 DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, 217 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 218 DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, 219 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 220 DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, 221 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 222 223 DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx), 224 DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx), 225 DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi), 226 DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp), 227 DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx), 228 DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx), 229 DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx), 230 DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx), 231 232 // i387 Floating point registers. 233 DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, 234 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 235 DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, 236 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 237 DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 238 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 239 DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 240 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 241 DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 242 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 243 DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 244 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 245 DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 246 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 247 DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 248 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 249 DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, 250 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 251 DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 252 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 253 254 // FP registers. 255 DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), 256 DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), 257 DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), 258 259 DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1), 260 DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3), 261 DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5), 262 DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7), 263 264 // XMM registers 265 DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), 266 DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), 267 DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), 268 269 // Copy of YMM registers assembled from xmm and ymmh 270 DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), 271 DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), 272 DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), 273 274 // MPX registers 275 DEFINE_BNDR(bnd, 0), 276 DEFINE_BNDR(bnd, 1), 277 DEFINE_BNDR(bnd, 2), 278 DEFINE_BNDR(bnd, 3), 279 280 DEFINE_BNDC(bndcfgu, 0), 281 DEFINE_BNDC(bndstatus, 1), 282 283 // Debug registers for lldb internal use 284 DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), 285 DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; 286 287 static_assert((sizeof(g_register_infos_i386) / 288 sizeof(g_register_infos_i386[0])) == k_num_registers_i386, 289 "g_register_infos_x86_64 has wrong number of register infos"); 290 291 #undef GPR_OFFSET 292 #undef FPR_OFFSET 293 #undef YMM_OFFSET 294 #undef FPR_SIZE 295 #undef FP_SIZE 296 #undef XMM_SIZE 297 #undef YMM_SIZE 298 #undef DEFINE_GPR 299 #undef DEFINE_FPR 300 #undef DEFINE_FP 301 #undef DEFINE_XMM 302 #undef DEFINE_YMM 303 #undef DEFINE_BNDR 304 #undef DEFINE_BNDC 305 #undef DEFINE_DR 306 #undef DEFINE_GPR_PSEUDO_16 307 #undef DEFINE_GPR_PSEUDO_8H 308 #undef DEFINE_GPR_PSEUDO_8L 309 310 #endif // DECLARE_REGISTER_INFOS_I386_STRUCT 311