From 5bc8a491a7768da0019b7b17da637e681f2ace90 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Oct 2021 23:24:34 +0100 Subject: Begin work on supporting `wasm64`; Correct `wasm32` compilation behaviour --- src/llvm_abi.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/llvm_abi.cpp') diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 9e7f4b290..aa12cc352 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1061,19 +1061,27 @@ LB_ABI_INFO(lb_get_abi_info) { } } - if (build_context.metrics.arch == TargetArch_amd64) { + switch (build_context.metrics.arch) { + case TargetArch_amd64: if (build_context.metrics.os == TargetOs_windows) { return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } else { return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } - } else if (build_context.metrics.arch == TargetArch_386) { + case TargetArch_386: return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); - } else if (build_context.metrics.arch == TargetArch_arm64) { + case TargetArch_arm64: return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); - } else if (build_context.metrics.arch == TargetArch_wasm32) { + case TargetArch_wasm32: + // TODO(bill): implement wasm32's ABI correct + // NOTE(bill): this ABI is only an issue for WASI compatibility return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); + case TargetArch_wasm64: + // TODO(bill): implement wasm64's ABI correct + // NOTE(bill): this ABI is only an issue for WASI compatibility + return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } + GB_PANIC("Unsupported ABI"); return {}; } -- cgit v1.2.3 From 32506a34ffa7a7cc3c12e14f31e36e9b22a91218 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 31 Oct 2021 15:23:39 +0000 Subject: Separate out the ABI for wasm32 from 386 --- src/llvm_abi.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'src/llvm_abi.cpp') diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index aa12cc352..ad8a45df7 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1039,6 +1039,70 @@ namespace lbAbiArm64 { } } +namespace lbAbiWasm32 { + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count); + lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined); + + LB_ABI_INFO(abi_info) { + lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType); + ft->ctx = c; + ft->args = compute_arg_types(c, arg_types, arg_count); + ft->ret = compute_return_type(c, return_type, return_is_defined); + ft->calling_convention = calling_convention; + return ft; + } + + lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) { + if (!is_return && lb_sizeof(type) > 8) { + return lb_arg_type_indirect(type, nullptr); + } + + LLVMAttributeRef attr = nullptr; + LLVMTypeRef i1 = LLVMInt1TypeInContext(c); + if (type == i1) { + attr = lb_create_enum_attribute(c, "zeroext"); + } + return lb_arg_type_direct(type, nullptr, nullptr, attr); + } + + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) { + auto args = array_make(heap_allocator(), arg_count); + + for (unsigned i = 0; i < arg_count; i++) { + LLVMTypeRef t = arg_types[i]; + LLVMTypeKind kind = LLVMGetTypeKind(t); + i64 sz = lb_sizeof(t); + if (kind == LLVMStructTypeKind || kind == LLVMArrayTypeKind) { + if (sz == 0) { + args[i] = lb_arg_type_ignore(t); + } else { + args[i] = lb_arg_type_indirect(t, nullptr); + } + } else { + args[i] = non_struct(c, t, false); + } + } + return args; + } + + lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) { + if (!return_is_defined) { + return lb_arg_type_direct(LLVMVoidTypeInContext(c)); + } else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) { + i64 sz = lb_sizeof(return_type); + switch (sz) { + case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); + case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), 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); + } + LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", return_type); + return lb_arg_type_indirect(return_type, attr); + } + return non_struct(c, return_type, true); + } +} + LB_ABI_INFO(lb_get_abi_info) { switch (calling_convention) { @@ -1075,7 +1139,7 @@ LB_ABI_INFO(lb_get_abi_info) { case TargetArch_wasm32: // TODO(bill): implement wasm32's ABI correct // NOTE(bill): this ABI is only an issue for WASI compatibility - return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); + return lbAbiWasm32::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); case TargetArch_wasm64: // TODO(bill): implement wasm64's ABI correct // NOTE(bill): this ABI is only an issue for WASI compatibility -- cgit v1.2.3 From 5f51337a01fa4a1e7a461604d564fa64601727cf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 31 Oct 2021 19:00:01 +0000 Subject: Add procs for wasm32 --- core/runtime/procs_wasm32.odin | 7 +++++++ src/checker.cpp | 3 +++ src/llvm_abi.cpp | 5 +++++ src/llvm_backend_opt.cpp | 6 ++++++ 4 files changed, 21 insertions(+) create mode 100644 core/runtime/procs_wasm32.odin (limited to 'src/llvm_abi.cpp') diff --git a/core/runtime/procs_wasm32.odin b/core/runtime/procs_wasm32.odin new file mode 100644 index 000000000..dbc0dfcb7 --- /dev/null +++ b/core/runtime/procs_wasm32.odin @@ -0,0 +1,7 @@ +//+build wasm32 +package runtime + +@(link_name="__ashlti3") +__ashlti3 :: proc "c" (a: i64, b: i32) -> i64 { + return a +} \ No newline at end of file diff --git a/src/checker.cpp b/src/checker.cpp index 8db9e1bd6..f0f463816 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2011,6 +2011,9 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("gnu_h2f_ieee"), str_lit("gnu_f2h_ieee"), str_lit("extendhfsf2"), + + // WASM Specific + str_lit("__ashlti3"), }; for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) { force_add_dependency_entity(c, c->info.runtime_package->scope, required_runtime_entities[i]); diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index ad8a45df7..9c7ced91e 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1053,6 +1053,11 @@ namespace lbAbiWasm32 { } lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) { + if (!is_return && type == LLVMIntTypeInContext(c, 128)) { + LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2); + return lb_arg_type_direct(type, cast_type, nullptr, nullptr); + } + if (!is_return && lb_sizeof(type) > 8) { return lb_arg_type_indirect(type, nullptr); } diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 8ddd3360d..75a377e5b 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -388,6 +388,12 @@ void lb_run_remove_unused_function_pass(LLVMModuleRef mod) { name == "memcpy") { continue; } + if (is_arch_wasm()) { + if (name == "__ashlti3") { + LLVMSetLinkage(curr_func, LLVMExternalLinkage); + continue; + } + } LLVMLinkage linkage = LLVMGetLinkage(curr_func); -- cgit v1.2.3