Improve SysV ABI for multiple return values that fit into a single register; Fixes #2384

This commit is contained in:
gingerBill
2023-03-19 00:51:57 +00:00
parent b7f953b2ee
commit 1f5bb99548
+8 -4
View File
@@ -563,7 +563,7 @@ namespace lbAbiAmd64SysV {
gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls);
gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
gb_internal Array<RegClass> classify(LLVMTypeRef t);
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes);
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes, LLVMTypeRef type);
gb_internal LB_ABI_INFO(abi_info) {
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
@@ -662,7 +662,7 @@ namespace lbAbiAmd64SysV {
// the ABI rules for SysV
reg_type = type;
} else {
reg_type = llreg(c, cls);
reg_type = llreg(c, cls, type);
}
return lb_arg_type_direct(type, reg_type, nullptr, nullptr);
}
@@ -785,13 +785,17 @@ namespace lbAbiAmd64SysV {
}
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes) {
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes, LLVMTypeRef type) {
auto types = array_make<LLVMTypeRef>(heap_allocator(), 0, reg_classes.count);
for (isize i = 0; i < reg_classes.count; /**/) {
RegClass reg_class = reg_classes[i];
switch (reg_class) {
case RegClass_Int:
array_add(&types, LLVMIntTypeInContext(c, 64));
if (reg_classes.count == 1) {
array_add(&types, LLVMIntTypeInContext(c, cast(unsigned)(lb_sizeof(type)*8)));
} else {
array_add(&types, LLVMIntTypeInContext(c, 64));
}
break;
case RegClass_SSEFv:
case RegClass_SSEDv: