Browse Source

This adds code which checks how big the return is and if it is to big returns the value via sret

Platin21 3 years ago
parent
commit
86f831ddd1
1 changed files with 14 additions and 1 deletions
  1. 14 1
      src/llvm_abi.cpp

+ 14 - 1
src/llvm_abi.cpp

@@ -965,6 +965,10 @@ namespace lbAbiArm64 {
 		}
 		}
 		return false;
 		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) {
 	lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) {
 		LLVMTypeRef homo_base_type = {};
 		LLVMTypeRef homo_base_type = {};
@@ -975,7 +979,16 @@ namespace lbAbiArm64 {
 		} else if (is_register(type)) {
 		} else if (is_register(type)) {
 			return non_struct(c, type);
 			return non_struct(c, type);
 		} else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) {
 		} 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 {
 		} else {
 			i64 size = lb_sizeof(type);
 			i64 size = lb_sizeof(type);
 			if (size <= 16) {
 			if (size <= 16) {