diff options
| author | gingerBill <bill@gingerbill.org> | 2023-03-19 00:51:57 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-03-19 00:51:57 +0000 |
| commit | 1f5bb99548d4164b3225cb145a44850909d6e0d7 (patch) | |
| tree | cb6bf16ddbb4fbe32725e060791256b48d7bf213 /src/llvm_abi.cpp | |
| parent | b7f953b2eeb8561509bc516cc87b416684cd89cb (diff) | |
Improve SysV ABI for multiple return values that fit into a single register; Fixes #2384
Diffstat (limited to 'src/llvm_abi.cpp')
| -rw-r--r-- | src/llvm_abi.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 1204050ef..9b8a39514 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -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 ®_classes); + gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_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 ®_classes) { + gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_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: |