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, 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, nullptr, 0 \ 98 } 99 100 #define DEFINE_XMM(reg, i) \ 101 { \ 102 #reg #i, nullptr, XMM_SIZE, \ 103 LLVM_EXTENSION FPR_OFFSET( \ 104 reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ 105 {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \ 106 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ 107 nullptr, nullptr, nullptr, 0 \ 108 } 109 110 // I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then 111 // differentiate based on register size. 112 #define DEFINE_YMM(reg, i) \ 113 { \ 114 #reg #i, nullptr, YMM_SIZE, \ 115 LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ 116 {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \ 117 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 118 lldb_##reg##i##_i386 }, \ 119 nullptr, nullptr, nullptr, 0 \ 120 } 121 122 #define DEFINE_BNDR(reg, i) \ 123 { \ 124 #reg #i, nullptr, BNDR_SIZE, \ 125 LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ 126 {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ 127 LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ 128 nullptr, nullptr, nullptr, 0 \ 129 } 130 131 #define DEFINE_BNDC(name, i) \ 132 { \ 133 #name, nullptr, BNDC_SIZE, \ 134 LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ 135 eFormatVectorOfUInt8, \ 136 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 137 LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ 138 nullptr, nullptr, nullptr, 0 \ 139 } 140 141 #define DEFINE_DR(reg, i) \ 142 { \ 143 #reg #i, nullptr, DR_SIZE, \ 144 DR_OFFSET(i), eEncodingUint, eFormatHex, \ 145 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 146 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 147 lldb_##reg##i##_i386 }, \ 148 nullptr, nullptr, nullptr, 0 \ 149 } 150 151 #define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ 152 { \ 153 #reg16, nullptr, 2, \ 154 GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ 155 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 156 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 157 lldb_##reg16##_i386 }, \ 158 RegisterContextPOSIX_x86::g_contained_##reg32, \ 159 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 160 } 161 162 #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ 163 { \ 164 #reg8, nullptr, 1, \ 165 GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \ 166 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 167 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 168 lldb_##reg8##_i386 }, \ 169 RegisterContextPOSIX_x86::g_contained_##reg32, \ 170 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 171 } 172 173 #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ 174 { \ 175 #reg8, nullptr, 1, \ 176 GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ 177 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 178 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 179 lldb_##reg8##_i386 }, \ 180 RegisterContextPOSIX_x86::g_contained_##reg32, \ 181 RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ 182 } 183 184 static RegisterInfo g_register_infos_i386[] = { 185 // General purpose registers. 186 DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, 187 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 188 DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, 189 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 190 DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, 191 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 192 DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, 193 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 194 DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, 195 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 196 DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, 197 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 198 DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, 199 LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), 200 DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, 201 LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), 202 DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, 203 LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), 204 DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, 205 LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), 206 DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, 207 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 208 DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, 209 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 210 DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, 211 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 212 DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, 213 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 214 DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, 215 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 216 DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, 217 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 218 219 DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx), 220 DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx), 221 DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi), 222 DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp), 223 DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx), 224 DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx), 225 DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx), 226 DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx), 227 228 // i387 Floating point registers. 229 DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, 230 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 231 DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, 232 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 233 DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 234 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 235 DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 236 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 237 DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 238 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 239 DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 240 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 241 DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 242 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 243 DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 244 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 245 DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, 246 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 247 DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 248 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), 249 250 // FP registers. 251 DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), 252 DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), 253 DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), 254 255 DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1), 256 DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3), 257 DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5), 258 DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7), 259 260 // XMM registers 261 DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), 262 DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), 263 DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), 264 265 // Copy of YMM registers assembled from xmm and ymmh 266 DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), 267 DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), 268 DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), 269 270 // MPX registers 271 DEFINE_BNDR(bnd, 0), 272 DEFINE_BNDR(bnd, 1), 273 DEFINE_BNDR(bnd, 2), 274 DEFINE_BNDR(bnd, 3), 275 276 DEFINE_BNDC(bndcfgu, 0), 277 DEFINE_BNDC(bndstatus, 1), 278 279 // Debug registers for lldb internal use 280 DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), 281 DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; 282 283 static_assert((sizeof(g_register_infos_i386) / 284 sizeof(g_register_infos_i386[0])) == k_num_registers_i386, 285 "g_register_infos_x86_64 has wrong number of register infos"); 286 287 #undef GPR_OFFSET 288 #undef FPR_OFFSET 289 #undef YMM_OFFSET 290 #undef FPR_SIZE 291 #undef FP_SIZE 292 #undef XMM_SIZE 293 #undef YMM_SIZE 294 #undef DEFINE_GPR 295 #undef DEFINE_FPR 296 #undef DEFINE_FP 297 #undef DEFINE_XMM 298 #undef DEFINE_YMM 299 #undef DEFINE_BNDR 300 #undef DEFINE_BNDC 301 #undef DEFINE_DR 302 #undef DEFINE_GPR_PSEUDO_16 303 #undef DEFINE_GPR_PSEUDO_8H 304 #undef DEFINE_GPR_PSEUDO_8L 305 306 #endif // DECLARE_REGISTER_INFOS_I386_STRUCT 307