aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_abi.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-03-20 17:39:00 +0000
committergingerBill <bill@gingerbill.org>2024-03-20 17:39:00 +0000
commitc17adc98f5dfd313d4123c8a08d23eb1907e238f (patch)
tree5f9152e2b53be20dcb92f2bc2b6f56da532c7127 /src/llvm_abi.cpp
parentd381b77164ebf912a2b1ff60158613c72a282533 (diff)
Try doing `<{i64, i32}>` instead of `[i64, i64]` for ARM64 12-byte parameters
Diffstat (limited to 'src/llvm_abi.cpp')
-rw-r--r--src/llvm_abi.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index 62658d178..375235752 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -1187,7 +1187,21 @@ namespace lbAbiArm64 {
cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8));
} else {
unsigned count = cast(unsigned)((size+7)/8);
- cast_type = llvm_array_type(LLVMIntTypeInContext(c, 64), count);
+
+ LLVMTypeRef llvm_i64 = LLVMIntTypeInContext(c, 64);
+ LLVMTypeRef *types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, count);
+
+ i64 size_copy = size;
+ for (unsigned i = 0; i < count; i++) {
+ if (size_copy >= 8) {
+ types[i] = llvm_i64;
+ } else {
+ types[i] = LLVMIntTypeInContext(c, 8*cast(unsigned)size_copy);
+ }
+ size_copy -= 8;
+ }
+ GB_ASSERT(size_copy <= 0);
+ cast_type = LLVMStructTypeInContext(c, types, count, true);
}
args[i] = lb_arg_type_direct(type, cast_type, nullptr, nullptr);
} else {