diff options
| author | gingerBill <bill@gingerbill.org> | 2022-11-23 16:25:09 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-11-23 16:25:09 +0000 |
| commit | 7ab591667a1c647926fe79fda18efec8ce706198 (patch) | |
| tree | 9c319a86d6f2a3ec4cc2d086c6f6441dff830b35 /src/llvm_backend_stmt.cpp | |
| parent | 0a0db23b1751c0b7021cc1b3af3329b5d93cf9da (diff) | |
Basic support for new ABI experiment on Win64
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 9159f7550..1d28ea1c6 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1576,9 +1576,27 @@ void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> cons } } -void lb_build_return_stmt_internal(lbProcedure *p, lbValue const &res) { - lbFunctionType *ft = lb_get_function_type(p->module, p, p->type); +void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) { + lbFunctionType *ft = lb_get_function_type(p->module, p->type); bool return_by_pointer = ft->ret.kind == lbArg_Indirect; + bool split_returns = ft->multiple_return_original_type != nullptr; + + if (split_returns) { + GB_ASSERT(res.value != nullptr); + Type *res_type = res.type; + GB_ASSERT(is_type_tuple(res_type)); + isize res_count = res_type->Tuple.variables.count; + + isize param_offset = return_by_pointer ? 1 : 0; + param_offset += ft->original_arg_count; + for (isize i = 0; i < res_count-1; i++) { + lbValue ret_ptr = {}; + ret_ptr.value = LLVMGetParam(p->value, cast(unsigned)(param_offset + i)); + ret_ptr.type = alloc_type_pointer(res_type->Tuple.variables[i]->type); + lb_emit_store(p, ret_ptr, lb_emit_struct_ev(p, res, cast(i32)i)); + } + res = lb_emit_struct_ev(p, res, cast(i32)(res_count-1)); + } if (return_by_pointer) { if (res.value != nullptr) { @@ -1617,7 +1635,7 @@ void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) { isize return_count = p->type->Proc.result_count; isize res_count = return_results.count; - lbFunctionType *ft = lb_get_function_type(p->module, p, p->type); + lbFunctionType *ft = lb_get_function_type(p->module, p->type); bool return_by_pointer = ft->ret.kind == lbArg_Indirect; if (return_count == 0) { |