3030// The ABI is not a source of such information as size, offset, encoding, etc.
3131// of a register. Just provides correct dwarf and eh_frame numbers.
3232
33- #define DEFINE_GENERIC_REGISTER_STUB (dwarf_num, str_name, generic_num ) \
33+ #define DEFINE_GENERIC_REGISTER_STUB (dwarf_num, generic_num ) \
3434 { \
3535 DEFINE_REG_NAME (dwarf_num), \
36- DEFINE_REG_NAME_STR (str_name), \
36+ DEFINE_REG_NAME_STR (nullptr ), \
3737 0 , \
3838 0 , \
3939 eEncodingInvalid, \
4444 nullptr , \
4545 }
4646
47- #define DEFINE_REGISTER_STUB (dwarf_num, str_name ) \
48- DEFINE_GENERIC_REGISTER_STUB (dwarf_num, str_name, LLDB_INVALID_REGNUM)
47+ #define DEFINE_REGISTER_STUB (dwarf_num ) \
48+ DEFINE_GENERIC_REGISTER_STUB (dwarf_num, LLDB_INVALID_REGNUM)
4949
5050using namespace lldb;
5151using namespace lldb_private ;
@@ -94,39 +94,39 @@ enum regnums {
9494};
9595
9696static const std::array<RegisterInfo, 33 > g_register_infos = {
97- {DEFINE_REGISTER_STUB (r0, nullptr ),
98- DEFINE_GENERIC_REGISTER_STUB (r1, nullptr , LLDB_REGNUM_GENERIC_RA),
99- DEFINE_REGISTER_STUB (r2, nullptr ),
100- DEFINE_GENERIC_REGISTER_STUB (r3, nullptr , LLDB_REGNUM_GENERIC_SP),
101- DEFINE_GENERIC_REGISTER_STUB (r4, nullptr , LLDB_REGNUM_GENERIC_ARG1),
102- DEFINE_GENERIC_REGISTER_STUB (r5, nullptr , LLDB_REGNUM_GENERIC_ARG2),
103- DEFINE_GENERIC_REGISTER_STUB (r6, nullptr , LLDB_REGNUM_GENERIC_ARG3),
104- DEFINE_GENERIC_REGISTER_STUB (r7, nullptr , LLDB_REGNUM_GENERIC_ARG4),
105- DEFINE_GENERIC_REGISTER_STUB (r8, nullptr , LLDB_REGNUM_GENERIC_ARG5),
106- DEFINE_GENERIC_REGISTER_STUB (r9, nullptr , LLDB_REGNUM_GENERIC_ARG6),
107- DEFINE_GENERIC_REGISTER_STUB (r10, nullptr , LLDB_REGNUM_GENERIC_ARG7),
108- DEFINE_GENERIC_REGISTER_STUB (r11, nullptr , LLDB_REGNUM_GENERIC_ARG8),
109- DEFINE_REGISTER_STUB (r12, nullptr ),
110- DEFINE_REGISTER_STUB (r13, nullptr ),
111- DEFINE_REGISTER_STUB (r14, nullptr ),
112- DEFINE_REGISTER_STUB (r15, nullptr ),
113- DEFINE_REGISTER_STUB (r16, nullptr ),
114- DEFINE_REGISTER_STUB (r17, nullptr ),
115- DEFINE_REGISTER_STUB (r18, nullptr ),
116- DEFINE_REGISTER_STUB (r19, nullptr ),
117- DEFINE_REGISTER_STUB (r20, nullptr ),
118- DEFINE_REGISTER_STUB (r21, nullptr ),
119- DEFINE_GENERIC_REGISTER_STUB (r22, nullptr , LLDB_REGNUM_GENERIC_FP),
120- DEFINE_REGISTER_STUB (r23, nullptr ),
121- DEFINE_REGISTER_STUB (r24, nullptr ),
122- DEFINE_REGISTER_STUB (r25, nullptr ),
123- DEFINE_REGISTER_STUB (r26, nullptr ),
124- DEFINE_REGISTER_STUB (r27, nullptr ),
125- DEFINE_REGISTER_STUB (r28, nullptr ),
126- DEFINE_REGISTER_STUB (r29, nullptr ),
127- DEFINE_REGISTER_STUB (r30, nullptr ),
128- DEFINE_REGISTER_STUB (r31, nullptr ),
129- DEFINE_GENERIC_REGISTER_STUB (pc, nullptr , LLDB_REGNUM_GENERIC_PC)}};
97+ {DEFINE_REGISTER_STUB (r0),
98+ DEFINE_GENERIC_REGISTER_STUB (r1, LLDB_REGNUM_GENERIC_RA),
99+ DEFINE_REGISTER_STUB (r2),
100+ DEFINE_GENERIC_REGISTER_STUB (r3, LLDB_REGNUM_GENERIC_SP),
101+ DEFINE_GENERIC_REGISTER_STUB (r4, LLDB_REGNUM_GENERIC_ARG1),
102+ DEFINE_GENERIC_REGISTER_STUB (r5, LLDB_REGNUM_GENERIC_ARG2),
103+ DEFINE_GENERIC_REGISTER_STUB (r6, LLDB_REGNUM_GENERIC_ARG3),
104+ DEFINE_GENERIC_REGISTER_STUB (r7, LLDB_REGNUM_GENERIC_ARG4),
105+ DEFINE_GENERIC_REGISTER_STUB (r8, LLDB_REGNUM_GENERIC_ARG5),
106+ DEFINE_GENERIC_REGISTER_STUB (r9, LLDB_REGNUM_GENERIC_ARG6),
107+ DEFINE_GENERIC_REGISTER_STUB (r10, LLDB_REGNUM_GENERIC_ARG7),
108+ DEFINE_GENERIC_REGISTER_STUB (r11, LLDB_REGNUM_GENERIC_ARG8),
109+ DEFINE_REGISTER_STUB (r12),
110+ DEFINE_REGISTER_STUB (r13),
111+ DEFINE_REGISTER_STUB (r14),
112+ DEFINE_REGISTER_STUB (r15),
113+ DEFINE_REGISTER_STUB (r16),
114+ DEFINE_REGISTER_STUB (r17),
115+ DEFINE_REGISTER_STUB (r18),
116+ DEFINE_REGISTER_STUB (r19),
117+ DEFINE_REGISTER_STUB (r20),
118+ DEFINE_REGISTER_STUB (r21),
119+ DEFINE_GENERIC_REGISTER_STUB (r22, LLDB_REGNUM_GENERIC_FP),
120+ DEFINE_REGISTER_STUB (r23),
121+ DEFINE_REGISTER_STUB (r24),
122+ DEFINE_REGISTER_STUB (r25),
123+ DEFINE_REGISTER_STUB (r26),
124+ DEFINE_REGISTER_STUB (r27),
125+ DEFINE_REGISTER_STUB (r28),
126+ DEFINE_REGISTER_STUB (r29),
127+ DEFINE_REGISTER_STUB (r30),
128+ DEFINE_REGISTER_STUB (r31),
129+ DEFINE_GENERIC_REGISTER_STUB (pc, LLDB_REGNUM_GENERIC_PC)}};
130130} // namespace dwarf
131131} // namespace
132132
@@ -275,44 +275,49 @@ Status ABISysV_loongarch::SetReturnValueObject(StackFrameSP &frame_sp,
275275 }
276276
277277 size_t reg_size = m_is_la64 ? 8 : 4 ;
278- if (num_bytes <= 2 * reg_size) {
279- offset_t offset = 0 ;
280- uint64_t raw_value = data.GetMaxU64 (&offset, num_bytes);
281-
282- auto reg_info =
283- reg_ctx.GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
284- if (!reg_ctx.WriteRegisterFromUnsigned (reg_info, raw_value)) {
285- result = Status::FromErrorStringWithFormat (
286- " Couldn't write value to register %s" , reg_info->name );
287- return result;
288- }
289-
290- if (num_bytes <= reg_size)
291- return result; // Successfully written.
292-
293- // for loongarch32, get the upper 32 bits from raw_value and write them
294- // for loongarch64, get the next 64 bits from data and write them
295- if (4 == reg_size)
296- raw_value >>= 32 ;
297- else
298- raw_value = data.GetMaxU64 (&offset, num_bytes - reg_size);
299- reg_info =
300- reg_ctx.GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
301- if (!reg_ctx.WriteRegisterFromUnsigned (reg_info, raw_value)) {
302- result = Status::FromErrorStringWithFormat (
303- " Couldn't write value to register %s" , reg_info->name );
304- }
278+ // Currently, we only support sizeof(data) <= 2 * reg_size.
279+ // 1. If the (`size` <= reg_size), the `data` will be returned through `ARG1`.
280+ // 2. If the (`size` > reg_size && `size` <= 2 * reg_size), the `data` will be
281+ // returned through a pair of registers (ARG1 and ARG2), and the lower-ordered
282+ // bits in the `ARG1`.
283+ if (num_bytes > 2 * reg_size) {
284+ result = Status::FromErrorString (
285+ " We don't support returning large integer values at present." );
286+ return result;
287+ }
305288
289+ offset_t offset = 0 ;
290+ uint64_t raw_value = data.GetMaxU64 (&offset, num_bytes);
291+ auto reg_info =
292+ reg_ctx.GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
293+ if (!reg_ctx.WriteRegisterFromUnsigned (reg_info, raw_value)) {
294+ result = Status::FromErrorStringWithFormat (
295+ " Couldn't write value to register %s" , reg_info->name );
306296 return result;
307297 }
308298
309- result = Status::FromErrorString (
310- " We don't support returning large integer values at present." );
299+ if (num_bytes <= reg_size)
300+ return result; // Successfully written.
301+
302+ // For loongarch32, get the upper 32 bits from raw_value and write them.
303+ // For loongarch64, get the next 64 bits from data and write them.
304+ if (4 == reg_size)
305+ raw_value >>= 32 ;
306+ else
307+ raw_value = data.GetMaxU64 (&offset, num_bytes - reg_size);
308+
309+ reg_info =
310+ reg_ctx.GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
311+ if (!reg_ctx.WriteRegisterFromUnsigned (reg_info, raw_value))
312+ result = Status::FromErrorStringWithFormat (
313+ " Couldn't write value to register %s" , reg_info->name );
314+
311315 return result;
312316}
313317
314318template <typename T>
315319static void SetInteger (Scalar &scalar, uint64_t raw_value, bool is_signed) {
320+ static_assert (std::is_unsigned<T>::value, " T must be an unsigned type." );
316321 raw_value &= std::numeric_limits<T>::max ();
317322 if (is_signed)
318323 scalar = static_cast <typename std::make_signed<T>::type>(raw_value);
@@ -371,21 +376,33 @@ static ValueObjectSP GetValObjFromIntRegs(Thread &thread,
371376 uint32_t byte_size) {
372377 Value value;
373378 ValueObjectSP return_valobj_sp;
374- auto reg_info_a0 =
379+ auto * reg_info_a0 =
375380 reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
376- auto reg_info_a1 =
381+ auto * reg_info_a1 =
377382 reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
378- uint64_t raw_value;
383+ uint64_t raw_value = 0 ;
379384
380385 switch (byte_size) {
381386 case sizeof (uint32_t ):
382387 // Read a0 to get the arg
383388 raw_value = reg_ctx->ReadRegisterAsUnsigned (reg_info_a0, 0 ) & UINT32_MAX;
384389 break ;
385390 case sizeof (uint64_t ):
386- raw_value = reg_ctx->ReadRegisterAsUnsigned (reg_info_a0, 0 );
391+ // Read a0 to get the arg on loongarch64, a0 and a1 on loongarch32
392+ if (llvm::Triple::loongarch32 == machine) {
393+ raw_value = reg_ctx->ReadRegisterAsUnsigned (reg_info_a0, 0 ) & UINT32_MAX;
394+ raw_value |=
395+ (reg_ctx->ReadRegisterAsUnsigned (reg_info_a1, 0 ) & UINT32_MAX) << 32U ;
396+ } else {
397+ raw_value = reg_ctx->ReadRegisterAsUnsigned (reg_info_a0, 0 );
398+ }
387399 break ;
388400 case 16 : {
401+ // Read a0 and a1 to get the arg on loongarch64, not supported on
402+ // loongarch32
403+ if (llvm::Triple::loongarch32 == machine)
404+ return return_valobj_sp;
405+
389406 // Create the ValueObjectSP here and return
390407 std::unique_ptr<DataBufferHeap> heap_data_up (
391408 new DataBufferHeap (byte_size, 0 ));
@@ -412,8 +429,8 @@ static ValueObjectSP GetValObjFromIntRegs(Thread &thread,
412429 }
413430
414431 if (type_flags & eTypeIsInteger) {
415- const bool is_signed = (type_flags & eTypeIsSigned) != 0 ;
416- if (! SetSizedInteger (value. GetScalar (), raw_value, byte_size, is_signed ))
432+ if (! SetSizedInteger (value. GetScalar (), raw_value, byte_size,
433+ type_flags & eTypeIsSigned ))
417434 return return_valobj_sp;
418435 } else if (type_flags & eTypeIsFloat) {
419436 if (!SetSizedFloat (value.GetScalar (), raw_value, byte_size))
@@ -432,7 +449,7 @@ static ValueObjectSP GetValObjFromFPRegs(Thread &thread,
432449 llvm::Triple::ArchType machine,
433450 uint32_t type_flags,
434451 uint32_t byte_size) {
435- auto reg_info_fa0 = reg_ctx->GetRegisterInfoByName (" f0" );
452+ auto * reg_info_fa0 = reg_ctx->GetRegisterInfoByName (" f0" );
436453 bool use_fp_regs = false ;
437454 ValueObjectSP return_valobj_sp;
438455
@@ -472,13 +489,11 @@ ValueObjectSP ABISysV_loongarch::GetReturnValueObjectSimple(
472489 const ArchSpec arch = thread.GetProcess ()->GetTarget ().GetArchitecture ();
473490 const llvm::Triple::ArchType machine = arch.GetMachine ();
474491
475- // Integer return type.
476492 if (type_flags & eTypeIsInteger) {
477493 return_valobj_sp =
478494 GetValObjFromIntRegs (thread, reg_ctx, machine, type_flags, byte_size);
479495 return return_valobj_sp;
480496 }
481- // Pointer return type.
482497 if (type_flags & eTypeIsPointer) {
483498 const auto *reg_info_a0 = reg_ctx->GetRegisterInfo (
484499 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
@@ -487,7 +502,6 @@ ValueObjectSP ABISysV_loongarch::GetReturnValueObjectSimple(
487502 return ValueObjectConstResult::Create (thread.GetStackFrameAtIndex (0 ).get (),
488503 value, ConstString (" " ));
489504 }
490- // Floating point return type.
491505 if (type_flags & eTypeIsFloat) {
492506 uint32_t float_count = 0 ;
493507 bool is_complex = false ;
@@ -576,28 +590,22 @@ bool ABISysV_loongarch::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
576590 const char *name = reg_info->name ;
577591 ArchSpec arch = GetProcessSP ()->GetTarget ().GetArchitecture ();
578592 uint32_t arch_flags = arch.GetFlags ();
579- // floating point registers are only callee saved when using
580- // F or D hardware floating point ABIs
593+ // Floating point registers are only callee saved when using
594+ // F or D hardware floating point ABIs.
581595 bool is_hw_fp = (arch_flags & ArchSpec::eLoongArch_abi_mask) != 0 ;
582596
583- bool is_callee_saved = llvm::StringSwitch<bool >(name)
584- // integer ABI names
585- .Cases (" ra" , " sp" , " fp" , true )
586- .Cases (" s0" , " s1" , " s2" , " s3" , " s4" , " s5" , " s6" ,
587- " s7" , " s8" , " s9" , true )
588- // integer hardware names
589- .Cases (" r1" , " r3" , " r22" , true )
590- .Cases (" r23" , " r24" , " r25" , " r26" , " r27" , " r28" ,
591- " r29" , " r30" , " 31" , true )
592- // floating point ABI names
593- .Cases (" fs0" , " fs1" , " fs2" , " fs3" , " fs4" , " fs5" ,
594- " fs6" , " fs7" , is_hw_fp)
595- // floating point hardware names
596- .Cases (" f24" , " f25" , " f26" , " f27" , " f28" , " f29" ,
597- " f30" , " f31" , is_hw_fp)
598- .Default (false );
599-
600- return is_callee_saved;
597+ return llvm::StringSwitch<bool >(name)
598+ // integer ABI names
599+ .Cases (" ra" , " sp" , " fp" , true )
600+ .Cases (" s0" , " s1" , " s2" , " s3" , " s4" , " s5" , " s6" , " s7" , " s8" , " s9" , true )
601+ // integer hardware names
602+ .Cases (" r1" , " r3" , " r22" , true )
603+ .Cases (" r23" , " r24" , " r25" , " r26" , " r27" , " r28" , " r29" , " r30" , " 31" , true )
604+ // floating point ABI names
605+ .Cases (" fs0" , " fs1" , " fs2" , " fs3" , " fs4" , " fs5" , " fs6" , " fs7" , is_hw_fp)
606+ // floating point hardware names
607+ .Cases (" f24" , " f25" , " f26" , " f27" , " f28" , " f29" , " f30" , " f31" , is_hw_fp)
608+ .Default (false );
601609}
602610
603611void ABISysV_loongarch::Initialize () {
0 commit comments