aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPlatin21 <arminmops@icloud.com>2021-12-27 22:10:52 +0100
committerPlatin21 <arminmops@icloud.com>2021-12-27 22:10:52 +0100
commit86f831ddd19e5f4e21179b32d603a6ae2cc6ce2f (patch)
treed97e08b96d0fb74d9fc77dc1ae627b2f6b570d8e
parenteec61c3f6f58b095243f5da66c71d5ee00283c10 (diff)
This adds code which checks how big the return is and if it is to big returns the value via sret
-rw-r--r--src/llvm_abi.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index c30f6531a..42f05bb27 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -965,6 +965,10 @@ namespace lbAbiArm64 {
}
return false;
}
+
+ unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef *base_type_, unsigned member_count_) {
+ return (member_count_ <= 4);
+ }
lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) {
LLVMTypeRef homo_base_type = {};
@@ -975,7 +979,16 @@ namespace lbAbiArm64 {
} else if (is_register(type)) {
return non_struct(c, type);
} else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) {
- return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
+ if(is_homogenous_aggregate_small_enough(&homo_base_type, homo_member_count)) {
+ return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
+ } else {
+ //TODO(Platin): do i need to create stuff that can handle the diffrent return type?
+ // else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type
+
+ //LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count);
+ LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type);
+ return lb_arg_type_indirect(type, attr);
+ }
} else {
i64 size = lb_sizeof(type);
if (size <= 16) {