diff options
| author | RilleP <rikkypikki@hotmail.com> | 2024-04-10 19:10:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-10 19:10:33 +0200 |
| commit | 95a38d5a96322cd9adbb03bd5b7425b93469e62f (patch) | |
| tree | 8cdc3b962506ddc4b7b1883f0e2ecb9dce54e2f9 /src/llvm_abi.cpp | |
| parent | 239d4e10762a12e96280bd91003acbf2170cadf2 (diff) | |
| parent | 13e459980b0143b49762cdfd04dd5cf1bbf83daa (diff) | |
Merge branch 'master' into parsing-package-fixes
Diffstat (limited to 'src/llvm_abi.cpp')
| -rw-r--r-- | src/llvm_abi.cpp | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 857b255f3..88bb58c55 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -192,7 +192,7 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType // } LLVMSetFunctionCallConv(fn, cc_kind); if (calling_convention == ProcCC_Odin) { - unsigned context_index = offset+arg_count; + unsigned context_index = arg_index; LLVMAddAttributeAtIndex(fn, context_index, noalias_attr); LLVMAddAttributeAtIndex(fn, context_index, nonnull_attr); LLVMAddAttributeAtIndex(fn, context_index, nocapture_attr); @@ -275,7 +275,7 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) { case LLVMIntegerTypeKind: { unsigned w = LLVMGetIntTypeWidth(type); - return gb_clamp((w + 7)/8, 1, build_context.ptr_size); + return gb_clamp((w + 7)/8, 1, build_context.max_align); } case LLVMHalfTypeKind: return 2; @@ -558,7 +558,6 @@ namespace lbAbiAmd64SysV { Amd64TypeAttribute_StructRect, }; - gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type); gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off); gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls); gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention); @@ -796,10 +795,10 @@ namespace lbAbiAmd64SysV { } } + i64 sz = lb_sizeof(type); if (all_ints) { - i64 sz = lb_sizeof(type); for_array(i, reg_classes) { - GB_ASSERT(sz != 0); + GB_ASSERT(sz > 0); // TODO(bill): is this even correct? BECAUSE LLVM DOES NOT DOCUMENT ANY OF THIS!!! if (sz >= 8) { array_add(&types, LLVMIntTypeInContext(c, 64)); @@ -811,12 +810,16 @@ namespace lbAbiAmd64SysV { } } else { for (isize i = 0; i < reg_classes.count; /**/) { + GB_ASSERT(sz > 0); RegClass reg_class = reg_classes[i]; switch (reg_class) { case RegClass_Int: - // TODO(bill): is this even correct? BECAUSE LLVM DOES NOT DOCUMENT ANY OF THIS!!! - array_add(&types, LLVMIntTypeInContext(c, 64)); - break; + { + i64 rs = gb_min(sz, 8); + array_add(&types, LLVMIntTypeInContext(c, cast(unsigned)(rs*8))); + sz -= rs; + break; + } case RegClass_SSEFv: case RegClass_SSEDv: case RegClass_SSEInt8: @@ -856,15 +859,18 @@ namespace lbAbiAmd64SysV { unsigned vec_len = llvec_len(reg_classes, i+1); LLVMTypeRef vec_type = LLVMVectorType(elem_type, vec_len * elems_per_word); array_add(&types, vec_type); + sz -= lb_sizeof(vec_type); i += vec_len; continue; } break; case RegClass_SSEFs: array_add(&types, LLVMFloatTypeInContext(c)); + sz -= 4; break; case RegClass_SSEDs: array_add(&types, LLVMDoubleTypeInContext(c)); + sz -= 8; break; default: GB_PANIC("Unhandled RegClass"); @@ -876,7 +882,8 @@ namespace lbAbiAmd64SysV { if (types.count == 1) { return types[0]; } - return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, false); + + return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, sz == 0); } gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off) { @@ -979,28 +986,6 @@ namespace lbAbiAmd64SysV { break; } } - - gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) { - if (!return_is_defined) { - return lb_arg_type_direct(LLVMVoidTypeInContext(c)); - } else if (lb_is_type_kind(return_type, LLVMStructTypeKind)) { - i64 sz = lb_sizeof(return_type); - switch (sz) { - case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr); - case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr); - case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); - case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr); - } - - LB_ABI_MODIFY_RETURN_IF_TUPLE_MACRO(); - - LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", return_type); - return lb_arg_type_indirect(return_type, attr); - } else if (build_context.metrics.os == TargetOs_windows && lb_is_type_kind(return_type, LLVMIntegerTypeKind) && lb_sizeof(return_type) == 16) { - return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 128), nullptr, nullptr); - } - return non_struct(c, return_type); - } }; @@ -1145,17 +1130,27 @@ namespace lbAbiArm64 { i64 size = lb_sizeof(return_type); if (size <= 16) { LLVMTypeRef cast_type = nullptr; - if (size <= 1) { - cast_type = LLVMInt8TypeInContext(c); - } else if (size <= 2) { - cast_type = LLVMInt16TypeInContext(c); - } else if (size <= 4) { - cast_type = LLVMInt32TypeInContext(c); - } else if (size <= 8) { - cast_type = LLVMInt64TypeInContext(c); + + GB_ASSERT(size > 0); + if (size <= 8) { + cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8)); } else { unsigned count = cast(unsigned)((size+7)/8); - cast_type = llvm_array_type(LLVMInt64TypeInContext(c), 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); } return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr); } else { @@ -1188,17 +1183,27 @@ namespace lbAbiArm64 { i64 size = lb_sizeof(type); if (size <= 16) { LLVMTypeRef cast_type = nullptr; - if (size <= 1) { - cast_type = LLVMIntTypeInContext(c, 8); - } else if (size <= 2) { - cast_type = LLVMIntTypeInContext(c, 16); - } else if (size <= 4) { - cast_type = LLVMIntTypeInContext(c, 32); + if (size == 0) { + cast_type = LLVMStructTypeInContext(c, nullptr, 0, false); } else if (size <= 8) { - cast_type = LLVMIntTypeInContext(c, 64); + 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 { |