1 //===-- ABISysV_mips64.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ABISysV_mips64.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/Triple.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObjectConstResult.h"
19 #include "lldb/Core/ValueObjectMemory.h"
20 #include "lldb/Core/ValueObjectRegister.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ConstString.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RegisterValue.h"
31 #include "lldb/Utility/Status.h"
34 using namespace lldb_private;
77 static const RegisterInfo g_register_infos_mips64[] = {
78 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
79 // DWARF GENERIC PROCESS PLUGIN
81 // ======== ====== == === ============= ========== =============
82 // ================= ==================== =================
83 // ====================
90 {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
102 {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
103 LLDB_INVALID_REGNUM},
114 {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
115 LLDB_INVALID_REGNUM},
126 {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
127 LLDB_INVALID_REGNUM},
138 {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
139 LLDB_INVALID_REGNUM},
150 {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
151 LLDB_INVALID_REGNUM},
162 {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
163 LLDB_INVALID_REGNUM},
174 {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
175 LLDB_INVALID_REGNUM},
186 {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
187 LLDB_INVALID_REGNUM},
198 {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
199 LLDB_INVALID_REGNUM},
210 {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM,
211 LLDB_INVALID_REGNUM},
222 {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM,
223 LLDB_INVALID_REGNUM},
234 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
235 LLDB_INVALID_REGNUM},
246 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
247 LLDB_INVALID_REGNUM},
258 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259 LLDB_INVALID_REGNUM},
270 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271 LLDB_INVALID_REGNUM},
282 {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283 LLDB_INVALID_REGNUM},
294 {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
295 LLDB_INVALID_REGNUM},
306 {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307 LLDB_INVALID_REGNUM},
318 {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
319 LLDB_INVALID_REGNUM},
330 {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
331 LLDB_INVALID_REGNUM},
342 {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
343 LLDB_INVALID_REGNUM},
354 {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355 LLDB_INVALID_REGNUM},
366 {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
367 LLDB_INVALID_REGNUM},
378 {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
379 LLDB_INVALID_REGNUM},
390 {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391 LLDB_INVALID_REGNUM},
402 {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
403 LLDB_INVALID_REGNUM},
414 {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415 LLDB_INVALID_REGNUM},
426 {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
427 LLDB_INVALID_REGNUM},
438 {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
439 LLDB_INVALID_REGNUM},
450 {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
451 LLDB_INVALID_REGNUM},
462 {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
463 LLDB_INVALID_REGNUM},
474 {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
475 LLDB_INVALID_REGNUM},
486 {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
487 LLDB_INVALID_REGNUM},
498 {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
499 LLDB_INVALID_REGNUM},
510 {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
511 LLDB_INVALID_REGNUM},
522 {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523 LLDB_INVALID_REGNUM},
534 {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
535 LLDB_INVALID_REGNUM},
542 static const uint32_t k_num_register_infos =
543 llvm::array_lengthof(g_register_infos_mips64);
545 const lldb_private::RegisterInfo *
546 ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) {
547 count = k_num_register_infos;
548 return g_register_infos_mips64;
551 size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
553 //------------------------------------------------------------------
555 //------------------------------------------------------------------
558 ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
559 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
560 if ((arch_type == llvm::Triple::mips64) ||
561 (arch_type == llvm::Triple::mips64el)) {
562 return ABISP(new ABISysV_mips64(process_sp));
567 bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
568 addr_t func_addr, addr_t return_addr,
569 llvm::ArrayRef<addr_t> args) const {
570 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
574 s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64
575 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
576 ", return_addr = 0x%" PRIx64,
577 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
578 (uint64_t)return_addr);
580 for (size_t i = 0; i < args.size(); ++i)
581 s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
583 log->PutString(s.GetString());
586 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
590 const RegisterInfo *reg_info = nullptr;
592 if (args.size() > 8) // TODO handle more than 8 arguments
595 for (size_t i = 0; i < args.size(); ++i) {
596 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
597 LLDB_REGNUM_GENERIC_ARG1 + i);
599 log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
600 args[i], reg_info->name);
601 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
605 // First, align the SP
608 log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
609 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
611 sp &= ~(0xfull); // 16-byte alignment
614 const RegisterInfo *pc_reg_info =
615 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
616 const RegisterInfo *sp_reg_info =
617 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
618 const RegisterInfo *ra_reg_info =
619 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
620 const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
621 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
624 log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
626 /* Write r0 with 0, in case we are stopped in syscall,
627 * such setting prevents automatic decrement of the PC.
628 * This clears the bug 23659 for MIPS.
630 if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
634 log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
636 // Set "sp" to the requested value
637 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
641 log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
643 // Set "ra" to the return address
644 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
648 log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
650 // Set pc to the address of the called function.
651 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
655 log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
657 // All callers of position independent functions must place the address of
658 // the called function in t9 (r25)
659 if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
665 bool ABISysV_mips64::GetArgumentValues(Thread &thread,
666 ValueList &values) const {
670 Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
671 lldb::ValueObjectSP &new_value_sp) {
674 error.SetErrorString("Empty value object for return value.");
678 CompilerType compiler_type = new_value_sp->GetCompilerType();
679 if (!compiler_type) {
680 error.SetErrorString("Null clang type for return value.");
684 Thread *thread = frame_sp->GetThread().get();
686 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
689 error.SetErrorString("no registers are available");
693 size_t num_bytes = new_value_sp->GetData(data, data_error);
694 if (data_error.Fail()) {
695 error.SetErrorStringWithFormat(
696 "Couldn't convert return value to raw data: %s",
697 data_error.AsCString());
701 const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
703 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
704 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
705 lldb::offset_t offset = 0;
707 if (num_bytes <= 16) {
708 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
709 if (num_bytes <= 8) {
710 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
712 if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
713 error.SetErrorString("failed to write register r2");
715 uint64_t raw_value = data.GetMaxU64(&offset, 8);
716 if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
717 const RegisterInfo *r3_info =
718 reg_ctx->GetRegisterInfoByName("r3", 0);
719 raw_value = data.GetMaxU64(&offset, num_bytes - offset);
721 if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
722 error.SetErrorString("failed to write register r3");
724 error.SetErrorString("failed to write register r2");
727 error.SetErrorString("We don't support returning longer than 128 bit "
728 "integer values at present.");
730 } else if (type_flags & eTypeIsFloat) {
731 error.SetErrorString("TODO: Handle Float Types.");
733 } else if (type_flags & eTypeIsVector) {
734 error.SetErrorString("returning vector values are not supported");
740 ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple(
741 Thread &thread, CompilerType &return_compiler_type) const {
742 ValueObjectSP return_valobj_sp;
743 return return_valobj_sp;
746 ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
747 Thread &thread, CompilerType &return_compiler_type) const {
748 ValueObjectSP return_valobj_sp;
752 ExecutionContext exe_ctx(thread.shared_from_this());
753 if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
754 return return_valobj_sp;
756 value.SetCompilerType(return_compiler_type);
758 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
760 return return_valobj_sp;
762 Target *target = exe_ctx.GetTargetPtr();
763 const ArchSpec target_arch = target->GetArchitecture();
764 ByteOrder target_byte_order = target_arch.GetByteOrder();
765 llvm::Optional<uint64_t> byte_size =
766 return_compiler_type.GetByteSize(nullptr);
768 return return_valobj_sp;
769 const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
771 target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
773 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
774 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
776 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
777 value.SetValueType(Value::eValueTypeScalar);
779 bool success = false;
780 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
781 // Extract the register context so we can read arguments from registers
782 // In MIPS register "r2" (v0) holds the integer function return values
784 uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
786 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
787 switch (*byte_size) {
791 case sizeof(uint64_t):
793 value.GetScalar() = (int64_t)(raw_value);
795 value.GetScalar() = (uint64_t)(raw_value);
799 case sizeof(uint32_t):
801 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
803 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
807 case sizeof(uint16_t):
809 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
811 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
815 case sizeof(uint8_t):
817 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
819 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
823 } else if (type_flags & eTypeIsFloat) {
824 if (type_flags & eTypeIsComplex) {
825 // Don't handle complex yet.
826 } else if (IsSoftFloat(fp_flag)) {
827 uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
828 switch (*byte_size) {
830 value.GetScalar() = *((float *)(&raw_value));
834 value.GetScalar() = *((double *)(&raw_value));
839 if (target_byte_order == eByteOrderLittle) {
840 result[0] = raw_value;
841 result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
842 value.GetScalar() = *((long double *)(result));
844 result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
845 result[1] = raw_value;
846 value.GetScalar() = *((long double *)(result));
853 if (*byte_size <= sizeof(long double)) {
854 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
856 RegisterValue f0_value;
857 DataExtractor f0_data;
859 reg_ctx->ReadRegister(f0_info, f0_value);
861 f0_value.GetData(f0_data);
863 lldb::offset_t offset = 0;
864 if (*byte_size == sizeof(float)) {
865 value.GetScalar() = (float)f0_data.GetFloat(&offset);
867 } else if (*byte_size == sizeof(double)) {
868 value.GetScalar() = (double)f0_data.GetDouble(&offset);
870 } else if (*byte_size == sizeof(long double)) {
871 const RegisterInfo *f2_info =
872 reg_ctx->GetRegisterInfoByName("f2", 0);
873 RegisterValue f2_value;
874 DataExtractor f2_data;
875 reg_ctx->ReadRegister(f2_info, f2_value);
876 DataExtractor *copy_from_extractor = nullptr;
877 DataBufferSP data_sp(new DataBufferHeap(16, 0));
878 DataExtractor return_ext(
879 data_sp, target_byte_order,
880 target->GetArchitecture().GetAddressByteSize());
882 if (target_byte_order == eByteOrderLittle) {
883 copy_from_extractor = &f0_data;
884 copy_from_extractor->CopyByteOrderedData(
885 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
886 f2_value.GetData(f2_data);
887 copy_from_extractor = &f2_data;
888 copy_from_extractor->CopyByteOrderedData(
889 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
892 copy_from_extractor = &f0_data;
893 copy_from_extractor->CopyByteOrderedData(
894 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
896 f2_value.GetData(f2_data);
897 copy_from_extractor = &f2_data;
898 copy_from_extractor->CopyByteOrderedData(
899 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
902 return_valobj_sp = ValueObjectConstResult::Create(
903 &thread, return_compiler_type, ConstString(""), return_ext);
904 return return_valobj_sp;
911 return_valobj_sp = ValueObjectConstResult::Create(
912 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
913 } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
914 type_flags & eTypeIsVector) {
915 // Any structure of up to 16 bytes in size is returned in the registers.
916 if (*byte_size <= 16) {
917 DataBufferSP data_sp(new DataBufferHeap(16, 0));
918 DataExtractor return_ext(data_sp, target_byte_order,
919 target->GetArchitecture().GetAddressByteSize());
921 RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
922 // Tracks how much bytes of r2 and r3 registers we've consumed so far
923 uint32_t integer_bytes = 0;
925 // True if return values are in FP return registers.
926 bool use_fp_regs = 0;
927 // True if we found any non floating point field in structure.
928 bool found_non_fp_field = 0;
929 // True if return values are in r2 register.
931 // True if return values are in r3 register.
933 // True if the result is copied into our data buffer
938 const uint32_t num_children = return_compiler_type.GetNumFields();
940 // A structure consisting of one or two FP values (and nothing else) will
941 // be returned in the two FP return-value registers i.e fp0 and fp2.
942 if (num_children <= 2) {
943 uint64_t field_bit_offset = 0;
945 // Check if this structure contains only floating point fields
946 for (uint32_t idx = 0; idx < num_children; idx++) {
947 CompilerType field_compiler_type =
948 return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
951 if (field_compiler_type.IsFloatingPointType(count, is_complex))
954 found_non_fp_field = 1;
957 if (use_fp_regs && !found_non_fp_field) {
958 // We have one or two FP-only values in this structure. Get it from
960 DataExtractor f0_data, f1_data, f2_data;
961 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
962 const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
963 const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
965 reg_ctx->ReadRegister(f0_info, f0_value);
966 reg_ctx->ReadRegister(f2_info, f2_value);
968 f0_value.GetData(f0_data);
970 for (uint32_t idx = 0; idx < num_children; idx++) {
971 CompilerType field_compiler_type =
972 return_compiler_type.GetFieldAtIndex(
973 idx, name, &field_bit_offset, nullptr, nullptr);
974 llvm::Optional<uint64_t> field_byte_width =
975 field_compiler_type.GetByteSize(nullptr);
976 if (!field_byte_width)
977 return return_valobj_sp;
979 DataExtractor *copy_from_extractor = nullptr;
980 uint64_t return_value[2];
984 // This case is for long double type.
985 if (*field_byte_width == 16) {
987 // If structure contains long double type, then it is returned
988 // in fp0/fp1 registers.
989 if (target_byte_order == eByteOrderLittle) {
990 return_value[0] = f0_data.GetU64(&offset);
991 reg_ctx->ReadRegister(f1_info, f1_value);
992 f1_value.GetData(f1_data);
994 return_value[1] = f1_data.GetU64(&offset);
996 return_value[1] = f0_data.GetU64(&offset);
997 reg_ctx->ReadRegister(f1_info, f1_value);
998 f1_value.GetData(f1_data);
1000 return_value[0] = f1_data.GetU64(&offset);
1003 f0_data.SetData(return_value, *field_byte_width,
1006 copy_from_extractor = &f0_data; // This is in f0, copy from
1007 // register to our result
1010 f2_value.GetData(f2_data);
1011 // This is in f2, copy from register to our result structure
1012 copy_from_extractor = &f2_data;
1015 // Sanity check to avoid crash
1016 if (!copy_from_extractor ||
1017 *field_byte_width > copy_from_extractor->GetByteSize())
1018 return return_valobj_sp;
1020 // copy the register contents into our data buffer
1021 copy_from_extractor->CopyByteOrderedData(
1022 0, *field_byte_width,
1023 data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
1027 // The result is in our data buffer. Create a variable object out of
1029 return_valobj_sp = ValueObjectConstResult::Create(
1030 &thread, return_compiler_type, ConstString(""), return_ext);
1032 return return_valobj_sp;
1036 // If we reach here, it means this structure either contains more than
1037 // two fields or it contains at least one non floating point type. In
1038 // that case, all fields are returned in GP return registers.
1039 for (uint32_t idx = 0; idx < num_children; idx++) {
1040 uint64_t field_bit_offset = 0;
1044 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1045 idx, name, &field_bit_offset, nullptr, nullptr);
1046 llvm::Optional<uint64_t> field_byte_width =
1047 field_compiler_type.GetByteSize(nullptr);
1049 // if we don't know the size of the field (e.g. invalid type), just
1051 if (!field_byte_width || *field_byte_width == 0)
1054 uint32_t field_byte_offset = field_bit_offset / 8;
1056 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1057 field_compiler_type.IsPointerType() ||
1058 field_compiler_type.IsFloatingPointType(count, is_complex)) {
1059 padding = field_byte_offset - integer_bytes;
1061 if (integer_bytes < 8) {
1062 // We have not yet consumed r2 completely.
1063 if (integer_bytes + *field_byte_width + padding <= 8) {
1064 // This field fits in r2, copy its value from r2 to our result
1066 integer_bytes = integer_bytes + *field_byte_width +
1067 padding; // Increase the consumed bytes.
1070 // There isn't enough space left in r2 for this field, so this
1072 integer_bytes = integer_bytes + *field_byte_width +
1073 padding; // Increase the consumed bytes.
1077 // We already have consumed at-least 8 bytes that means r2 is done,
1078 // and this field will be in r3. Check if this field can fit in r3.
1079 else if (integer_bytes + *field_byte_width + padding <= 16) {
1080 integer_bytes = integer_bytes + *field_byte_width + padding;
1083 // There isn't any space left for this field, this should not
1084 // happen as we have already checked the overall size is not
1085 // greater than 16 bytes. For now, return a nullptr return value
1087 return return_valobj_sp;
1091 // Vector types up to 16 bytes are returned in GP return registers
1092 if (type_flags & eTypeIsVector) {
1093 if (*byte_size <= 8)
1102 reg_ctx->ReadRegister(r2_info, r2_value);
1104 const size_t bytes_copied = r2_value.GetAsMemoryData(
1105 r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order,
1107 if (bytes_copied != r2_info->byte_size)
1108 return return_valobj_sp;
1112 reg_ctx->ReadRegister(r3_info, r3_value);
1113 const size_t bytes_copied = r3_value.GetAsMemoryData(
1114 r3_info, data_sp->GetBytes() + r2_info->byte_size,
1115 r3_info->byte_size, target_byte_order, error);
1117 if (bytes_copied != r3_info->byte_size)
1118 return return_valobj_sp;
1122 // The result is in our data buffer. Create a variable object out of
1124 return_valobj_sp = ValueObjectConstResult::Create(
1125 &thread, return_compiler_type, ConstString(""), return_ext);
1127 return return_valobj_sp;
1130 // Any structure/vector greater than 16 bytes in size is returned in
1131 // memory. The pointer to that memory is returned in r2.
1132 uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
1133 reg_ctx->GetRegisterInfoByName("r2", 0), 0);
1135 // We have got the address. Create a memory object out of it
1136 return_valobj_sp = ValueObjectMemory::Create(
1137 &thread, "", Address(mem_address, nullptr), return_compiler_type);
1139 return return_valobj_sp;
1142 bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1143 unwind_plan.Clear();
1144 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1146 UnwindPlan::RowSP row(new UnwindPlan::Row);
1148 // Our Call Frame Address is the stack pointer value
1149 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1151 // The previous PC is in the RA
1152 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1153 unwind_plan.AppendRow(row);
1155 // All other registers are the same.
1157 unwind_plan.SetSourceName("mips64 at-func-entry default");
1158 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1159 unwind_plan.SetReturnAddressRegister(dwarf_r31);
1163 bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1164 unwind_plan.Clear();
1165 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1167 UnwindPlan::RowSP row(new UnwindPlan::Row);
1169 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1171 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1173 unwind_plan.AppendRow(row);
1174 unwind_plan.SetSourceName("mips64 default unwind plan");
1175 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1176 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1180 bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1181 return !RegisterIsCalleeSaved(reg_info);
1184 bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const {
1185 return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1188 bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1190 // Preserved registers are :
1191 // r16-r23, r28, r29, r30, r31
1193 int reg = ((reg_info->byte_offset) / 8);
1195 bool save = (reg >= 16) && (reg <= 23);
1196 save |= (reg >= 28) && (reg <= 31);
1203 void ABISysV_mips64::Initialize() {
1204 PluginManager::RegisterPlugin(
1205 GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
1208 void ABISysV_mips64::Terminate() {
1209 PluginManager::UnregisterPlugin(CreateInstance);
1212 lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() {
1213 static ConstString g_name("sysv-mips64");
1217 //------------------------------------------------------------------
1218 // PluginInterface protocol
1219 //------------------------------------------------------------------
1221 lldb_private::ConstString ABISysV_mips64::GetPluginName() {
1222 return GetPluginNameStatic();
1225 uint32_t ABISysV_mips64::GetPluginVersion() { return 1; }