180814287SRaphael Isemann //===-- RegisterContextPOSIX_mips64.cpp -----------------------------------===//
23e699d41SVirgile Bello //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63e699d41SVirgile Bello //
73e699d41SVirgile Bello //===----------------------------------------------------------------------===//
83e699d41SVirgile Bello
976e47d48SRaphael Isemann #include <cerrno>
1076e47d48SRaphael Isemann #include <cstdint>
113e699d41SVirgile Bello #include <cstring>
123e699d41SVirgile Bello
131a05affaSJames Y Knight #include "lldb/Target/Process.h"
143e699d41SVirgile Bello #include "lldb/Target/Target.h"
153e699d41SVirgile Bello #include "lldb/Target/Thread.h"
16666cc0b2SZachary Turner #include "lldb/Utility/DataBufferHeap.h"
17666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
1801c3243fSZachary Turner #include "lldb/Utility/Endian.h"
19d821c997SPavel Labath #include "lldb/Utility/RegisterValue.h"
20d821c997SPavel Labath #include "lldb/Utility/Scalar.h"
213e699d41SVirgile Bello #include "llvm/Support/Compiler.h"
223e699d41SVirgile Bello
23b9c1b51eSKate Stone #include "RegisterContextPOSIX_mips64.h"
24b8dbd323SNitesh Jain #include "RegisterContextFreeBSD_mips64.h"
253e699d41SVirgile Bello
263e699d41SVirgile Bello using namespace lldb_private;
273e699d41SVirgile Bello using namespace lldb;
283e699d41SVirgile Bello
IsGPR(unsigned reg)29b9c1b51eSKate Stone bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) {
30b8dbd323SNitesh Jain return reg < m_registers_count[gpr_registers_count]; // GPR's come first.
313e699d41SVirgile Bello }
323e699d41SVirgile Bello
IsFPR(unsigned reg)33b9c1b51eSKate Stone bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) {
34b8dbd323SNitesh Jain int set = GetRegisterSetCount();
35b8dbd323SNitesh Jain if (set > 1)
36b8dbd323SNitesh Jain return reg < (m_registers_count[fpr_registers_count]
37b8dbd323SNitesh Jain + m_registers_count[gpr_registers_count]);
383e699d41SVirgile Bello return false;
393e699d41SVirgile Bello }
403e699d41SVirgile Bello
RegisterContextPOSIX_mips64(Thread & thread,uint32_t concrete_frame_idx,RegisterInfoInterface * register_info)41b9c1b51eSKate Stone RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
42b9c1b51eSKate Stone Thread &thread, uint32_t concrete_frame_idx,
433e699d41SVirgile Bello RegisterInfoInterface *register_info)
44b9c1b51eSKate Stone : RegisterContext(thread, concrete_frame_idx) {
45d5b44036SJonas Devlieghere m_register_info_up.reset(register_info);
46b8dbd323SNitesh Jain m_num_registers = GetRegisterCount();
47b8dbd323SNitesh Jain int set = GetRegisterSetCount();
48b8dbd323SNitesh Jain
49b8dbd323SNitesh Jain const RegisterSet *reg_set_ptr;
50b8dbd323SNitesh Jain for(int i = 0; i < set; ++i) {
51b8dbd323SNitesh Jain reg_set_ptr = GetRegisterSet(i);
52b8dbd323SNitesh Jain m_registers_count[i] = reg_set_ptr->num_registers;
53b8dbd323SNitesh Jain }
54b8dbd323SNitesh Jain
5504e7c08dSDavide Italiano assert(m_num_registers ==
5604e7c08dSDavide Italiano static_cast<uint32_t>(m_registers_count[gpr_registers_count] +
57b8dbd323SNitesh Jain m_registers_count[fpr_registers_count] +
5804e7c08dSDavide Italiano m_registers_count[msa_registers_count]));
593e699d41SVirgile Bello }
603e699d41SVirgile Bello
61*fd2433e1SJonas Devlieghere RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() = default;
623e699d41SVirgile Bello
Invalidate()63b9c1b51eSKate Stone void RegisterContextPOSIX_mips64::Invalidate() {}
643e699d41SVirgile Bello
InvalidateAllRegisters()65b9c1b51eSKate Stone void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {}
663e699d41SVirgile Bello
GetRegisterOffset(unsigned reg)67b9c1b51eSKate Stone unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) {
68b8dbd323SNitesh Jain assert(reg < m_num_registers && "Invalid register number.");
693e699d41SVirgile Bello return GetRegisterInfo()[reg].byte_offset;
703e699d41SVirgile Bello }
713e699d41SVirgile Bello
GetRegisterSize(unsigned reg)72b9c1b51eSKate Stone unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) {
73b8dbd323SNitesh Jain assert(reg < m_num_registers && "Invalid register number.");
743e699d41SVirgile Bello return GetRegisterInfo()[reg].byte_size;
753e699d41SVirgile Bello }
763e699d41SVirgile Bello
GetRegisterCount()77b9c1b51eSKate Stone size_t RegisterContextPOSIX_mips64::GetRegisterCount() {
78d5b44036SJonas Devlieghere return m_register_info_up->GetRegisterCount();
793e699d41SVirgile Bello }
803e699d41SVirgile Bello
GetGPRSize()81b9c1b51eSKate Stone size_t RegisterContextPOSIX_mips64::GetGPRSize() {
82d5b44036SJonas Devlieghere return m_register_info_up->GetGPRSize();
833e699d41SVirgile Bello }
843e699d41SVirgile Bello
GetRegisterInfo()85b9c1b51eSKate Stone const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
86b9c1b51eSKate Stone // Commonly, this method is overridden and g_register_infos is copied and
8705097246SAdrian Prantl // specialized. So, use GetRegisterInfo() rather than g_register_infos in
8805097246SAdrian Prantl // this scope.
89d5b44036SJonas Devlieghere return m_register_info_up->GetRegisterInfo();
903e699d41SVirgile Bello }
913e699d41SVirgile Bello
923e699d41SVirgile Bello const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)93b9c1b51eSKate Stone RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
94b8dbd323SNitesh Jain if (reg < m_num_registers)
953e699d41SVirgile Bello return &GetRegisterInfo()[reg];
963e699d41SVirgile Bello else
97248a1305SKonrad Kleine return nullptr;
983e699d41SVirgile Bello }
993e699d41SVirgile Bello
GetRegisterSetCount()100b9c1b51eSKate Stone size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
101d5b44036SJonas Devlieghere ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
102b8dbd323SNitesh Jain switch (target_arch.GetTriple().getOS()) {
103b8dbd323SNitesh Jain default: {
104d5b44036SJonas Devlieghere const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
105d5b44036SJonas Devlieghere m_register_info_up.get());
106b8dbd323SNitesh Jain return context->GetRegisterSetCount();
1073e699d41SVirgile Bello }
1083e699d41SVirgile Bello
109b8dbd323SNitesh Jain }
1103e699d41SVirgile Bello }
1113e699d41SVirgile Bello
GetRegisterSet(size_t set)112b9c1b51eSKate Stone const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
113d5b44036SJonas Devlieghere ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
114b8dbd323SNitesh Jain switch (target_arch.GetTriple().getOS()) {
115b8dbd323SNitesh Jain default: {
116d5b44036SJonas Devlieghere const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
117d5b44036SJonas Devlieghere m_register_info_up.get());
118b8dbd323SNitesh Jain return context->GetRegisterSet(set);
119b8dbd323SNitesh Jain }
120b8dbd323SNitesh Jain }
1213e699d41SVirgile Bello }
1223e699d41SVirgile Bello
GetRegisterName(unsigned reg)123b9c1b51eSKate Stone const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) {
124b8dbd323SNitesh Jain assert(reg < m_num_registers && "Invalid register offset.");
1253e699d41SVirgile Bello return GetRegisterInfo()[reg].name;
1263e699d41SVirgile Bello }
1273e699d41SVirgile Bello
IsRegisterSetAvailable(size_t set_index)128b9c1b51eSKate Stone bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
129b8dbd323SNitesh Jain size_t num_sets = GetRegisterSetCount();
1303e699d41SVirgile Bello
1313e699d41SVirgile Bello return (set_index < num_sets);
1323e699d41SVirgile Bello }
1333e699d41SVirgile Bello
13405097246SAdrian Prantl // Used when parsing DWARF and EH frame information and any other object file
13505097246SAdrian Prantl // sections that contain register numbers in them.
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t num)136b9c1b51eSKate Stone uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
137b9c1b51eSKate Stone lldb::RegisterKind kind, uint32_t num) {
138b8dbd323SNitesh Jain const uint32_t num_regs = m_num_registers;
1393e699d41SVirgile Bello
1403e699d41SVirgile Bello assert(kind < kNumRegisterKinds);
141b9c1b51eSKate Stone for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
1423e699d41SVirgile Bello const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
1433e699d41SVirgile Bello
1443e699d41SVirgile Bello if (reg_info->kinds[kind] == num)
1453e699d41SVirgile Bello return reg_idx;
1463e699d41SVirgile Bello }
1473e699d41SVirgile Bello
1483e699d41SVirgile Bello return LLDB_INVALID_REGNUM;
1493e699d41SVirgile Bello }
150