diff options
| author | gingerBill <bill@gingerbill.org> | 2024-08-05 13:46:24 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-08-05 13:46:24 +0100 |
| commit | 7e701d1677fbe594e0970824062d8b3564d33d26 (patch) | |
| tree | 27c2370d163b96f00021d35be1395af7a579cb29 /src/llvm_backend_proc.cpp | |
| parent | b67ed78afdbe9a9b3330f07d4d55ca7604ec930e (diff) | |
Add `intrinsics.simd_gather` and ``intrinsics.simd_scatter`
Diffstat (limited to 'src/llvm_backend_proc.cpp')
| -rw-r--r-- | src/llvm_backend_proc.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 64db2ad36..5ccbd3399 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1688,6 +1688,52 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn return res; } + + case BuiltinProc_simd_gather: + case BuiltinProc_simd_scatter: + { + LLVMValueRef ptr = arg0.value; + LLVMValueRef val = arg1.value; + LLVMValueRef mask = arg2.value; + + unsigned count = cast(unsigned)get_array_type_count(arg0.type); + + LLVMTypeRef mask_type = LLVMVectorType(LLVMInt1TypeInContext(p->module->ctx), count); + mask = LLVMBuildTrunc(p->builder, mask, mask_type, ""); + + char const *name = nullptr; + switch (builtin_id) { + case BuiltinProc_simd_gather: name = "llvm.masked.gather"; break; + case BuiltinProc_simd_scatter: name = "llvm.masked.scatter"; break; + } + LLVMTypeRef types[2] = { + lb_type(p->module, arg1.type), + lb_type(p->module, arg0.type) + }; + + auto alignment = cast(unsigned long long)type_align_of(base_array_type(arg1.type)); + LLVMValueRef align = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), alignment, false); + + LLVMValueRef args[4] = {}; + switch (builtin_id) { + case BuiltinProc_simd_gather: + args[0] = ptr; + args[1] = align; + args[2] = mask; + args[3] = val; + break; + case BuiltinProc_simd_scatter: + args[0] = val; + args[1] = ptr; + args[2] = align; + args[3] = mask; + break; + } + + res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types)); + return res; + + } } GB_PANIC("Unhandled simd intrinsic: '%.*s'", LIT(builtin_procs[builtin_id].name)); |