Skip to content

Commit 8363707

Browse files
committed
Address @DavidSpickett's comments
Created using spr 1.3.5-bogner
1 parent f390561 commit 8363707

File tree

2 files changed

+107
-99
lines changed

2 files changed

+107
-99
lines changed

lldb/source/Plugins/ABI/LoongArch/ABISysV_loongarch.cpp

Lines changed: 104 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
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, \
@@ -44,8 +44,8 @@
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

5050
using namespace lldb;
5151
using namespace lldb_private;
@@ -94,39 +94,39 @@ enum regnums {
9494
};
9595

9696
static 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

314318
template <typename T>
315319
static 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

603611
void ABISysV_loongarch::Initialize() {

lldb/source/Plugins/ABI/LoongArch/ABISysV_loongarch.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ class ABISysV_loongarch : public lldb_private::RegInfoBasedABI {
4848
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
4949

5050
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
51-
// The CFA must be 128 bit aligned.
51+
// The CFA must be 16 byte aligned.
5252
return (cfa & 0xfull) == 0;
5353
}
5454

5555
void SetIsLA64(bool is_la64) { m_is_la64 = is_la64; }
5656

5757
bool CodeAddressIsValid(lldb::addr_t pc) override {
58+
// Code address must be 4 byte aligned.
5859
if (pc & (4ull - 1ull))
59-
return false; // Not 4 byte aligned
60+
return false;
6061

61-
// Anything else if fair game..
6262
return true;
6363
}
6464

0 commit comments

Comments
 (0)