Author: Michał Górny Date: 2021-10-19T13:36:38+02:00 New Revision: c6d7f248bda3439a06c630c35360d40dbfc06abe
URL: https://github.com/llvm/llvm-project/commit/c6d7f248bda3439a06c630c35360d40dbfc06abe DIFF: https://github.com/llvm/llvm-project/commit/c6d7f248bda3439a06c630c35360d40dbfc06abe.diff LOG: [lldb] [ABI/X86] Refactor ABIX86::AugmentRegisterInfo() Refactor ABIX86::AugmentRegisterInfo() and helper functions for better readability. This also fixes listing eax & co. as potential subregs on 32-bit systems. Differential Revision: https://reviews.llvm.org/D108937 Added: Modified: lldb/source/Plugins/ABI/X86/ABIX86.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/ABI/X86/ABIX86.cpp b/lldb/source/Plugins/ABI/X86/ABIX86.cpp index 0286140e4e24c..2615235cdd8fe 100644 --- a/lldb/source/Plugins/ABI/X86/ABIX86.cpp +++ b/lldb/source/Plugins/ABI/X86/ABIX86.cpp @@ -33,36 +33,40 @@ void ABIX86::Terminate() { ABIWindows_x86_64::Terminate(); } -enum class RegKind { - GPR32 = 0, +namespace { +enum RegKind { + GPR32, GPR16, GPR8h, GPR8, + MM, + YMM_YMMh, + YMM_XMM, - MM = 0, + RegKindCount +}; +} + +struct RegData { + RegKind subreg_kind; + llvm::StringRef subreg_name; + llvm::Optional<uint32_t> base_index; }; -typedef llvm::SmallDenseMap<llvm::StringRef, - llvm::SmallVector<llvm::StringRef, 4>, 16> - RegisterMap; - -static void addPartialRegisters( - std::vector<DynamicRegisterInfo::Register> ®s, - llvm::ArrayRef<uint32_t> base_reg_indices, const RegisterMap ®_names, - uint32_t base_size, RegKind name_index, lldb::Encoding encoding, - lldb::Format format, uint32_t subreg_size, uint32_t subreg_offset = 0) { - for (uint32_t base_index : base_reg_indices) { - if (base_index == LLDB_INVALID_REGNUM) - break; - assert(base_index < regs.size()); +static void +addPartialRegisters(std::vector<DynamicRegisterInfo::Register> ®s, + llvm::ArrayRef<RegData *> subregs, uint32_t base_size, + lldb::Encoding encoding, lldb::Format format, + uint32_t subreg_size, uint32_t subreg_offset = 0) { + for (const RegData *subreg : subregs) { + assert(subreg); + uint32_t base_index = subreg->base_index.getValue(); DynamicRegisterInfo::Register &full_reg = regs[base_index]; - llvm::StringRef subreg_name = reg_names.lookup( - full_reg.name.GetStringRef())[static_cast<int>(name_index)]; - if (subreg_name.empty() || full_reg.byte_size != base_size) + if (full_reg.byte_size != base_size) continue; - lldb_private::DynamicRegisterInfo::Register subreg{ - lldb_private::ConstString(subreg_name), + lldb_private::DynamicRegisterInfo::Register new_reg{ + lldb_private::ConstString(subreg->subreg_name), lldb_private::ConstString(), lldb_private::ConstString("supplementary registers"), subreg_size, @@ -77,10 +81,65 @@ static void addPartialRegisters( {}, subreg_offset}; - addSupplementaryRegister(regs, subreg); + addSupplementaryRegister(regs, new_reg); } } +typedef llvm::SmallDenseMap<llvm::StringRef, llvm::SmallVector<RegData, 4>, 64> + BaseRegToRegsMap; + +#define GPRh(l) \ + { \ + is64bit \ + ? BaseRegToRegsMap::value_type("r" l "x", \ + {{GPR32, "e" l "x", llvm::None}, \ + {GPR16, l "x", llvm::None}, \ + {GPR8h, l "h", llvm::None}, \ + {GPR8, l "l", llvm::None}}) \ + : BaseRegToRegsMap::value_type("e" l "x", {{GPR16, l "x", llvm::None}, \ + {GPR8h, l "h", llvm::None}, \ + {GPR8, l "l", llvm::None}}) \ + } + +#define GPR(r16) \ + { \ + is64bit \ + ? BaseRegToRegsMap::value_type("r" r16, {{GPR32, "e" r16, llvm::None}, \ + {GPR16, r16, llvm::None}, \ + {GPR8, r16 "l", llvm::None}}) \ + : BaseRegToRegsMap::value_type("e" r16, {{GPR16, r16, llvm::None}, \ + {GPR8, r16 "l", llvm::None}}) \ + } + +#define GPR64(n) \ + { \ + BaseRegToRegsMap::value_type("r" #n, {{GPR32, "r" #n "d", llvm::None}, \ + {GPR16, "r" #n "w", llvm::None}, \ + {GPR8, "r" #n "l", llvm::None}}) \ + } + +#define STMM(n) \ + { BaseRegToRegsMap::value_type("st" #n, {{MM, "mm" #n, llvm::None}}) } + +BaseRegToRegsMap makeBaseRegMap(bool is64bit) { + BaseRegToRegsMap out{{// GPRs common to amd64 & i386 + GPRh("a"), GPRh("b"), GPRh("c"), GPRh("d"), GPR("si"), + GPR("di"), GPR("bp"), GPR("sp"), + + // ST/MM registers + STMM(0), STMM(1), STMM(2), STMM(3), STMM(4), STMM(5), + STMM(6), STMM(7)}}; + + if (is64bit) { + BaseRegToRegsMap amd64_regs{{// GPRs specific to amd64 + GPR64(8), GPR64(9), GPR64(10), GPR64(11), + GPR64(12), GPR64(13), GPR64(14), GPR64(15)}}; + out.insert(amd64_regs.begin(), amd64_regs.end()); + } + + return out; +} + void ABIX86::AugmentRegisterInfo( std::vector<DynamicRegisterInfo::Register> ®s) { MCBasedABI::AugmentRegisterInfo(regs); @@ -91,83 +150,51 @@ void ABIX86::AugmentRegisterInfo( uint32_t gpr_base_size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize(); - bool is64bit = gpr_base_size == 8; - - typedef RegisterMap::value_type RegPair; -#define GPR_BASE(basename) (is64bit ? "r" basename : "e" basename) - RegisterMap gpr_regs{{ - RegPair(GPR_BASE("ax"), {"eax", "ax", "ah", "al"}), - RegPair(GPR_BASE("bx"), {"ebx", "bx", "bh", "bl"}), - RegPair(GPR_BASE("cx"), {"ecx", "cx", "ch", "cl"}), - RegPair(GPR_BASE("dx"), {"edx", "dx", "dh", "dl"}), - RegPair(GPR_BASE("si"), {"esi", "si", "", "sil"}), - RegPair(GPR_BASE("di"), {"edi", "di", "", "dil"}), - RegPair(GPR_BASE("bp"), {"ebp", "bp", "", "bpl"}), - RegPair(GPR_BASE("sp"), {"esp", "sp", "", "spl"}), - }}; -#undef GPR_BASE - if (is64bit) { -#define R(base) RegPair(base, {base "d", base "w", "", base "l"}) - RegisterMap amd64_regs{{ - R("r8"), - R("r9"), - R("r10"), - R("r11"), - R("r12"), - R("r13"), - R("r14"), - R("r15"), - }}; -#undef R - gpr_regs.insert(amd64_regs.begin(), amd64_regs.end()); - } - RegisterMap st_regs{{ - RegPair("st0", {"mm0"}), - RegPair("st1", {"mm1"}), - RegPair("st2", {"mm2"}), - RegPair("st3", {"mm3"}), - RegPair("st4", {"mm4"}), - RegPair("st5", {"mm5"}), - RegPair("st6", {"mm6"}), - RegPair("st7", {"mm7"}), - }}; - - // regs from gpr_basenames, in list order - std::vector<uint32_t> gpr_base_reg_indices; - // st0..st7, in list order - std::vector<uint32_t> st_reg_indices; - // map used for fast register lookups + // primary map from a base register to its subregisters + BaseRegToRegsMap base_reg_map = makeBaseRegMap(gpr_base_size == 8); + // set used for fast matching of register names to subregisters llvm::SmallDenseSet<llvm::StringRef, 64> subreg_name_set; - - // put all subreg names into the lookup set - for (const RegisterMap ®set : {gpr_regs, st_regs}) { - for (const RegPair &kv : regset) - subreg_name_set.insert(kv.second.begin(), kv.second.end()); + // convenience array providing access to all subregisters of given kind, + // sorted by base register index + std::array<llvm::SmallVector<RegData *, 16>, RegKindCount> subreg_by_kind; + + // prepare the set of all known subregisters + for (const auto &x : base_reg_map) { + for (const auto &subreg : x.second) + subreg_name_set.insert(subreg.subreg_name); } + // iterate over all registers for (const auto &x : llvm::enumerate(regs)) { llvm::StringRef reg_name = x.value().name.GetStringRef(); - // find expected base registers - if (gpr_regs.find(reg_name) != gpr_regs.end()) - gpr_base_reg_indices.push_back(x.index()); - else if (st_regs.find(reg_name) != st_regs.end()) - st_reg_indices.push_back(x.index()); // abort if at least one sub-register is already present - else if (llvm::is_contained(subreg_name_set, reg_name)) + if (llvm::is_contained(subreg_name_set, reg_name)) return; + + auto found = base_reg_map.find(reg_name); + if (found == base_reg_map.end()) + continue; + + for (auto &subreg : found->second) { + // fill in base register indices + subreg.base_index = x.index(); + // fill subreg_by_kind map-array + subreg_by_kind[static_cast<size_t>(subreg.subreg_kind)].push_back( + &subreg); + } } - if (is64bit) - addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size, - RegKind::GPR32, eEncodingUint, eFormatHex, 4); - addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size, - RegKind::GPR16, eEncodingUint, eFormatHex, 2); - addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size, - RegKind::GPR8h, eEncodingUint, eFormatHex, 1, 1); - addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size, - RegKind::GPR8, eEncodingUint, eFormatHex, 1); - - addPartialRegisters(regs, st_reg_indices, st_regs, 10, RegKind::MM, - eEncodingUint, eFormatHex, 8); + // now add registers by kind + addPartialRegisters(regs, subreg_by_kind[GPR32], gpr_base_size, eEncodingUint, + eFormatHex, 4); + addPartialRegisters(regs, subreg_by_kind[GPR16], gpr_base_size, eEncodingUint, + eFormatHex, 2); + addPartialRegisters(regs, subreg_by_kind[GPR8h], gpr_base_size, eEncodingUint, + eFormatHex, 1, 1); + addPartialRegisters(regs, subreg_by_kind[GPR8], gpr_base_size, eEncodingUint, + eFormatHex, 1); + + addPartialRegisters(regs, subreg_by_kind[MM], 10, eEncodingUint, eFormatHex, + 8); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits