Index: lldb/trunk/include/lldb/Core/ArchSpec.h =================================================================== --- lldb/trunk/include/lldb/Core/ArchSpec.h +++ lldb/trunk/include/lldb/Core/ArchSpec.h @@ -65,8 +65,9 @@ eCore_arm_arm64, eCore_arm_armv8, eCore_arm_aarch64, - + eCore_mips64, + eCore_mips64el, eCore_ppc_generic, eCore_ppc_ppc601, Index: lldb/trunk/source/Core/ArchSpec.cpp =================================================================== --- lldb/trunk/source/Core/ArchSpec.cpp +++ lldb/trunk/source/Core/ArchSpec.cpp @@ -88,6 +88,7 @@ { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64 , "aarch64" }, { eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64el , "mips64el" }, { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "powerpc" }, { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, @@ -266,7 +267,8 @@ { ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64 { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9 { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64 - { ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // MIPS + { ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , llvm::Triple::mips64, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64 + { ArchSpec::eCore_mips64el , llvm::ELF::EM_MIPS , llvm::Triple::mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64el { ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // HEXAGON { ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA { ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA Index: lldb/trunk/source/Host/common/HostInfoBase.cpp =================================================================== --- lldb/trunk/source/Host/common/HostInfoBase.cpp +++ lldb/trunk/source/Host/common/HostInfoBase.cpp @@ -414,6 +414,7 @@ case llvm::Triple::aarch64: case llvm::Triple::mips64: + case llvm::Triple::mips64el: case llvm::Triple::sparcv9: arch_64.SetTriple(triple); break; Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -283,8 +283,34 @@ } static uint32_t +mipsVariantFromElfFlags(const elf::elf_word e_flags, uint32_t endian) +{ + const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH; + uint32_t arch_variant = LLDB_INVALID_CPUTYPE; + + switch (mips_arch) + { + case llvm::ELF::EF_MIPS_ARCH_64: + if (endian == ELFDATA2LSB) + arch_variant = llvm::Triple::mips64el; + else + arch_variant = llvm::Triple::mips64; + break; + + default: + break; + } + + return arch_variant; +} + +static uint32_t subTypeFromElfHeader(const elf::ELFHeader& header) { + if (header.e_machine == llvm::ELF::EM_MIPS) + return mipsVariantFromElfFlags (header.e_flags, + header.e_ident[EI_DATA]); + return llvm::ELF::EM_CSR_KALIMBA == header.e_machine ? kalimbaVariantFromElfFlags(header.e_flags) : Index: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -586,6 +586,7 @@ } break; case llvm::Triple::mips64: + case llvm::Triple::mips64el: { static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d }; trap_opcode = g_hex_opcode; Index: lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt +++ lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt @@ -9,6 +9,7 @@ NativeProcessLinux.cpp NativeRegisterContextLinux_arm64.cpp NativeRegisterContextLinux_x86_64.cpp + NativeRegisterContextLinux_mips64.cpp NativeThreadLinux.cpp ProcessLinux.cpp ProcessMonitor.cpp Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -3179,6 +3179,7 @@ // set per architecture. Need ARM, MIPS support here. static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 }; static const uint8_t g_i386_opcode [] = { 0xCC }; + static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d }; switch (m_arch.GetMachine ()) { @@ -3193,6 +3194,12 @@ actual_opcode_size = sizeof(g_i386_opcode); return Error (); + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + trap_opcode_bytes = g_mips64_opcode; + actual_opcode_size = sizeof(g_mips64_opcode); + return Error (); + default: assert(false && "CPU type not supported!"); return Error ("CPU type not supported"); Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h @@ -0,0 +1,122 @@ +//===-- NativeRegisterContextLinux_mips64.h ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef lldb_NativeRegisterContextLinux_mips64_h +#define lldb_NativeRegisterContextLinux_mips64_h + +#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h" +#include "Plugins/Process/Utility/RegisterContext_mips64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" + +// --------------------------------------------------------------------------- +// Internal codes for mips64 GP registers. +// --------------------------------------------------------------------------- +enum +{ + k_first_gp_reg_mips64, + gp_reg_r0_mips64 = k_first_gp_reg_mips64, + gp_reg_r1_mips64, + gp_reg_r2_mips64, + gp_reg_r3_mips64, + gp_reg_r4_mips64, + gp_reg_r5_mips64, + gp_reg_r6_mips64, + gp_reg_r7_mips64, + gp_reg_r8_mips64, + gp_reg_r9_mips64, + gp_reg_r10_mips64, + gp_reg_r11_mips64, + gp_reg_r12_mips64, + gp_reg_r13_mips64, + gp_reg_r14_mips64, + gp_reg_r15_mips64, + gp_reg_r16_mips64, + gp_reg_r17_mips64, + gp_reg_r18_mips64, + gp_reg_r19_mips64, + gp_reg_r20_mips64, + gp_reg_r21_mips64, + gp_reg_r22_mips64, + gp_reg_r23_mips64, + gp_reg_r24_mips64, + gp_reg_r25_mips64, + gp_reg_r26_mips64, + gp_reg_r27_mips64, + gp_reg_r28_mips64, + gp_reg_r29_mips64, + gp_reg_r30_mips64, + gp_reg_r31_mips64, + gp_reg_mullo_mips64, + gp_reg_mulhi_mips64, + gp_reg_pc_mips64, + gp_reg_badvaddr_mips64, + gp_reg_sr_mips64, + gp_reg_cause_mips64, + k_num_gp_reg_mips64, +}; + +namespace lldb_private +{ + class NativeProcessLinux; + + class NativeRegisterContextLinux_mips64 : public NativeRegisterContextRegisterInfo + { + public: + NativeRegisterContextLinux_mips64 (NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p); + + uint32_t + GetRegisterSetCount () const override; + + const RegisterSet * + GetRegisterSet (uint32_t set_index) const override; + + Error + ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) override; + + Error + WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) override; + + Error + ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override; + + Error + WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override; + + Error + IsWatchpointHit (uint8_t wp_index); + + Error + IsWatchpointVacant (uint32_t wp_index); + + bool + ClearHardwareWatchpoint (uint32_t wp_index) override; + + Error + ClearAllHardwareWatchpoints (); + + Error + SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size, + uint32_t watch_flags, uint32_t wp_index); + + uint32_t + SetHardwareWatchpoint (lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + lldb::addr_t + GetWatchpointAddress (uint32_t wp_index); + + uint32_t + NumSupportedHardwareWatchpoints () override; + }; +} + +#endif // #ifndef lldb_NativeRegisterContextLinux_mips64_h + Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -0,0 +1,213 @@ +//===-- NativeRegisterContextLinux_mips64.cpp ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "NativeRegisterContextLinux_mips64.h" + +#include "lldb/lldb-private-forward.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Host/common/NativeThreadProtocol.h" +#include "Plugins/Process/Linux/NativeProcessLinux.h" + +using namespace lldb_private; + +// ---------------------------------------------------------------------------- +// Private namespace. +// ---------------------------------------------------------------------------- + +namespace +{ + // mips64 general purpose registers. + const uint32_t + g_gp_regnums_mips64[] = + { + gp_reg_r0_mips64, + gp_reg_r1_mips64, + gp_reg_r2_mips64, + gp_reg_r3_mips64, + gp_reg_r4_mips64, + gp_reg_r5_mips64, + gp_reg_r6_mips64, + gp_reg_r7_mips64, + gp_reg_r8_mips64, + gp_reg_r9_mips64, + gp_reg_r10_mips64, + gp_reg_r11_mips64, + gp_reg_r12_mips64, + gp_reg_r13_mips64, + gp_reg_r14_mips64, + gp_reg_r15_mips64, + gp_reg_r16_mips64, + gp_reg_r17_mips64, + gp_reg_r18_mips64, + gp_reg_r19_mips64, + gp_reg_r20_mips64, + gp_reg_r21_mips64, + gp_reg_r22_mips64, + gp_reg_r23_mips64, + gp_reg_r24_mips64, + gp_reg_r25_mips64, + gp_reg_r26_mips64, + gp_reg_r27_mips64, + gp_reg_r28_mips64, + gp_reg_r29_mips64, + gp_reg_r30_mips64, + gp_reg_r31_mips64, + gp_reg_mullo_mips64, + gp_reg_mulhi_mips64, + gp_reg_pc_mips64, + gp_reg_badvaddr_mips64, + gp_reg_sr_mips64, + gp_reg_cause_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag + }; + + static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - 1 == k_num_gp_reg_mips64, + "g_gp_regnums_mips64 has wrong number of register infos"); + + // Number of register sets provided by this context. + enum + { + k_num_register_sets = 1 + }; + + // Register sets for mips64. + static const RegisterSet + g_reg_sets_mips64[k_num_register_sets] = + { + { "General Purpose Registers", "gpr", k_num_gp_reg_mips64, g_gp_regnums_mips64 } + }; +} + +// ---------------------------------------------------------------------------- +// NativeRegisterContextLinux_mips64 members. +// ---------------------------------------------------------------------------- + +NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) : + NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p) +{ +} + +uint32_t +NativeRegisterContextLinux_mips64::GetRegisterSetCount () const +{ + return k_num_register_sets; +} + +const lldb_private::RegisterSet * +NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const +{ + if (set_index >= k_num_register_sets) + return nullptr; + + switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ()) + { + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return &g_reg_sets_mips64[set_index]; + default: + assert (false && "Unhandled target architecture."); + return nullptr; + } + + return nullptr; +} + +lldb_private::Error +NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadRegister not implemented"); + return error; +} + +lldb_private::Error +NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteRegister not implemented"); + return error; +} + +lldb_private::Error +NativeRegisterContextLinux_mips64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadAllRegisterValues not implemented"); + return error; +} + +lldb_private::Error +NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteAllRegisterValues not implemented"); + return error; +} + +Error +NativeRegisterContextLinux_mips64::IsWatchpointHit (uint8_t wp_index) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointHit not implemented"); + return error; +} + +Error +NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented"); + return error; +} + +bool +NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint (uint32_t wp_index) +{ + return false; +} + +Error +NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints () +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints not implemented"); + return error; +} + +Error +NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex ( + lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) +{ + Error error; + error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex not implemented"); + return error; +} + +uint32_t +NativeRegisterContextLinux_mips64::SetHardwareWatchpoint ( + lldb::addr_t addr, size_t size, uint32_t watch_flags) +{ + return LLDB_INVALID_INDEX32; +} + +lldb::addr_t +NativeRegisterContextLinux_mips64::GetWatchpointAddress (uint32_t wp_index) +{ + return LLDB_INVALID_ADDRESS; +} + +uint32_t +NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints () +{ + return 0; +} Index: lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -15,6 +15,7 @@ #include "NativeProcessLinux.h" #include "NativeRegisterContextLinux_arm64.h" #include "NativeRegisterContextLinux_x86_64.h" +#include "NativeRegisterContextLinux_mips64.h" #include "lldb/Core/Log.h" #include "lldb/Core/State.h" @@ -31,6 +32,7 @@ #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" #include "Plugins/Process/Utility/RegisterInfoInterface.h" using namespace lldb; @@ -175,6 +177,12 @@ reg_interface = static_cast (new RegisterContextLinux_x86_64 (target_arch)); } break; + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) + && "Register setting path assumes this is a 64-bit host"); + reg_interface = static_cast(new RegisterContextLinux_mips64 (target_arch)); + break; default: break; } @@ -199,6 +207,13 @@ break; } #endif + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + { + const uint32_t concrete_frame_idx = 0; + m_reg_context_sp.reset (new NativeRegisterContextLinux_mips64 (*this, concrete_frame_idx, reg_interface)); + break; + } case llvm::Triple::aarch64: { const uint32_t concrete_frame_idx = 0; Index: lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt +++ lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt @@ -22,6 +22,7 @@ RegisterContextLinux_arm64.cpp RegisterContextLinux_i386.cpp RegisterContextLinux_x86_64.cpp + RegisterContextLinux_mips64.cpp RegisterContextLLDB.cpp RegisterContextMacOSXFrameBackchain.cpp RegisterContextMach_arm.cpp Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h @@ -0,0 +1,36 @@ +//===-- RegisterContextLinux_mips64.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextLinux_mips64_H_ +#define liblldb_RegisterContextLinux_mips64_H_ + +#include "lldb/lldb-private.h" +#include "RegisterInfoInterface.h" + +class RegisterContextLinux_mips64 + : public lldb_private::RegisterInfoInterface +{ +public: + RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch); + + size_t + GetGPRSize() const override; + + const lldb_private::RegisterInfo * + GetRegisterInfo() const override; + + uint32_t + GetRegisterCount () const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; +}; + +#endif Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp @@ -0,0 +1,151 @@ +//===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include +#include + +// For GDB, GCC and DWARF Register numbers +#include "RegisterContextLinux_mips64.h" + +// Internal codes for all mips64 registers +#include "Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h" +#include "RegisterContext_mips64.h" + +using namespace lldb_private; +using namespace lldb; + +// GP registers +typedef struct _GPR +{ + uint64_t gp_reg[32]; + uint64_t mul_lo; + uint64_t mul_hi; + uint64_t cp0_epc; + uint64_t cp0_badvaddr; + uint64_t cp0_status; + uint64_t cp0_cause; +} GPR; + +// FP registers +typedef struct _FPR +{ + uint64_t fp_reg[32]; + uint64_t fsr; /* FPU status register */ + uint64_t fcr; /* FPU control register */ +} FPR; + +// Computes the offset of the given GPR/FPR in the user data area. +#define GPR_OFFSET(regname) (offsetof(GPR, regname)) +#define FPR_OFFSET(regname) (offsetof(FPR, regname)) + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(member, reg, alt, kind1, kind2, kind3, kind4) \ + { #reg, alt, sizeof(((GPR*)0)->member), GPR_OFFSET(member), eEncodingUint, \ + eFormatHex, { kind1, kind2, kind3, kind4, gp_reg_##reg##_mips64 }, NULL, NULL } + +#define DEFINE_FPR(member, reg, alt, kind1, kind2, kind3, kind4) \ + { #reg, alt, sizeof(((FPR*)0)->member), FPR_OFFSET(member), eEncodingIEEE754, \ + eFormatFloat, { kind1, kind2, kind3, kind4, fp_reg_##reg##_mips64 }, NULL, NULL } + +static RegisterInfo +g_register_infos_mips64[] = +{ + DEFINE_GPR (gp_reg[0], r0, "zero", gcc_dwarf_zero_mips64, gcc_dwarf_zero_mips64, LLDB_INVALID_REGNUM, gdb_zero_mips64), + DEFINE_GPR (gp_reg[1], r1, "at", gcc_dwarf_r1_mips64, gcc_dwarf_r1_mips64, LLDB_INVALID_REGNUM, gdb_r1_mips64), + DEFINE_GPR (gp_reg[2], r2, NULL, gcc_dwarf_r2_mips64, gcc_dwarf_r2_mips64, LLDB_INVALID_REGNUM, gdb_r2_mips64), + DEFINE_GPR (gp_reg[3], r3, NULL, gcc_dwarf_r3_mips64, gcc_dwarf_r3_mips64, LLDB_INVALID_REGNUM, gdb_r3_mips64), + DEFINE_GPR (gp_reg[4], r4, NULL, gcc_dwarf_r4_mips64, gcc_dwarf_r4_mips64, LLDB_REGNUM_GENERIC_ARG1, gdb_r4_mips64), + DEFINE_GPR (gp_reg[5], r5, NULL, gcc_dwarf_r5_mips64, gcc_dwarf_r5_mips64, LLDB_REGNUM_GENERIC_ARG2, gdb_r5_mips64), + DEFINE_GPR (gp_reg[6], r6, NULL, gcc_dwarf_r6_mips64, gcc_dwarf_r6_mips64, LLDB_REGNUM_GENERIC_ARG3, gdb_r6_mips64), + DEFINE_GPR (gp_reg[7], r7, NULL, gcc_dwarf_r7_mips64, gcc_dwarf_r7_mips64, LLDB_REGNUM_GENERIC_ARG4, gdb_r7_mips64), + DEFINE_GPR (gp_reg[8], r8, NULL, gcc_dwarf_r8_mips64, gcc_dwarf_r8_mips64, LLDB_INVALID_REGNUM, gdb_r8_mips64), + DEFINE_GPR (gp_reg[9], r9, NULL, gcc_dwarf_r9_mips64, gcc_dwarf_r9_mips64, LLDB_INVALID_REGNUM, gdb_r9_mips64), + DEFINE_GPR (gp_reg[10], r10, NULL, gcc_dwarf_r10_mips64, gcc_dwarf_r10_mips64, LLDB_INVALID_REGNUM, gdb_r10_mips64), + DEFINE_GPR (gp_reg[11], r11, NULL, gcc_dwarf_r11_mips64, gcc_dwarf_r11_mips64, LLDB_INVALID_REGNUM, gdb_r11_mips64), + DEFINE_GPR (gp_reg[12], r12, NULL, gcc_dwarf_r12_mips64, gcc_dwarf_r12_mips64, LLDB_INVALID_REGNUM, gdb_r12_mips64), + DEFINE_GPR (gp_reg[13], r13, NULL, gcc_dwarf_r13_mips64, gcc_dwarf_r13_mips64, LLDB_INVALID_REGNUM, gdb_r13_mips64), + DEFINE_GPR (gp_reg[14], r14, NULL, gcc_dwarf_r14_mips64, gcc_dwarf_r14_mips64, LLDB_INVALID_REGNUM, gdb_r14_mips64), + DEFINE_GPR (gp_reg[15], r15, NULL, gcc_dwarf_r15_mips64, gcc_dwarf_r15_mips64, LLDB_INVALID_REGNUM, gdb_r15_mips64), + DEFINE_GPR (gp_reg[16], r16, NULL, gcc_dwarf_r16_mips64, gcc_dwarf_r16_mips64, LLDB_INVALID_REGNUM, gdb_r16_mips64), + DEFINE_GPR (gp_reg[17], r17, NULL, gcc_dwarf_r17_mips64, gcc_dwarf_r17_mips64, LLDB_INVALID_REGNUM, gdb_r17_mips64), + DEFINE_GPR (gp_reg[18], r18, NULL, gcc_dwarf_r18_mips64, gcc_dwarf_r18_mips64, LLDB_INVALID_REGNUM, gdb_r18_mips64), + DEFINE_GPR (gp_reg[19], r19, NULL, gcc_dwarf_r19_mips64, gcc_dwarf_r19_mips64, LLDB_INVALID_REGNUM, gdb_r19_mips64), + DEFINE_GPR (gp_reg[20], r20, NULL, gcc_dwarf_r20_mips64, gcc_dwarf_r20_mips64, LLDB_INVALID_REGNUM, gdb_r20_mips64), + DEFINE_GPR (gp_reg[21], r21, NULL, gcc_dwarf_r21_mips64, gcc_dwarf_r21_mips64, LLDB_INVALID_REGNUM, gdb_r21_mips64), + DEFINE_GPR (gp_reg[22], r22, NULL, gcc_dwarf_r22_mips64, gcc_dwarf_r22_mips64, LLDB_INVALID_REGNUM, gdb_r22_mips64), + DEFINE_GPR (gp_reg[23], r23, NULL, gcc_dwarf_r23_mips64, gcc_dwarf_r23_mips64, LLDB_INVALID_REGNUM, gdb_r23_mips64), + DEFINE_GPR (gp_reg[24], r24, NULL, gcc_dwarf_r24_mips64, gcc_dwarf_r24_mips64, LLDB_INVALID_REGNUM, gdb_r24_mips64), + DEFINE_GPR (gp_reg[25], r25, NULL, gcc_dwarf_r25_mips64, gcc_dwarf_r25_mips64, LLDB_INVALID_REGNUM, gdb_r25_mips64), + DEFINE_GPR (gp_reg[26], r26, NULL, gcc_dwarf_r26_mips64, gcc_dwarf_r26_mips64, LLDB_INVALID_REGNUM, gdb_r26_mips64), + DEFINE_GPR (gp_reg[27], r27, NULL, gcc_dwarf_r27_mips64, gcc_dwarf_r27_mips64, LLDB_INVALID_REGNUM, gdb_r27_mips64), + DEFINE_GPR (gp_reg[28], r28, "gp", gcc_dwarf_gp_mips64, gcc_dwarf_gp_mips64, LLDB_INVALID_REGNUM, gdb_gp_mips64), + DEFINE_GPR (gp_reg[29], r29, "sp", gcc_dwarf_sp_mips64, gcc_dwarf_sp_mips64, LLDB_REGNUM_GENERIC_SP, gdb_sp_mips64), + DEFINE_GPR (gp_reg[30], r30, "fp", gcc_dwarf_r30_mips64, gcc_dwarf_r30_mips64, LLDB_REGNUM_GENERIC_FP, gdb_r30_mips64), + DEFINE_GPR (gp_reg[31], r31, "ra", gcc_dwarf_ra_mips64, gcc_dwarf_ra_mips64, LLDB_REGNUM_GENERIC_RA, gdb_ra_mips64), + DEFINE_GPR (mul_lo, mullo, NULL, gcc_dwarf_lo_mips64, gcc_dwarf_lo_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR (mul_hi, mulhi, NULL, gcc_dwarf_hi_mips64, gcc_dwarf_hi_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR (cp0_epc, pc, NULL, gcc_dwarf_pc_mips64, gcc_dwarf_pc_mips64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR (cp0_badvaddr, badvaddr, NULL, gcc_dwarf_bad_mips64, gcc_dwarf_bad_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR (cp0_status, sr, "status", gcc_dwarf_sr_mips64, gcc_dwarf_sr_mips64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR (cp0_cause, cause, NULL, gcc_dwarf_cause_mips64, gcc_dwarf_cause_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), +}; + +static const RegisterInfo * +GetRegisterInfoPtr (const ArchSpec &target_arch) +{ + switch (target_arch.GetMachine()) + { + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return g_register_infos_mips64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +GetRegisterInfoCount (const ArchSpec &target_arch) +{ + switch (target_arch.GetMachine()) + { + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return static_cast (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextLinux_mips64::RegisterContextLinux_mips64(const ArchSpec &target_arch) : + lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p (GetRegisterInfoPtr (target_arch)), + m_register_info_count (GetRegisterInfoCount (target_arch)) +{ +} + +size_t +RegisterContextLinux_mips64::GetGPRSize() const +{ + return sizeof(GPR); +} + +const RegisterInfo * +RegisterContextLinux_mips64::GetRegisterInfo() const +{ + return m_register_info_p; +} + +uint32_t +RegisterContextLinux_mips64::GetRegisterCount () const +{ + return m_register_info_count; +} +